mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 21:46:35 +03:00
improve test setup and code style
This commit is contained in:
committed by
Simon Laux
parent
bdd4aa0f10
commit
2f00b098ac
@@ -3,11 +3,11 @@ name = "deltachat-jsonrpc"
|
||||
version = "1.86.0"
|
||||
authors = ["Delta Chat Developers (ML) <delta@codespeak.net>"]
|
||||
edition = "2021"
|
||||
default-run = "webserver"
|
||||
default-run = "deltachat-jsonrpc-server"
|
||||
license = "MPL-2.0"
|
||||
|
||||
[[bin]]
|
||||
name = "webserver"
|
||||
name = "deltachat-jsonrpc-server"
|
||||
path = "src/webserver.rs"
|
||||
required-features = ["webserver"]
|
||||
|
||||
@@ -36,6 +36,3 @@ tokio = { version = "1.19.2", features = ["full", "rt-multi-thread"] }
|
||||
[features]
|
||||
default = []
|
||||
webserver = ["env_logger", "axum", "tokio/full", "yerpc/support-axum"]
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
||||
@@ -9,14 +9,19 @@
|
||||
"scripts": {
|
||||
"prettier:check": "prettier --check **.ts",
|
||||
"prettier:fix": "prettier --write **.ts",
|
||||
"build": "npm run generate-bindings && tsc",
|
||||
"bundle": "npm run build && esbuild --bundle dist/deltachat.js --outfile=dist/deltachat.bundle.js",
|
||||
"generate-bindings": "cargo test",
|
||||
"example:build": "tsc && esbuild --bundle dist/example/example.js --outfile=dist/example.bundle.js",
|
||||
"build": "run-s generate-bindings build:tsc build:bundle",
|
||||
"build:tsc": "tsc",
|
||||
"build:bundle": "esbuild --bundle dist/deltachat.js --outfile=dist/deltachat.bundle.js",
|
||||
"example": "run-s build example:build example:start",
|
||||
"example:build": "esbuild --bundle dist/example/example.js --outfile=dist/example.bundle.js",
|
||||
"example:start": "http-server .",
|
||||
"example:dev": "esbuild example/example.ts --bundle --outfile=dist/example.bundle.js --servedir=.",
|
||||
"coverage": "tsc -b test && COVERAGE=1 NODE_OPTIONS=--enable-source-maps c8 --include \"dist/*\" -r text -r html -r json mocha test_dist && node report_api_coverage.mjs",
|
||||
"test": "rm -rf dist && npm run build && npm run coverage && npm run prettier:check",
|
||||
"test": "run-s test:prepare test:run-coverage test:report-coverage",
|
||||
"test:prepare": "cargo build --features webserver --bin deltachat-jsonrpc-server",
|
||||
"test:run": "mocha dist/test",
|
||||
"test:run-coverage": "COVERAGE=1 NODE_OPTIONS=--enable-source-maps c8 --include 'dist/*' -r text -r html -r json mocha dist/test",
|
||||
"test:report-coverage": "node report_api_coverage.mjs",
|
||||
"docs": "typedoc --out docs deltachat.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -34,8 +39,10 @@
|
||||
"chai": "^4.3.4",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"esbuild": "^0.14.11",
|
||||
"http-server": "^14.1.1",
|
||||
"mocha": "^9.1.1",
|
||||
"node-fetch": "^2.6.1",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.6.2",
|
||||
"typedoc": "^0.23.2",
|
||||
"typescript": "^4.5.5",
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { readFileSync } from "fs";
|
||||
// only checks for the coverge of the api functions in bindings.ts for now
|
||||
const generated_file = "typescript/generated/client.ts";
|
||||
const generatedFile = "typescript/generated/client.ts";
|
||||
const json = JSON.parse(readFileSync("./coverage/coverage-final.json"));
|
||||
const jsonCoverage =
|
||||
json[Object.keys(json).find((k) => k.includes(generated_file))];
|
||||
json[Object.keys(json).find((k) => k.includes(generatedFile))];
|
||||
const fnMap = Object.keys(jsonCoverage.fnMap).map(
|
||||
(key) => jsonCoverage.fnMap[key]
|
||||
);
|
||||
const htmlCoverage = readFileSync(
|
||||
"./coverage/" + generated_file + ".html",
|
||||
"./coverage/" + generatedFile + ".html",
|
||||
"utf8"
|
||||
);
|
||||
const uncoveredLines = htmlCoverage
|
||||
@@ -22,7 +22,7 @@ console.log(
|
||||
uncoveredFunctions
|
||||
.map((uF) => fnMap.find(({ name }) => name === uF))
|
||||
.map(
|
||||
({ name, line }) => `.${name.padEnd(40)} (${generated_file}:${line})`
|
||||
({ name, line }) => `.${name.padEnd(40)} (${generatedFile}:${line})`
|
||||
)
|
||||
.join("\n")
|
||||
);
|
||||
|
||||
@@ -2,59 +2,55 @@ import { strictEqual } from "assert";
|
||||
import chai, { assert, expect } from "chai";
|
||||
import chaiAsPromised from "chai-as-promised";
|
||||
chai.use(chaiAsPromised);
|
||||
import { Deltachat } from "../dist/deltachat.js";
|
||||
import { Deltachat } from "../deltachat.js";
|
||||
|
||||
import {
|
||||
CMD_API_Server_Handle,
|
||||
CMD_API_SERVER_PORT,
|
||||
startCMD_API_Server,
|
||||
RpcServerHandle,
|
||||
startServer,
|
||||
} from "./test_base.js";
|
||||
|
||||
describe("basic tests", () => {
|
||||
let server_handle: CMD_API_Server_Handle;
|
||||
let serverHandle: RpcServerHandle;
|
||||
let dc: Deltachat;
|
||||
|
||||
before(async () => {
|
||||
server_handle = await startCMD_API_Server(CMD_API_SERVER_PORT);
|
||||
serverHandle = await startServer();
|
||||
// make sure server is up by the time we continue
|
||||
await new Promise((res) => setTimeout(res, 100));
|
||||
|
||||
dc = new Deltachat({
|
||||
url: "ws://localhost:" + CMD_API_SERVER_PORT + "/ws",
|
||||
});
|
||||
dc.on("ALL", (event) => {
|
||||
dc = new Deltachat(serverHandle.url)
|
||||
// dc.on("ALL", (event) => {
|
||||
//console.log("event", event);
|
||||
});
|
||||
// });
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
dc && dc.close();
|
||||
await server_handle.close();
|
||||
await serverHandle.close();
|
||||
});
|
||||
|
||||
it("check email", async () => {
|
||||
const positive_test_cases = [
|
||||
it("check email address validity", async () => {
|
||||
const validAddresses = [
|
||||
"email@example.com",
|
||||
"36aa165ae3406424e0c61af17700f397cad3fe8ab83d682d0bddf3338a5dd52e@yggmail@yggmail",
|
||||
];
|
||||
const negative_test_cases = ["email@", "example.com", "emai221"];
|
||||
const invalidAddresses = ["email@", "example.com", "emai221"];
|
||||
|
||||
expect(
|
||||
await Promise.all(
|
||||
positive_test_cases.map((email) => dc.rpc.checkEmailValidity(email))
|
||||
validAddresses.map((email) => dc.rpc.checkEmailValidity(email))
|
||||
)
|
||||
).to.not.contain(false);
|
||||
|
||||
expect(
|
||||
await Promise.all(
|
||||
negative_test_cases.map((email) => dc.rpc.checkEmailValidity(email))
|
||||
invalidAddresses.map((email) => dc.rpc.checkEmailValidity(email))
|
||||
)
|
||||
).to.not.contain(true);
|
||||
});
|
||||
|
||||
it("system info", async () => {
|
||||
const system_info = await dc.rpc.getSystemInfo();
|
||||
expect(system_info).to.contain.keys([
|
||||
const systemInfo = await dc.rpc.getSystemInfo();
|
||||
expect(systemInfo).to.contain.keys([
|
||||
"arch",
|
||||
"num_cpus",
|
||||
"deltachat_core_version",
|
||||
@@ -64,7 +60,8 @@ describe("basic tests", () => {
|
||||
|
||||
describe("account managment", () => {
|
||||
it("should create account", async () => {
|
||||
await dc.rpc.addAccount();
|
||||
const res = await dc.rpc.addAccount();
|
||||
console.log('res', res)
|
||||
assert((await dc.rpc.getAllAccountIds()).length === 1);
|
||||
});
|
||||
|
||||
@@ -83,55 +80,55 @@ describe("basic tests", () => {
|
||||
});
|
||||
|
||||
describe("contact managment", function () {
|
||||
let acc: number;
|
||||
let accountId: number;
|
||||
before(async () => {
|
||||
acc = await dc.rpc.addAccount();
|
||||
accountId = await dc.rpc.addAccount();
|
||||
});
|
||||
it("block and unblock contact", async function () {
|
||||
it("should block and unblock contact", async function () {
|
||||
const contactId = await dc.rpc.contactsCreateContact(
|
||||
acc,
|
||||
accountId,
|
||||
"example@delta.chat",
|
||||
null
|
||||
);
|
||||
expect((await dc.rpc.contactsGetContact(acc, contactId)).is_blocked).to.be
|
||||
expect((await dc.rpc.contactsGetContact(accountId, contactId)).is_blocked).to.be
|
||||
.false;
|
||||
await dc.rpc.contactsBlock(acc, contactId);
|
||||
expect((await dc.rpc.contactsGetContact(acc, contactId)).is_blocked).to.be
|
||||
await dc.rpc.contactsBlock(accountId, contactId);
|
||||
expect((await dc.rpc.contactsGetContact(accountId, contactId)).is_blocked).to.be
|
||||
.true;
|
||||
expect(await dc.rpc.contactsGetBlocked(acc)).to.have.length(1);
|
||||
await dc.rpc.contactsUnblock(acc, contactId);
|
||||
expect((await dc.rpc.contactsGetContact(acc, contactId)).is_blocked).to.be
|
||||
expect(await dc.rpc.contactsGetBlocked(accountId)).to.have.length(1);
|
||||
await dc.rpc.contactsUnblock(accountId, contactId);
|
||||
expect((await dc.rpc.contactsGetContact(accountId, contactId)).is_blocked).to.be
|
||||
.false;
|
||||
expect(await dc.rpc.contactsGetBlocked(acc)).to.have.length(0);
|
||||
expect(await dc.rpc.contactsGetBlocked(accountId)).to.have.length(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("configuration", function () {
|
||||
let acc: number;
|
||||
let accountId: number;
|
||||
before(async () => {
|
||||
acc = await dc.rpc.addAccount();
|
||||
accountId = await dc.rpc.addAccount();
|
||||
});
|
||||
|
||||
it("set and retrive", async function () {
|
||||
await dc.rpc.setConfig(acc, "addr", "valid@email");
|
||||
assert((await dc.rpc.getConfig(acc, "addr")) == "valid@email");
|
||||
await dc.rpc.setConfig(accountId, "addr", "valid@email");
|
||||
assert((await dc.rpc.getConfig(accountId, "addr")) == "valid@email");
|
||||
});
|
||||
it("set invalid key should throw", async function () {
|
||||
await expect(dc.rpc.setConfig(acc, "invalid_key", "some value")).to.be
|
||||
await expect(dc.rpc.setConfig(accountId, "invalid_key", "some value")).to.be
|
||||
.eventually.rejected;
|
||||
});
|
||||
it("get invalid key should throw", async function () {
|
||||
await expect(dc.rpc.getConfig(acc, "invalid_key")).to.be.eventually
|
||||
await expect(dc.rpc.getConfig(accountId, "invalid_key")).to.be.eventually
|
||||
.rejected;
|
||||
});
|
||||
it("set and retrive ui.*", async function () {
|
||||
await dc.rpc.setConfig(acc, "ui.chat_bg", "color:red");
|
||||
assert((await dc.rpc.getConfig(acc, "ui.chat_bg")) == "color:red");
|
||||
await dc.rpc.setConfig(accountId, "ui.chat_bg", "color:red");
|
||||
assert((await dc.rpc.getConfig(accountId, "ui.chat_bg")) == "color:red");
|
||||
});
|
||||
it("set and retrive (batch)", async function () {
|
||||
const config = { addr: "valid@email", mail_pw: "1234" };
|
||||
await dc.rpc.batchSetConfig(acc, config);
|
||||
const retrieved = await dc.rpc.batchGetConfig(acc, Object.keys(config));
|
||||
await dc.rpc.batchSetConfig(accountId, config);
|
||||
const retrieved = await dc.rpc.batchGetConfig(accountId, Object.keys(config));
|
||||
expect(retrieved).to.deep.equal(config);
|
||||
});
|
||||
it("set and retrive ui.* (batch)", async function () {
|
||||
@@ -139,8 +136,8 @@ describe("basic tests", () => {
|
||||
"ui.chat_bg": "color:green",
|
||||
"ui.enter_key_sends": "true",
|
||||
};
|
||||
await dc.rpc.batchSetConfig(acc, config);
|
||||
const retrieved = await dc.rpc.batchGetConfig(acc, Object.keys(config));
|
||||
await dc.rpc.batchSetConfig(accountId, config);
|
||||
const retrieved = await dc.rpc.batchGetConfig(accountId, Object.keys(config));
|
||||
expect(retrieved).to.deep.equal(config);
|
||||
});
|
||||
it("set and retrive mixed(ui and core) (batch)", async function () {
|
||||
@@ -150,8 +147,8 @@ describe("basic tests", () => {
|
||||
addr: "valid2@email",
|
||||
mail_pw: "123456",
|
||||
};
|
||||
await dc.rpc.batchSetConfig(acc, config);
|
||||
const retrieved = await dc.rpc.batchGetConfig(acc, Object.keys(config));
|
||||
await dc.rpc.batchSetConfig(accountId, config);
|
||||
const retrieved = await dc.rpc.batchGetConfig(accountId, Object.keys(config));
|
||||
expect(retrieved).to.deep.equal(config);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
import { assert, expect } from "chai";
|
||||
import { Deltachat, DeltachatEvent, EventTypeName } from "../dist/deltachat.js";
|
||||
import { Deltachat, DeltachatEvent, EventTypeName } from "../deltachat.js";
|
||||
import {
|
||||
CMD_API_Server_Handle,
|
||||
CMD_API_SERVER_PORT,
|
||||
RpcServerHandle,
|
||||
createTempUser,
|
||||
startCMD_API_Server,
|
||||
startServer,
|
||||
} from "./test_base.js";
|
||||
|
||||
const EVENT_TIMEOUT = 10000
|
||||
|
||||
describe("online tests", function () {
|
||||
let server_handle: CMD_API_Server_Handle;
|
||||
let serverHandle: RpcServerHandle;
|
||||
let dc: Deltachat;
|
||||
let account: { email: string; password: string };
|
||||
let account1: { email: string; password: string };
|
||||
let account2: { email: string; password: string };
|
||||
let acc1: number, acc2: number;
|
||||
let accountId1: number, accountId2: number;
|
||||
|
||||
before(async function () {
|
||||
this.timeout(12000)
|
||||
@@ -29,17 +30,15 @@ describe("online tests", function () {
|
||||
);
|
||||
this.skip();
|
||||
}
|
||||
server_handle = await startCMD_API_Server(CMD_API_SERVER_PORT);
|
||||
dc = new Deltachat({
|
||||
url: "ws://localhost:" + CMD_API_SERVER_PORT + "/ws",
|
||||
});
|
||||
serverHandle = await startServer();
|
||||
dc = new Deltachat(serverHandle.url)
|
||||
|
||||
dc.on("ALL", ({ id, contextId }) => {
|
||||
if (id !== "Info") console.log(contextId, id);
|
||||
});
|
||||
|
||||
account = await createTempUser(process.env.DCC_NEW_TMP_EMAIL);
|
||||
if (!account || !account.email || !account.password) {
|
||||
account1 = await createTempUser(process.env.DCC_NEW_TMP_EMAIL);
|
||||
if (!account1 || !account1.email || !account1.password) {
|
||||
console.log(
|
||||
"We didn't got back an account from the api, skip intergration tests"
|
||||
);
|
||||
@@ -47,6 +46,7 @@ describe("online tests", function () {
|
||||
}
|
||||
|
||||
account2 = await createTempUser(process.env.DCC_NEW_TMP_EMAIL);
|
||||
console.log({ account: account1, account2 })
|
||||
if (!account2 || !account2.email || !account2.password) {
|
||||
console.log(
|
||||
"We didn't got back an account2 from the api, skip intergration tests"
|
||||
@@ -57,108 +57,109 @@ describe("online tests", function () {
|
||||
|
||||
after(async () => {
|
||||
dc && dc.close();
|
||||
server_handle && (await server_handle.close());
|
||||
serverHandle && (await serverHandle.close());
|
||||
});
|
||||
|
||||
let are_configured = false;
|
||||
let accountsConfigured = false;
|
||||
|
||||
it("configure test accounts", async function () {
|
||||
this.timeout(20000);
|
||||
|
||||
acc1 = await dc.rpc.addAccount();
|
||||
await dc.rpc.setConfig(acc1, "addr", account.email);
|
||||
await dc.rpc.setConfig(acc1, "mail_pw", account.password);
|
||||
let configure_promise = dc.rpc.configure(acc1);
|
||||
accountId1 = await dc.rpc.addAccount();
|
||||
await dc.rpc.setConfig(accountId1, "addr", account1.email);
|
||||
await dc.rpc.setConfig(accountId1, "mail_pw", account1.password);
|
||||
console.log('config set')
|
||||
await dc.rpc.configure(accountId1);
|
||||
console.log('account configured')
|
||||
|
||||
acc2 = await dc.rpc.addAccount();
|
||||
await dc.rpc.batchSetConfig(acc2, {
|
||||
accountId2 = await dc.rpc.addAccount();
|
||||
await dc.rpc.batchSetConfig(accountId2, {
|
||||
addr: account2.email,
|
||||
mail_pw: account2.password,
|
||||
});
|
||||
|
||||
await Promise.all([configure_promise, dc.rpc.configure(acc2)]);
|
||||
are_configured = true;
|
||||
await dc.rpc.configure(accountId2)
|
||||
accountsConfigured = true;
|
||||
});
|
||||
|
||||
it("send and recieve text message", async function () {
|
||||
if (!are_configured) {
|
||||
if (!accountsConfigured) {
|
||||
this.skip();
|
||||
}
|
||||
this.timeout(15000);
|
||||
|
||||
const contactId = await dc.rpc.contactsCreateContact(
|
||||
acc1,
|
||||
accountId1,
|
||||
account2.email,
|
||||
null
|
||||
);
|
||||
const chatId = await dc.rpc.contactsCreateChatByContactId(acc1, contactId);
|
||||
const chatId = await dc.rpc.contactsCreateChatByContactId(accountId1, contactId);
|
||||
const eventPromise = Promise.race([
|
||||
waitForEvent(dc, "MsgsChanged", acc2),
|
||||
waitForEvent(dc, "IncomingMsg", acc2),
|
||||
waitForEvent(dc, "MsgsChanged", accountId2),
|
||||
waitForEvent(dc, "IncomingMsg", accountId2),
|
||||
]);
|
||||
|
||||
dc.rpc.miscSendTextMessage(acc1, "Hello", chatId);
|
||||
await dc.rpc.miscSendTextMessage(accountId1, "Hello", chatId);
|
||||
const { field1: chatIdOnAccountB } = await eventPromise;
|
||||
await dc.rpc.acceptChat(acc2, chatIdOnAccountB);
|
||||
await dc.rpc.acceptChat(accountId2, chatIdOnAccountB);
|
||||
const messageList = await dc.rpc.messageListGetMessageIds(
|
||||
acc2,
|
||||
accountId2,
|
||||
chatIdOnAccountB,
|
||||
0
|
||||
);
|
||||
|
||||
expect(messageList).have.length(1);
|
||||
const message = await dc.rpc.messageGetMessage(acc2, messageList[0]);
|
||||
const message = await dc.rpc.messageGetMessage(accountId2, messageList[0]);
|
||||
expect(message.text).equal("Hello");
|
||||
});
|
||||
|
||||
it("send and recieve text message roundtrip, encrypted on answer onwards", async function () {
|
||||
if (!are_configured) {
|
||||
if (!accountsConfigured) {
|
||||
this.skip();
|
||||
}
|
||||
this.timeout(10000);
|
||||
|
||||
// send message from A to B
|
||||
const contactId = await dc.rpc.contactsCreateContact(
|
||||
acc1,
|
||||
accountId1,
|
||||
account2.email,
|
||||
null
|
||||
);
|
||||
const chatId = await dc.rpc.contactsCreateChatByContactId(acc1, contactId);
|
||||
const chatId = await dc.rpc.contactsCreateChatByContactId(accountId1, contactId);
|
||||
const eventPromise = Promise.race([
|
||||
waitForEvent(dc, "MsgsChanged", acc2),
|
||||
waitForEvent(dc, "IncomingMsg", acc2),
|
||||
waitForEvent(dc, "MsgsChanged", accountId2),
|
||||
waitForEvent(dc, "IncomingMsg", accountId2),
|
||||
]);
|
||||
dc.rpc.miscSendTextMessage(acc1, "Hello2", chatId);
|
||||
dc.rpc.miscSendTextMessage(accountId1, "Hello2", chatId);
|
||||
// wait for message from A
|
||||
console.log("wait for message from A");
|
||||
|
||||
const event = await eventPromise;
|
||||
const { field1: chatIdOnAccountB } = event;
|
||||
|
||||
await dc.rpc.acceptChat(acc2, chatIdOnAccountB);
|
||||
await dc.rpc.acceptChat(accountId2, chatIdOnAccountB);
|
||||
const messageList = await dc.rpc.messageListGetMessageIds(
|
||||
acc2,
|
||||
accountId2,
|
||||
chatIdOnAccountB,
|
||||
0
|
||||
);
|
||||
const message = await dc.rpc.messageGetMessage(
|
||||
acc2,
|
||||
accountId2,
|
||||
messageList.reverse()[0]
|
||||
);
|
||||
expect(message.text).equal("Hello2");
|
||||
// Send message back from B to A
|
||||
const eventPromise2 = Promise.race([
|
||||
waitForEvent(dc, "MsgsChanged", acc1),
|
||||
waitForEvent(dc, "IncomingMsg", acc1),
|
||||
waitForEvent(dc, "MsgsChanged", accountId1),
|
||||
waitForEvent(dc, "IncomingMsg", accountId1),
|
||||
]);
|
||||
dc.rpc.miscSendTextMessage(acc2, "super secret message", chatId);
|
||||
dc.rpc.miscSendTextMessage(accountId2, "super secret message", chatId);
|
||||
// Check if answer arives at A and if it is encrypted
|
||||
await eventPromise2;
|
||||
|
||||
const messageId = (
|
||||
await dc.rpc.messageListGetMessageIds(acc1, chatId, 0)
|
||||
await dc.rpc.messageListGetMessageIds(accountId1, chatId, 0)
|
||||
).reverse()[0];
|
||||
const message2 = await dc.rpc.messageGetMessage(acc1, messageId);
|
||||
const message2 = await dc.rpc.messageGetMessage(accountId1, messageId);
|
||||
expect(message2.text).equal("super secret message");
|
||||
expect(message2.show_padlock).equal(true);
|
||||
});
|
||||
@@ -181,23 +182,24 @@ describe("online tests", function () {
|
||||
});
|
||||
});
|
||||
|
||||
type event_data = {
|
||||
contextId: number;
|
||||
id: EventTypeName;
|
||||
[key: string]: any;
|
||||
};
|
||||
async function waitForEvent(
|
||||
dc: Deltachat,
|
||||
event: EventTypeName,
|
||||
accountId: number
|
||||
): Promise<event_data> {
|
||||
return new Promise((res, rej) => {
|
||||
const callback = (ev: DeltachatEvent) => {
|
||||
if (ev.contextId == accountId) {
|
||||
dc.off(event, callback);
|
||||
res(ev);
|
||||
eventType: EventTypeName,
|
||||
accountId: number,
|
||||
timeout: number = EVENT_TIMEOUT
|
||||
): Promise<DeltachatEvent> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const rejectTimeout = setTimeout(
|
||||
() => reject(new Error('Timeout reached before event came in')),
|
||||
timeout
|
||||
)
|
||||
const callback = (event: DeltachatEvent) => {
|
||||
if (event.contextId == accountId) {
|
||||
dc.off(eventType, callback);
|
||||
clearTimeout(rejectTimeout)
|
||||
resolve(event);
|
||||
}
|
||||
};
|
||||
dc.on(event, callback);
|
||||
dc.on(eventType, callback);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,28 +1,90 @@
|
||||
import { tmpdir } from "os";
|
||||
import { join } from "path";
|
||||
import { join, resolve } from "path";
|
||||
import { mkdtemp, rm } from "fs/promises";
|
||||
import { existsSync } from "fs";
|
||||
import { spawn, exec } from "child_process";
|
||||
import { unwrapPromise } from "./ts_helpers.js";
|
||||
import fetch from "node-fetch";
|
||||
/* port is not configurable yet */
|
||||
|
||||
export const RPC_SERVER_PORT = 20808;
|
||||
|
||||
export type RpcServerHandle = {
|
||||
url: string,
|
||||
close: () => Promise<void>
|
||||
}
|
||||
|
||||
export async function startServer(port: number = RPC_SERVER_PORT): Promise<RpcServerHandle> {
|
||||
const tmpDir = await mkdtemp(join(tmpdir(), "deltachat-jsonrpc-test"));
|
||||
|
||||
const pathToServerBinary = resolve(join(await getTargetDir(), "debug/deltachat-jsonrpc-server"));
|
||||
console.log('using server binary: ' + pathToServerBinary);
|
||||
|
||||
if (!existsSync(pathToServerBinary)) {
|
||||
throw new Error(
|
||||
"server executable does not exist, you need to build it first" +
|
||||
"\nserver executable not found at " +
|
||||
pathToServerBinary
|
||||
);
|
||||
}
|
||||
|
||||
const server = spawn(pathToServerBinary, {
|
||||
cwd: tmpDir,
|
||||
env: {
|
||||
RUST_LOG: process.env.RUST_LOG || "info",
|
||||
DC_PORT: '' + port
|
||||
},
|
||||
});
|
||||
let shouldClose = false;
|
||||
|
||||
server.on("exit", () => {
|
||||
if (shouldClose) {
|
||||
return;
|
||||
}
|
||||
throw new Error("Server quit");
|
||||
});
|
||||
|
||||
server.stderr.pipe(process.stderr);
|
||||
server.stdout.pipe(process.stdout)
|
||||
|
||||
const url = `ws://localhost:${port}/ws`
|
||||
|
||||
return {
|
||||
url,
|
||||
close: async () => {
|
||||
shouldClose = true;
|
||||
if (!server.kill()) {
|
||||
console.log("server termination failed");
|
||||
}
|
||||
await rm(tmpDir, { recursive: true });
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export async function createTempUser(url: string) {
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"cache-control": "no-cache",
|
||||
},
|
||||
});
|
||||
if (!response.ok) throw new Error('Received invalid response')
|
||||
return response.json();
|
||||
}
|
||||
|
||||
function getTargetDir(): Promise<string> {
|
||||
return new Promise((res, rej) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
exec(
|
||||
"cargo metadata --no-deps --format-version 1",
|
||||
(error, stdout, stderr) => {
|
||||
(error, stdout, _stderr) => {
|
||||
if (error) {
|
||||
console.log("error", error);
|
||||
rej(error);
|
||||
reject(error);
|
||||
} else {
|
||||
try {
|
||||
const json = JSON.parse(stdout);
|
||||
res(json.target_directory);
|
||||
resolve(json.target_directory);
|
||||
} catch (error) {
|
||||
console.log("json error", error);
|
||||
rej(error);
|
||||
reject(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,66 +92,3 @@ function getTargetDir(): Promise<string> {
|
||||
});
|
||||
}
|
||||
|
||||
export const CMD_API_SERVER_PORT = 20808;
|
||||
export async function startCMD_API_Server(port: typeof CMD_API_SERVER_PORT) {
|
||||
const tmp_dir = await mkdtemp(join(tmpdir(), "test_prefix"));
|
||||
|
||||
const path_of_server = join(await getTargetDir(), "debug/webserver");
|
||||
console.log(path_of_server);
|
||||
|
||||
if (!existsSync(path_of_server)) {
|
||||
throw new Error(
|
||||
"server executable does not exist, you need to build it first" +
|
||||
"\nserver executable not found at " +
|
||||
path_of_server
|
||||
);
|
||||
}
|
||||
|
||||
const server = spawn(path_of_server, {
|
||||
cwd: tmp_dir,
|
||||
env: {
|
||||
RUST_LOG: "info",
|
||||
},
|
||||
});
|
||||
let should_close = false;
|
||||
|
||||
server.on("exit", () => {
|
||||
if (should_close) {
|
||||
return;
|
||||
}
|
||||
throw new Error("Server quit");
|
||||
});
|
||||
|
||||
server.stderr.pipe(process.stderr);
|
||||
|
||||
//server.stdout.pipe(process.stdout)
|
||||
|
||||
return {
|
||||
close: async () => {
|
||||
should_close = true;
|
||||
if (!server.kill(9)) {
|
||||
console.log("server termination failed");
|
||||
}
|
||||
await rm(tmp_dir, { recursive: true });
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export type CMD_API_Server_Handle = unwrapPromise<
|
||||
ReturnType<typeof startCMD_API_Server>
|
||||
>;
|
||||
|
||||
export async function createTempUser(url: string) {
|
||||
async function postData(url = "") {
|
||||
// Default options are marked with *
|
||||
const response = await fetch(url, {
|
||||
method: "POST", // *GET, POST, PUT, DELETE, etc.
|
||||
headers: {
|
||||
"cache-control": "no-cache",
|
||||
},
|
||||
});
|
||||
return response.json(); // parses JSON response into native JavaScript objects
|
||||
}
|
||||
|
||||
return await postData(url);
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export type unwrapPromise<T> = T extends Promise<infer U> ? U : never;
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"rootDir": ".",
|
||||
"outDir": "../test_dist",
|
||||
"target": "ES2020",
|
||||
"module": "es2020",
|
||||
"moduleResolution": "node",
|
||||
"declaration": false,
|
||||
"esModuleInterop": true,
|
||||
"noImplicitAny": true,
|
||||
"isolatedModules": true,
|
||||
"strictNullChecks": true,
|
||||
"strict": true,
|
||||
"sourceMap": true
|
||||
},
|
||||
"compileOnSave": true
|
||||
}
|
||||
@@ -8,13 +8,13 @@
|
||||
"outDir": "dist",
|
||||
"lib": ["ES2017", "dom"],
|
||||
"target": "ES2017",
|
||||
"module": "es2015",
|
||||
"module": "es2020",
|
||||
"declaration": true,
|
||||
"esModuleInterop": true,
|
||||
"moduleResolution": "node",
|
||||
"noImplicitAny": true,
|
||||
"isolatedModules": true
|
||||
},
|
||||
"include": ["*.ts", "example/*.ts"],
|
||||
"include": ["*.ts", "example/*.ts", "test/*.ts"],
|
||||
"compileOnSave": false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user