mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-23 06:22:43 +00:00
nodejs: add tests to library (#7694)
* nodejs: add tests to library * new tests * remove message splitting * fix race * docs * replace extract-zip with yauzl that it wraps (high severity issue) * fix ci tests * skip server tests on macos and win unless SMP_SERVER is set * fix win test * fix win test --------- Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
This commit is contained in:
1 parent
ba9269a3ad
commit
46b2cf9f85
73 files changed
+957
-265
No files matched your search
@@ -2,17 +2,25 @@ import * as path from "path"
|
||||
import * as fs from "fs"
|
||||
import {CEvt, T} from "@simplex-chat/types"
|
||||
import {api} from ".."
|
||||
import {SmpServer, describeIfSmpServerAvailable, startSmpServer} from "./smpServer"
|
||||
|
||||
const CT = T.ChatType
|
||||
|
||||
describe("API tests (use preset servers)", () => {
|
||||
describeIfSmpServerAvailable("API tests (use local SMP server)", () => {
|
||||
const tmpDir = "./tests/tmp"
|
||||
const alicePath = path.join(tmpDir, "alice")
|
||||
const bobPath = path.join(tmpDir, "bob")
|
||||
let smpServer: SmpServer
|
||||
|
||||
beforeAll(async () => { smpServer = await startSmpServer() }, 120000)
|
||||
afterAll(() => smpServer?.stop())
|
||||
beforeEach(() => fs.mkdirSync(tmpDir, {recursive: true}))
|
||||
afterEach(() => fs.rmSync(tmpDir, {recursive: true, force: true}))
|
||||
|
||||
async function useSmpServer(chat: api.ChatApi): Promise<void> {
|
||||
expect(await chat.sendChatCmd(`/smp ${smpServer.address}`)).toMatchObject({type: "cmdOk"})
|
||||
}
|
||||
|
||||
it("should send/receive message", async () => {
|
||||
// create users and start chat controllers
|
||||
const alice = await api.ChatApi.init({type: "sqlite", filePrefix: alicePath})
|
||||
@@ -27,32 +35,37 @@ describe("API tests (use preset servers)", () => {
|
||||
await bob.apiCreateActiveUser({displayName: "bob", fullName: ""})
|
||||
await alice.startChat()
|
||||
await bob.startChat()
|
||||
await useSmpServer(alice)
|
||||
await useSmpServer(bob)
|
||||
// connect via link
|
||||
const link = await alice.apiCreateLink(aliceUser.userId)
|
||||
const connected = Promise.all([alice.wait("contactConnected"), bob.wait("contactConnected")])
|
||||
await expect(bob.apiConnectActiveUser(link)).resolves.toBe(api.ConnReqType.Invitation)
|
||||
const [bobContact, aliceContact] = await Promise.all([
|
||||
(await alice.wait("contactConnected")).contact,
|
||||
(await bob.wait("contactConnected")).contact
|
||||
])
|
||||
const [{contact: bobContact}, {contact: aliceContact}] = await connected
|
||||
expect(bobContact).toMatchObject({profile: {displayName: "bob"}})
|
||||
expect(aliceContact).toMatchObject({profile: {displayName: "alice"}})
|
||||
// exchange messages
|
||||
const isMessage = ({contactId}: T.Contact, msg: string) => (evt: CEvt.NewChatItems) =>
|
||||
evt.chatItems.some(ci => ci.chatInfo.type === CT.Direct && ci.chatInfo.contact.contactId === contactId && ci.chatItem.meta.itemText === msg)
|
||||
const hello = bob.wait("newChatItems", isMessage(aliceContact, "hello"))
|
||||
await alice.apiSendTextMessage([CT.Direct, bobContact.contactId], "hello")
|
||||
await bob.wait("newChatItems", isMessage(aliceContact, "hello"))
|
||||
await hello
|
||||
const helloToo = alice.wait("newChatItems", isMessage(bobContact, "hello too"), 10000)
|
||||
await bob.apiSendTextMessage([CT.Direct, aliceContact.contactId], "hello too")
|
||||
await alice.wait("newChatItems", isMessage(bobContact, "hello too"), 10000)
|
||||
await expect(helloToo).resolves.toBeDefined()
|
||||
const howAreYou = bob.wait("newChatItems", isMessage(aliceContact, "how are you?"))
|
||||
await alice.apiSendTextMessage([CT.Direct, bobContact.contactId], "how are you?")
|
||||
await bob.wait("newChatItems", isMessage(aliceContact, "how are you?"))
|
||||
await howAreYou
|
||||
const okAndYou = alice.wait("newChatItems", isMessage(bobContact, "ok, and you?"), 10000)
|
||||
await bob.apiSendTextMessage([CT.Direct, aliceContact.contactId], "ok, and you?")
|
||||
await alice.wait("newChatItems", isMessage(bobContact, "ok, and you?"), 10000)
|
||||
await expect(okAndYou).resolves.toBeDefined()
|
||||
// no more messages
|
||||
await expect(alice.wait("newChatItems", 500)).resolves.toBeUndefined()
|
||||
await expect(bob.wait("newChatItems", 500)).resolves.toBeUndefined()
|
||||
// delete contacts, stop chat controllers and close databases
|
||||
const deleted = bob.wait("contactDeletedByContact")
|
||||
await alice.apiDeleteChat(CT.Direct, bobContact.contactId)
|
||||
await bob.wait("contactDeletedByContact")
|
||||
await deleted
|
||||
await bob.apiDeleteChat(CT.Direct, aliceContact.contactId)
|
||||
await alice.stopChat()
|
||||
await bob.stopChat()
|
||||
@@ -60,8 +73,7 @@ describe("API tests (use preset servers)", () => {
|
||||
await bob.close()
|
||||
await expect(alice.startChat()).rejects.toThrow("chat api controller not initialized")
|
||||
await expect(bob.startChat()).rejects.toThrow("chat api controller not initialized")
|
||||
expect(servers.length).toBe(2)
|
||||
expect(servers[0] !== servers[1]).toBe(true)
|
||||
expect([...new Set(servers)]).toEqual(["localhost"])
|
||||
expect(eventCount > 0).toBe(true)
|
||||
}, 30000)
|
||||
|
||||
@@ -77,20 +89,19 @@ describe("API tests (use preset servers)", () => {
|
||||
await alice.startChat()
|
||||
await bob.startChat()
|
||||
await carol.startChat()
|
||||
await useSmpServer(alice)
|
||||
await useSmpServer(bob)
|
||||
await useSmpServer(carol)
|
||||
// connect alice <-> bob
|
||||
const aliceLink1 = await alice.apiCreateLink(aliceUser.userId)
|
||||
const bobConnected = Promise.all([alice.wait("contactConnected"), bob.wait("contactConnected")])
|
||||
await expect(bob.apiConnectActiveUser(aliceLink1)).resolves.toBe(api.ConnReqType.Invitation)
|
||||
const [bobContact] = await Promise.all([
|
||||
(await alice.wait("contactConnected")).contact,
|
||||
(await bob.wait("contactConnected")).contact
|
||||
])
|
||||
const [{contact: bobContact}] = await bobConnected
|
||||
// connect alice <-> carol
|
||||
const aliceLink2 = await alice.apiCreateLink(aliceUser.userId)
|
||||
const carolConnected = Promise.all([alice.wait("contactConnected"), carol.wait("contactConnected")])
|
||||
await expect(carol.apiConnectActiveUser(aliceLink2)).resolves.toBe(api.ConnReqType.Invitation)
|
||||
const [carolContact] = await Promise.all([
|
||||
(await alice.wait("contactConnected")).contact,
|
||||
(await carol.wait("contactConnected")).contact
|
||||
])
|
||||
const [{contact: carolContact}] = await carolConnected
|
||||
// create group with direct messages enabled
|
||||
const group = await alice.apiNewGroup(aliceUser.userId, {
|
||||
displayName: "test-group",
|
||||
@@ -105,10 +116,10 @@ describe("API tests (use preset servers)", () => {
|
||||
await alice.apiAddMember(groupId, bobContact.contactId, T.GroupMemberRole.Member)
|
||||
const bobInvEvt = await bobInvP
|
||||
expect(bobInvEvt).toBeDefined()
|
||||
const aliceBobConnP = alice.wait("connectedToGroupMember", 15000)
|
||||
const bobAliceConnP = bob.wait("connectedToGroupMember", 15000)
|
||||
const aliceBobConnP = alice.wait("joinedGroupMember", 15000)
|
||||
const bobAliceConnP = bob.wait("userJoinedGroup", 15000)
|
||||
await bob.apiJoinGroup(bobInvEvt!.groupInfo.groupId)
|
||||
await Promise.all([aliceBobConnP, bobAliceConnP])
|
||||
expect(await Promise.all([aliceBobConnP, bobAliceConnP])).not.toContain(undefined)
|
||||
// add carol to the group
|
||||
const carolInvP = carol.wait("receivedGroupInvitation", 30000)
|
||||
await alice.apiAddMember(groupId, carolContact.contactId, T.GroupMemberRole.Member)
|
||||
@@ -117,14 +128,13 @@ describe("API tests (use preset servers)", () => {
|
||||
// wait for carol to connect to both alice and bob (and vice versa)
|
||||
const bobCarolConnP = bob.wait("connectedToGroupMember",
|
||||
(evt: CEvt.ConnectedToGroupMember) => evt.member.memberProfile.displayName === "carol", 30000)
|
||||
const carolAliceConnP = carol.wait("connectedToGroupMember",
|
||||
(evt: CEvt.ConnectedToGroupMember) => evt.member.memberProfile.displayName === "alice", 30000)
|
||||
const carolAliceConnP = carol.wait("userJoinedGroup", 30000)
|
||||
const carolBobConnP = carol.wait("connectedToGroupMember",
|
||||
(evt: CEvt.ConnectedToGroupMember) => evt.member.memberProfile.displayName === "bob", 30000)
|
||||
const aliceCarolConnP = alice.wait("connectedToGroupMember",
|
||||
(evt: CEvt.ConnectedToGroupMember) => evt.member.memberProfile.displayName === "carol", 30000)
|
||||
const aliceCarolConnP = alice.wait("joinedGroupMember",
|
||||
(evt: CEvt.JoinedGroupMember) => evt.member.memberProfile.displayName === "carol", 30000)
|
||||
await carol.apiJoinGroup(carolInvEvt!.groupInfo.groupId)
|
||||
await Promise.all([bobCarolConnP, carolAliceConnP, carolBobConnP, aliceCarolConnP])
|
||||
expect(await Promise.all([bobCarolConnP, carolAliceConnP, carolBobConnP, aliceCarolConnP])).not.toContain(undefined)
|
||||
// find carol's memberId from bob's perspective
|
||||
const members = await bob.apiListMembers(groupId)
|
||||
const carolMember = members.find(m => m.memberProfile.displayName === "carol")
|
||||
|
||||
Reference in new issue
Block a user