Test rate-limiting, stories in mock server
This commit is contained in:
parent
450051e541
commit
f9453c64dd
9 changed files with 212 additions and 10 deletions
154
ts/test-mock/rate-limit/story_test.ts
Normal file
154
ts/test-mock/rate-limit/story_test.ts
Normal file
|
@ -0,0 +1,154 @@
|
|||
// Copyright 2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { assert } from 'chai';
|
||||
import createDebug from 'debug';
|
||||
import { Proto, StorageState } from '@signalapp/mock-server';
|
||||
|
||||
import * as durations from '../../util/durations';
|
||||
import { uuidToBytes } from '../../util/uuidToBytes';
|
||||
import { MY_STORIES_ID } from '../../types/Stories';
|
||||
import { Bootstrap } from '../bootstrap';
|
||||
import type { App } from '../bootstrap';
|
||||
|
||||
export const debug = createDebug('mock:test:rate-limit');
|
||||
|
||||
const IdentifierType = Proto.ManifestRecord.Identifier.Type;
|
||||
|
||||
describe('rate-limit/story', function needsName() {
|
||||
this.timeout(durations.MINUTE);
|
||||
|
||||
let bootstrap: Bootstrap;
|
||||
let app: App;
|
||||
|
||||
beforeEach(async () => {
|
||||
bootstrap = new Bootstrap({
|
||||
contactCount: 0,
|
||||
contactsWithoutProfileKey: 40,
|
||||
});
|
||||
await bootstrap.init();
|
||||
|
||||
const { phone } = bootstrap;
|
||||
|
||||
let state = StorageState.getEmpty();
|
||||
|
||||
state = state.updateAccount({
|
||||
profileKey: phone.profileKey.serialize(),
|
||||
e164: phone.device.number,
|
||||
givenName: phone.profileName,
|
||||
hasSetMyStoriesPrivacy: true,
|
||||
});
|
||||
|
||||
state = state.addRecord({
|
||||
type: IdentifierType.STORY_DISTRIBUTION_LIST,
|
||||
record: {
|
||||
storyDistributionList: {
|
||||
allowsReplies: true,
|
||||
identifier: uuidToBytes(MY_STORIES_ID),
|
||||
isBlockList: true,
|
||||
name: MY_STORIES_ID,
|
||||
recipientUuids: [],
|
||||
},
|
||||
},
|
||||
});
|
||||
phone.setStorageState(state);
|
||||
|
||||
app = await bootstrap.link();
|
||||
});
|
||||
|
||||
afterEach(async function after() {
|
||||
if (this.currentTest?.state !== 'passed') {
|
||||
await bootstrap.saveLogs(app);
|
||||
}
|
||||
|
||||
await app.close();
|
||||
await bootstrap.teardown();
|
||||
});
|
||||
|
||||
it('should request challenge and accept solution', async () => {
|
||||
const {
|
||||
server,
|
||||
contactsWithoutProfileKey: contacts,
|
||||
phone,
|
||||
desktop,
|
||||
} = bootstrap;
|
||||
|
||||
for (const contact of contacts) {
|
||||
server.rateLimit({ source: desktop.uuid, target: contact.device.uuid });
|
||||
}
|
||||
|
||||
const window = await app.getWindow();
|
||||
|
||||
debug('Posting a new story');
|
||||
{
|
||||
const storiesPane = window.locator('.Stories');
|
||||
|
||||
await window.locator('button.module-main-header__stories-icon').click();
|
||||
|
||||
await storiesPane
|
||||
.locator('button.Stories__pane__add-story__button')
|
||||
.click();
|
||||
await storiesPane
|
||||
.locator(
|
||||
'.ContextMenu__popper .Stories__pane__add-story__option--title ' +
|
||||
'>> "Text story"'
|
||||
)
|
||||
.click();
|
||||
|
||||
debug('Focusing textarea');
|
||||
await storiesPane.locator('.TextAttachment__story').click();
|
||||
|
||||
debug('Entering text');
|
||||
await storiesPane.locator('.TextAttachment__text__textarea').type('123');
|
||||
|
||||
debug('Clicking "Next"');
|
||||
await storiesPane
|
||||
.locator('.StoryCreator__toolbar button >> "Next"')
|
||||
.click();
|
||||
|
||||
debug('Selecting "My Stories"');
|
||||
await window
|
||||
.locator('.SendStoryModal__distribution-list__name >> "My Stories"')
|
||||
.click();
|
||||
|
||||
debug('Hitting Send');
|
||||
await window.locator('button.SendStoryModal__send').click();
|
||||
}
|
||||
|
||||
debug('Waiting for challenge');
|
||||
const request = await app.waitForChallenge();
|
||||
|
||||
debug('Checking for presence of captcha modal');
|
||||
await window
|
||||
.locator('.module-Modal__title >> "Verify to continue messaging"')
|
||||
.waitFor();
|
||||
|
||||
debug('Removing rate-limiting');
|
||||
for (const contact of contacts) {
|
||||
const failedMessages = server.stopRateLimiting({
|
||||
source: desktop.uuid,
|
||||
target: contact.device.uuid,
|
||||
});
|
||||
assert.isAtMost(failedMessages ?? 0, 1);
|
||||
}
|
||||
|
||||
debug('Solving challenge');
|
||||
app.solveChallenge({
|
||||
seq: request.seq,
|
||||
data: { captcha: 'anything' },
|
||||
});
|
||||
|
||||
debug('Verifying that all contacts received story');
|
||||
await Promise.all(
|
||||
contacts.map(async contact => {
|
||||
const { storyMessage } = await contact.waitForStory();
|
||||
assert.isTrue(
|
||||
phone.profileKey
|
||||
.serialize()
|
||||
.equals(storyMessage.profileKey ?? new Uint8Array(0))
|
||||
);
|
||||
assert.strictEqual(storyMessage.textAttachment?.text, '123');
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue