Remove `matrix-bot-sdk` usage in tests (#15)

Remove `matrix-bot-sdk` usage in tests because it didn't have timestamp massaging `?ts` and it's not really necessary to rely on since we can just call the API directly 🤷. `matrix-bot-sdk` is also very annoying having to build rust crypto packages.

We're now using direct `fetch` requests against the Matrix API and lightweight `client` object.

All 3 current tests pass 
This commit is contained in:
Eric Eastwood 2022-06-09 20:44:57 -05:00 committed by GitHub
parent 7dfe8cabc9
commit 9fc71a3412
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 467 additions and 1653 deletions

1524
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -31,8 +31,6 @@
"express": "^4.17.2", "express": "^4.17.2",
"hydrogen-view-sdk": "^0.0.4", "hydrogen-view-sdk": "^0.0.4",
"linkedom": "^0.14.1", "linkedom": "^0.14.1",
"matrix-bot-sdk": "^0.5.19",
"matrix-js-sdk": "^15.5.2",
"matrix-public-archive-shared": "file:./shared/", "matrix-public-archive-shared": "file:./shared/",
"nconf": "^0.11.3", "nconf": "^0.11.3",
"node-fetch": "^2.6.7", "node-fetch": "^2.6.7",

View File

@ -16,7 +16,7 @@ assert(matrixServerUrl);
// Consider this scenario: dayStart(fromTs) <---- msg1 <- msg2 <-- msg3 <---- dayEnd(toTs) // Consider this scenario: dayStart(fromTs) <---- msg1 <- msg2 <-- msg3 <---- dayEnd(toTs)
// - ❌ If we start from dayStart and look backwards, we will find nothing. // - ❌ If we start from dayStart and look backwards, we will find nothing.
// - ❌ If we start from dayStart and look forwards, we will find msg1, but federated backfill won't be able to paginate forwards // - ❌ If we start from dayStart and look forwards, we will find msg1, but federated backfill won't be able to paginate forwards
// - ✅ If we start from dayEnd and look backwards, we will msg3 // - ✅ If we start from dayEnd and look backwards, we will find msg3
// - ❌ If we start from dayEnd and look forwards, we will find nothing // - ❌ If we start from dayEnd and look forwards, we will find nothing
// //
// Returns events in reverse-chronological order. // Returns events in reverse-chronological order.

View File

@ -20,7 +20,7 @@ function configureNodeEnv() {
} }
const nodeEnv = configureNodeEnv(); const nodeEnv = configureNodeEnv();
console.log('nodeEnv', nodeEnv); console.log(`Config is using nodeEnv=${nodeEnv}`);
const configDir = path.join(__dirname, '../../config'); const configDir = path.join(__dirname, '../../config');
nconf.argv().env('__'); nconf.argv().env('__');

View File

@ -33,6 +33,7 @@ async function fetchEndpoint(endpoint, options = {}) {
const res = await fetch(endpoint, { const res = await fetch(endpoint, {
method, method,
headers, headers,
body: options.body,
}); });
await checkResponseStatus(res); await checkResponseStatus(res);
@ -49,11 +50,16 @@ async function fetchEndpointAsJson(endpoint, options) {
const opts = { const opts = {
...options, ...options,
headers: { headers: {
Accept: 'application/json',
'Content-Type': 'application/json', 'Content-Type': 'application/json',
...(options.headers || {}), ...(options.headers || {}),
}, },
}; };
if (options.body) {
opts.body = JSON.stringify(options.body);
}
const res = await fetchEndpoint(endpoint, opts); const res = await fetchEndpoint(endpoint, opts);
const data = await res.json(); const data = await res.json();
return data; return data;

View File

@ -174,7 +174,7 @@ async function mountHydrogen() {
const memberEvent = workingStateEventMap[event.user_id]; const memberEvent = workingStateEventMap[event.user_id];
return makeEventEntryFromEventJson(event, memberEvent); return makeEventEntryFromEventJson(event, memberEvent);
}); });
console.log('eventEntries', eventEntries.length); //console.log('eventEntries', eventEntries.length);
// Map of `event_id` to `EventEntry` // Map of `event_id` to `EventEntry`
const eventEntriesByEventId = eventEntries.reduce((currentMap, eventEntry) => { const eventEntriesByEventId = eventEntries.reduce((currentMap, eventEntry) => {

View File

@ -1,17 +1,17 @@
``` ```sh
$ docker pull matrixdotorg/synapse:latest $ docker pull matrixdotorg/synapse:latest
$ docker build -t matrix-public-archive-test-homeserver -f test/dockerfiles/Synapse.Dockerfile test/dockerfiles/ $ docker build -t matrix-public-archive-test-homeserver -f test/dockerfiles/Synapse.Dockerfile test/dockerfiles/
``` ```
``` ```sh
docker-compose -f test/docker-compose.yml up -d --no-recreate $ docker-compose --project-name matrix_public_archive_test -f test/docker-compose.yml up -d --no-recreate
``` ```
``` ```sh
$ docker ps --all | grep test_hs $ docker ps --all | grep test_hs
$ docker logs test_hs1_1 $ docker logs -f --tail 10 matrix_public_archive_test_hs1_1
$ docker logs test_hs2_1 $ docker logs -f --tail 10 matrix_public_archive_test_hs2_1
$ docker stop test_hs1_1 test_hs2_1 $ docker stop matrix_public_archive_test_hs1_1 matrix_public_archive_test_hs2_1
$ docker rm test_hs1_1 test_hs2_1 $ docker rm matrix_public_archive_test_hs1_1 matrix_public_archive_test_hs2_1
``` ```

211
test/client-utils.js Normal file
View File

@ -0,0 +1,211 @@
'use strict';
const assert = require('assert');
const { URLSearchParams } = require('url');
const urlJoin = require('url-join');
const { fetchEndpointAsJson, fetchEndpoint } = require('../server/lib/fetch-endpoint');
const config = require('../server/lib/config');
const matrixAccessToken = config.get('matrixAccessToken');
assert(matrixAccessToken);
let txnCount = 0;
function getTxnId() {
txnCount++;
return `${new Date().getTime()}--${txnCount}`;
}
// Get client to act with for all of the client methods. This will use the
// application service access token and client methods will append `?user_id`
// for the specific user to act upon so we can use the `?ts` message timestamp
// massaging when sending.
async function getTestClientForHs(testMatrixServerUrl) {
// Register the virtual user
const username = `user-t${new Date().getTime()}-r${Math.floor(Math.random() * 1000000000)}`;
const registerResponse = await fetchEndpointAsJson(
urlJoin(testMatrixServerUrl, '/_matrix/client/v3/register'),
{
method: 'POST',
body: {
type: 'm.login.application_service',
username,
},
accessToken: matrixAccessToken,
}
);
const userId = registerResponse['user_id'];
assert(userId);
return {
homeserverUrl: testMatrixServerUrl,
// We use the application service AS token because we need to be able to use
// the `?ts` timestamp massaging when sending events
accessToken: matrixAccessToken,
userId: userId,
};
}
// Create a public room to test in
async function createTestRoom(client) {
let qs = new URLSearchParams();
if (client.userId) {
qs.append('user_id', client.userId);
}
const createRoomResponse = await fetchEndpointAsJson(
urlJoin(client.homeserverUrl, `/_matrix/client/v3/createRoom?${qs.toString()}`),
{
method: 'POST',
body: {
preset: 'public_chat',
name: 'the hangout spot',
initial_state: [
{
type: 'm.room.history_visibility',
state_key: '',
content: {
history_visibility: 'world_readable',
},
},
],
},
accessToken: client.accessToken,
}
);
const roomId = createRoomResponse['room_id'];
assert(roomId);
return roomId;
}
async function joinRoom({ client, roomId, viaServers }) {
let qs = new URLSearchParams();
if (viaServers) {
[].concat(viaServers).forEach((viaServer) => {
qs.append('server_name', viaServer);
});
}
if (client.userId) {
qs.append('user_id', client.userId);
}
const joinRoomResponse = await fetchEndpointAsJson(
urlJoin(client.homeserverUrl, `/_matrix/client/v3/join/${roomId}?${qs.toString()}`),
{
method: 'POST',
accessToken: client.accessToken,
}
);
const joinedRoomId = joinRoomResponse['room_id'];
assert(joinedRoomId);
return joinedRoomId;
}
async function sendEvent({ client, roomId, eventType, content, timestamp }) {
assert(client);
assert(roomId);
assert(content);
let qs = new URLSearchParams();
if (timestamp) {
assert(
timestamp && client.userId,
'We can only do `?ts` massaging from an application service access token. ' +
'Expected `client.userId` to be defined so we can act on behalf of that user'
);
qs.append('ts', timestamp);
}
if (client.userId) {
qs.append('user_id', client.userId);
}
const sendResponse = await fetchEndpointAsJson(
urlJoin(
client.homeserverUrl,
`/_matrix/client/v3/rooms/${roomId}/send/${eventType}/${getTxnId()}?${qs.toString()}`
),
{
method: 'PUT',
body: content,
accessToken: client.accessToken,
}
);
const eventId = sendResponse['event_id'];
assert(eventId);
return eventId;
}
async function sendMessage({ client, roomId, content, timestamp }) {
return sendEvent({ client, roomId, eventType: 'm.room.message', content, timestamp });
}
// Create a number of messages in the given room
async function createMessagesInRoom({ client, roomId, numMessages, prefix, timestamp }) {
let eventIds = [];
for (let i = 0; i < numMessages; i++) {
const eventId = await sendMessage({
client,
roomId,
content: {
msgtype: 'm.text',
body: `${prefix} - message${i}`,
},
timestamp,
});
eventIds.push(eventId);
}
return eventIds;
}
// Uploads the given data Buffer and returns the MXC URI of the uploaded content
async function uploadContent({ client, roomId, data, fileName, contentType }) {
assert(client);
assert(roomId);
assert(data);
let qs = new URLSearchParams();
if (client.userId) {
qs.append('user_id', client.userId);
}
if (fileName) {
qs.append('filename', fileName);
}
// We don't want to use `fetchEndpointAsJson` here because it will
// `JSON.stringify(...)` the body data
const uploadResponse = await fetchEndpoint(
urlJoin(client.homeserverUrl, `/_matrix/media/v3/upload`),
{
method: 'POST',
body: data,
headers: {
'Content-Type': contentType || 'application/octet-stream',
},
accessToken: client.accessToken,
}
);
const uploadResponseData = await uploadResponse.json();
const mxcUri = uploadResponseData['content_uri'];
assert(mxcUri);
return mxcUri;
}
module.exports = {
getTestClientForHs,
createTestRoom,
joinRoom,
sendEvent,
sendMessage,
createMessagesInRoom,
uploadContent,
};

View File

@ -24,7 +24,7 @@ COPY keys/* /ca/
RUN openssl genrsa -out /conf/server.tls.key 2048 RUN openssl genrsa -out /conf/server.tls.key 2048
# generate a signing key # generate a signing key
RUN generate_signing_key.py -o /conf/server.signing.key RUN generate_signing_key -o /conf/server.signing.key
WORKDIR /data WORKDIR /data

View File

@ -6,6 +6,7 @@ report_stats: False
signing_key_path: /conf/server.signing.key signing_key_path: /conf/server.signing.key
trusted_key_servers: [] trusted_key_servers: []
enable_registration: true enable_registration: true
enable_registration_without_verification: true
## Listeners ## ## Listeners ##
@ -94,6 +95,13 @@ rc_joins:
federation_rr_transactions_per_room_per_second: 9999 federation_rr_transactions_per_room_per_second: 9999
## Media Store ##
# Whether to generate new thumbnails on the fly. This lets the image thumbnails
# load in the tests.
#
dynamic_thumbnails: true
## API Configuration ## ## API Configuration ##
# A list of application service config files to use # A list of application service config files to use

View File

@ -3,16 +3,26 @@
process.env.NODE_ENV = 'test'; process.env.NODE_ENV = 'test';
const assert = require('assert'); const assert = require('assert');
const path = require('path');
const urlJoin = require('url-join'); const urlJoin = require('url-join');
const escapeStringRegexp = require('escape-string-regexp'); const escapeStringRegexp = require('escape-string-regexp');
const { MatrixAuth } = require('matrix-bot-sdk');
const { parseHTML } = require('linkedom'); const { parseHTML } = require('linkedom');
const { readFile } = require('fs').promises;
const { fetchEndpointAsText, fetchEndpointAsJson } = require('../server/lib/fetch-endpoint');
const MatrixPublicArchiveURLCreator = require('matrix-public-archive-shared/lib/url-creator'); const MatrixPublicArchiveURLCreator = require('matrix-public-archive-shared/lib/url-creator');
const { fetchEndpointAsText, fetchEndpointAsJson } = require('../server/lib/fetch-endpoint');
const config = require('../server/lib/config'); const config = require('../server/lib/config');
const {
getTestClientForHs,
createTestRoom,
joinRoom,
sendEvent,
sendMessage,
createMessagesInRoom,
uploadContent,
} = require('./client-utils');
const testMatrixServerUrl1 = config.get('testMatrixServerUrl1'); const testMatrixServerUrl1 = config.get('testMatrixServerUrl1');
const testMatrixServerUrl2 = config.get('testMatrixServerUrl2'); const testMatrixServerUrl2 = config.get('testMatrixServerUrl2');
assert(testMatrixServerUrl1); assert(testMatrixServerUrl1);
@ -28,48 +38,6 @@ const HOMESERVER_URL_TO_PRETTY_NAME_MAP = {
[testMatrixServerUrl2]: 'hs2', [testMatrixServerUrl2]: 'hs2',
}; };
async function getTestClientForHs(testMatrixServerUrl) {
const auth = new MatrixAuth(testMatrixServerUrl);
const client = await auth.passwordRegister(
`user-t${new Date().getTime()}-r${Math.floor(Math.random() * 1000000000)}`,
'password'
);
return client;
}
async function createMessagesInRoom(client, roomId, numMessages, prefix) {
let eventIds = [];
for (let i = 0; i < numMessages; i++) {
const eventId = await client.sendMessage(roomId, {
msgtype: 'm.text',
body: `${prefix} - message${i}`,
});
eventIds.push(eventId);
}
return eventIds;
}
async function createTestRoom(client) {
const roomId = await client.createRoom({
preset: 'public_chat',
name: 'the hangout spot',
initial_state: [
{
type: 'm.room.history_visibility',
state_key: '',
content: {
history_visibility: 'world_readable',
},
},
],
});
return roomId;
}
describe('matrix-public-archive', () => { describe('matrix-public-archive', () => {
let server; let server;
before(() => { before(() => {
@ -83,24 +51,28 @@ describe('matrix-public-archive', () => {
} }
}); });
describe('Test fixture homeservers', () => {
// Sanity check that our test homeservers can actually federate with each // Sanity check that our test homeservers can actually federate with each
// other. The rest of the tests won't work properly if this isn't working. // other. The rest of the tests won't work properly if this isn't working.
it('Test federation between fixture homeservers', async () => { it('Test federation between fixture homeservers', async () => {
try {
const hs1Client = await getTestClientForHs(testMatrixServerUrl1); const hs1Client = await getTestClientForHs(testMatrixServerUrl1);
const hs2Client = await getTestClientForHs(testMatrixServerUrl2); const hs2Client = await getTestClientForHs(testMatrixServerUrl2);
// Create a room on hs2 // Create a room on hs2
const hs2RoomId = await createTestRoom(hs2Client); const hs2RoomId = await createTestRoom(hs2Client);
const room2EventIds = await createMessagesInRoom( const room2EventIds = await createMessagesInRoom({
hs2Client, client: hs2Client,
hs2RoomId, roomId: hs2RoomId,
10, numMessages: 10,
HOMESERVER_URL_TO_PRETTY_NAME_MAP[hs2Client.homeserverUrl] prefix: HOMESERVER_URL_TO_PRETTY_NAME_MAP[hs2Client.homeserverUrl],
); });
// Join hs1 to a room on hs2 (federation) // Join hs1 to a room on hs2 (federation)
await hs1Client.joinRoom(hs2RoomId, 'hs2'); await joinRoom({
client: hs1Client,
roomId: hs2RoomId,
viaServers: 'hs2',
});
// From, hs1, make sure we can fetch messages from hs2 // From, hs1, make sure we can fetch messages from hs2
const messagesEndpoint = urlJoin( const messagesEndpoint = urlJoin(
@ -129,31 +101,59 @@ describe('matrix-public-archive', () => {
}") to be in room on hs2=${JSON.stringify(room2EventIds)}` }") to be in room on hs2=${JSON.stringify(room2EventIds)}`
); );
}); });
} catch (err) { });
if (err.body) {
// FIXME: Remove this try/catch once the matrix-bot-sdk no longer throws
// huge response objects as errors, see
// https://github.com/turt2live/matrix-bot-sdk/pull/158
throw new Error(
`Error occured in matrix-bot-sdk (this new error is to stop it from logging the huge response) statusCode=${
err.statusCode
} body=${JSON.stringify(err.body)}`
);
}
throw err;
}
}); });
describe('Archive', () => {
// Use a fixed date at the start of the UTC day so that the tests are
// consistent. Otherwise, the tests could fail when they start close to
// midnight and it rolls over to the next day.
const archiveDate = new Date(Date.UTC(2022, 0, 3));
let archiveUrl;
let numMessagesSent = 0;
afterEach(() => {
if (interactive) {
console.log('Interactive URL for test', archiveUrl);
}
// Reset `numMessagesSent` between tests so each test starts from the
// beginning of the day and we don't run out of minutes in the day to send
// messages in (we space messages out by a minute so the timestamp visibly
// changes in the UI).
numMessagesSent = 0;
});
// Sends a message and makes sure that a timestamp was provided
async function sendMessageOnArchiveDate(options) {
const minute = 1000 * 60;
// Adjust the timestamp by a minute each time so there is some visual difference.
options.timestamp = archiveDate.getTime() + minute * numMessagesSent;
numMessagesSent++;
return sendMessage(options);
}
// Sends a message and makes sure that a timestamp was provided
async function sendEventOnArchiveDate(options) {
const minute = 1000 * 60;
// Adjust the timestamp by a minute each time so there is some visual difference.
options.timestamp = archiveDate.getTime() + minute * numMessagesSent;
numMessagesSent++;
return sendEvent(options);
}
it('shows all events in a given day', async () => { it('shows all events in a given day', async () => {
try {
const client = await getTestClientForHs(testMatrixServerUrl1); const client = await getTestClientForHs(testMatrixServerUrl1);
const roomId = await createTestRoom(client); const roomId = await createTestRoom(client);
const archiveUrl = matrixPublicArchiveURLCreator.archiveUrlForDate(roomId, new Date()); // Just render the page initially so that the archiver user is already
// Just render the page initially so that the archiver user is already joined to the page. // joined to the page. We don't want their join event masking the one-off
// We don't want their join event masking the one-off problem where we're missing the latest message in the room. // problem where we're missing the latest message in the room. We just use the date now
await fetchEndpointAsText(archiveUrl); // because it will find whatever events backwards no matter when they were sent.
await fetchEndpointAsText(
matrixPublicArchiveURLCreator.archiveUrlForDate(roomId, new Date())
);
const messageTextList = [ const messageTextList = [
`Amontons' First Law: The force of friction is directly proportional to the applied load.`, `Amontons' First Law: The force of friction is directly proportional to the applied load.`,
@ -164,9 +164,13 @@ describe('matrix-public-archive', () => {
const eventIds = []; const eventIds = [];
for (const messageText of messageTextList) { for (const messageText of messageTextList) {
const eventId = await client.sendMessage(roomId, { const eventId = await sendMessageOnArchiveDate({
client,
roomId,
content: {
msgtype: 'm.text', msgtype: 'm.text',
body: messageText, body: messageText,
},
}); });
eventIds.push(eventId); eventIds.push(eventId);
} }
@ -174,10 +178,7 @@ describe('matrix-public-archive', () => {
// Sanity check that we actually sent some messages // Sanity check that we actually sent some messages
assert.strictEqual(eventIds.length, 3); assert.strictEqual(eventIds.length, 3);
if (interactive) { archiveUrl = matrixPublicArchiveURLCreator.archiveUrlForDate(roomId, archiveDate);
console.log('Interactive URL for test', archiveUrl);
}
const archivePageHtml = await fetchEndpointAsText(archiveUrl); const archivePageHtml = await fetchEndpointAsText(archiveUrl);
const dom = parseHTML(archivePageHtml); const dom = parseHTML(archivePageHtml);
@ -191,25 +192,10 @@ describe('matrix-public-archive', () => {
new RegExp(`.*${escapeStringRegexp(eventText)}.*`) new RegExp(`.*${escapeStringRegexp(eventText)}.*`)
); );
} }
} catch (err) {
if (err.body) {
// FIXME: Remove this try/catch once the matrix-bot-sdk no longer throws
// huge response objects as errors, see
// https://github.com/turt2live/matrix-bot-sdk/pull/158
throw new Error(
`Error occured in matrix-bot-sdk (this new error is to stop it from logging the huge response) statusCode=${
err.statusCode
} body=${JSON.stringify(err.body)}`
);
}
throw err;
}
}); });
// eslint-disable-next-line max-statements // eslint-disable-next-line max-statements
it('can render diverse messages', async () => { it('can render diverse messages', async () => {
try {
const client = await getTestClientForHs(testMatrixServerUrl1); const client = await getTestClientForHs(testMatrixServerUrl1);
const roomId = await createTestRoom(client); const roomId = await createTestRoom(client);
@ -218,49 +204,64 @@ describe('matrix-public-archive', () => {
// TODO: Set avatar of room // TODO: Set avatar of room
// Test image // Test image
const mxcUri = await client.uploadContentFromUrl( // via https://en.wikipedia.org/wiki/Friction#/media/File:Friction_between_surfaces.jpg (CaoHao)
'https://en.wikipedia.org/wiki/Friction#/media/File:Friction_between_surfaces.jpg' const imageBuffer = await readFile(
path.resolve(__dirname, './fixtures/friction_between_surfaces.jpg')
); );
const imageEventId = await client.sendMessage(roomId, { const imageFileName = 'friction_between_surfaces.jpg';
body: 'Friction_between_surfaces.jpeg', const mxcUri = await uploadContent({
client,
roomId,
data: imageBuffer,
fileName: imageFileName,
});
const imageEventId = await sendMessageOnArchiveDate({
client,
roomId,
content: {
body: imageFileName,
info: { info: {
size: 396644, size: 17471,
mimetype: 'image/jpeg', mimetype: 'image/jpeg',
thumbnail_info: { w: 640,
w: 800, h: 312,
h: 390, 'xyz.amorgan.blurhash': 'LkR3G|IU?w%NbxbIemae_NxuD$M{',
mimetype: 'image/jpeg',
size: 126496,
},
w: 1894,
h: 925,
'xyz.amorgan.blurhash': 'LkR3G|IU?w%NbwbIemae_NxuD$M{',
// TODO: How to get a proper thumnail URL that will load?
thumbnail_url: mxcUri,
}, },
msgtype: 'm.image', msgtype: 'm.image',
url: mxcUri, url: mxcUri,
},
}); });
// A normal text message // A normal text message
const normalMessageText1 = const normalMessageText1 =
'^ Figure 1: Simulated blocks with fractal rough surfaces, exhibiting static frictional interactions'; '^ Figure 1: Simulated blocks with fractal rough surfaces, exhibiting static frictional interactions';
const normalMessageEventId1 = await client.sendMessage(roomId, { const normalMessageEventId1 = await sendMessageOnArchiveDate({
client,
roomId,
content: {
msgtype: 'm.text', msgtype: 'm.text',
body: normalMessageText1, body: normalMessageText1,
},
}); });
// Another normal text message // Another normal text message
const normalMessageText2 = const normalMessageText2 =
'The topography of the Moon has been measured with laser altimetry and stereo image analysis.'; 'The topography of the Moon has been measured with laser altimetry and stereo image analysis.';
const normalMessageEventId2 = await client.sendMessage(roomId, { const normalMessageEventId2 = await sendMessageOnArchiveDate({
client,
roomId,
content: {
msgtype: 'm.text', msgtype: 'm.text',
body: normalMessageText2, body: normalMessageText2,
},
}); });
// Test replies // Test replies
const replyMessageText = `The concentration of maria on the near side likely reflects the substantially thicker crust of the highlands of the Far Side, which may have formed in a slow-velocity impact of a second moon of Earth a few tens of millions of years after the Moon's formation.`; const replyMessageText = `The concentration of maria on the near side likely reflects the substantially thicker crust of the highlands of the Far Side, which may have formed in a slow-velocity impact of a second moon of Earth a few tens of millions of years after the Moon's formation.`;
const replyMessageEventId = await client.sendMessage(roomId, { const replyMessageEventId = await sendMessageOnArchiveDate({
client,
roomId,
content: {
'org.matrix.msc1767.message': [ 'org.matrix.msc1767.message': [
{ {
body: '> <@ericgittertester:my.synapse.server> ${normalMessageText2}', body: '> <@ericgittertester:my.synapse.server> ${normalMessageText2}',
@ -280,22 +281,25 @@ describe('matrix-public-archive', () => {
event_id: normalMessageEventId2, event_id: normalMessageEventId2,
}, },
}, },
},
}); });
// Test reactions // Test reactions
const reactionText = '😅'; const reactionText = '😅';
await client.sendEvent(roomId, 'm.reaction', { await sendEventOnArchiveDate({
client,
roomId,
eventType: 'm.reaction',
content: {
'm.relates_to': { 'm.relates_to': {
rel_type: 'm.annotation', rel_type: 'm.annotation',
event_id: replyMessageEventId, event_id: replyMessageEventId,
key: reactionText, key: reactionText,
}, },
},
}); });
const archiveUrl = matrixPublicArchiveURLCreator.archiveUrlForDate(roomId, new Date()); archiveUrl = matrixPublicArchiveURLCreator.archiveUrlForDate(roomId, archiveDate);
if (interactive) {
console.log('Interactive URL for test', archiveUrl);
}
const archivePageHtml = await fetchEndpointAsText(archiveUrl); const archivePageHtml = await fetchEndpointAsText(archiveUrl);
@ -305,7 +309,7 @@ describe('matrix-public-archive', () => {
const imageElement = dom.document.querySelector(`[data-event-id="${imageEventId}"] img`); const imageElement = dom.document.querySelector(`[data-event-id="${imageEventId}"] img`);
assert(imageElement); assert(imageElement);
assert.match(imageElement.getAttribute('src'), new RegExp(`^http://.*`)); assert.match(imageElement.getAttribute('src'), new RegExp(`^http://.*`));
assert.strictEqual(imageElement.getAttribute('alt'), 'Friction_between_surfaces.jpeg'); assert.strictEqual(imageElement.getAttribute('alt'), imageFileName);
// Make sure the normal message is visible // Make sure the normal message is visible
assert.match( assert.match(
@ -337,20 +341,6 @@ describe('matrix-public-archive', () => {
replyMessageElement.outerHTML, replyMessageElement.outerHTML,
new RegExp(`.*${escapeStringRegexp(reactionText)}.*`) new RegExp(`.*${escapeStringRegexp(reactionText)}.*`)
); );
} catch (err) {
if (err.body) {
// FIXME: Remove this try/catch once the matrix-bot-sdk no longer throws
// huge response objects as errors, see
// https://github.com/turt2live/matrix-bot-sdk/pull/158
throw new Error(
`Error occured in matrix-bot-sdk (this new error is to stop it from logging the huge response) statusCode=${
err.statusCode
} body=${JSON.stringify(err.body)}`
);
}
throw err;
}
}); });
it(`can render day back in time from room on remote homeserver we haven't backfilled from`); it(`can render day back in time from room on remote homeserver we haven't backfilled from`);
@ -363,3 +353,4 @@ describe('matrix-public-archive', () => {
`will render a room with a sparse amount of messages (a few per day) with no contamination between days` `will render a room with a sparse amount of messages (a few per day) with no contamination between days`
); );
}); });
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB