import { MjolnirAppService } from "../../../src/appservice/AppService"; import { newTestUser } from "../../integration/clientHelper"; import { isPolicyRoom, readTestConfig, setupHarness } from "../utils/harness"; import { CreateMjolnirResponse, MjolnirWebAPIClient } from "../utils/webAPIClient"; import { MatrixClient } from "matrix-bot-sdk"; import { getFirstReply } from "../../integration/commands/commandUtils"; import expect from "expect"; import dns from 'node:dns'; interface Context extends Mocha.Context { appservice?: MjolnirAppService moderator?: MatrixClient } // Necessary for CI: Node 17+ defaults to using ipv6 first, but Github Actions does not support ipv6 dns.setDefaultResultOrder('ipv4first'); describe("Test that the app service can provision a mjolnir when requested from the web API", function () { afterEach(function(this: Context) { this.moderator?.stop(); if (this.appservice) { return this.appservice.close(); } else { console.warn("Missing Appservice in this context, so cannot stop it.") return Promise.resolve(); // TS7030: Not all code paths return a value. } }); it("A moderator that requests a mjolnir via a matrix invitation will be invited to a new policy and management room", async function (this: Context) { const config = readTestConfig(); this.appservice = await setupHarness(); // create a moderator const moderator = await newTestUser(config.homeserver.url, { name: { contains: "test" } }); const apiClient = await MjolnirWebAPIClient.makeClient(moderator, "http://localhost:9001"); const roomToProtectId = await moderator.createRoom({ preset: "public_chat" }); // have the moderator invite the appservice bot in order to request a new mjolnir this.moderator = moderator; const roomsInvitedTo: string[] = []; const mjolnirDetails: CreateMjolnirResponse = await new Promise(async resolve => { const mjolnirDetailsPromise = apiClient.createMjolnir(roomToProtectId); moderator.on('room.invite', (roomId: string) => { roomsInvitedTo.push(roomId) // the appservice should invite it to a policy room and a management room. if (roomsInvitedTo.length === 2) { mjolnirDetailsPromise.then(resolve); } }); await moderator.start(); }); await Promise.all(roomsInvitedTo.map(roomId => moderator.joinRoom(roomId))); const managementRoomId = roomsInvitedTo.filter(async roomId => !(await isPolicyRoom(moderator, roomId)))[0]; expect(managementRoomId).toBe(mjolnirDetails.managementRoomId); // Check that the newly provisioned mjolnir is actually responsive. const event = await getFirstReply(moderator, managementRoomId, () => { return moderator.sendMessage(managementRoomId, { body: `!mjolnir status`, msgtype: 'm.text' }); }) expect(event.sender).toBe(mjolnirDetails.mjolnirUserId); }) })