Add attachment support to mock tests
This commit is contained in:
parent
6940c532ea
commit
9010245083
|
@ -128,7 +128,7 @@
|
|||
"@indutny/parallel-prettier": "3.0.0",
|
||||
"@indutny/rezip-electron": "1.3.1",
|
||||
"@indutny/symbolicate-mac": "2.3.0",
|
||||
"@signalapp/mock-server": "6.6.0",
|
||||
"@signalapp/mock-server": "6.7.0",
|
||||
"@storybook/addon-a11y": "8.1.11",
|
||||
"@storybook/addon-actions": "8.1.11",
|
||||
"@storybook/addon-controls": "8.1.11",
|
||||
|
@ -7176,6 +7176,21 @@
|
|||
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@redis/client": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@redis/client/-/client-1.6.0.tgz",
|
||||
"integrity": "sha512-aR0uffYI700OEEH4gYnitAnv3vzVGXCFvYfdpu/CJKvk4pHfLPEy/JSZyrpQ+15WhXe1yJRXLtfQ84s4mEXnPg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"cluster-key-slot": "1.1.2",
|
||||
"generic-pool": "3.9.0",
|
||||
"yallist": "4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@sideway/address": {
|
||||
"version": "4.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
|
||||
|
@ -7239,12 +7254,14 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@signalapp/mock-server": {
|
||||
"version": "6.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@signalapp/mock-server/-/mock-server-6.6.0.tgz",
|
||||
"integrity": "sha512-zeLz9YikLaCQfWgSy2XDeEMdLWUTpyGOteSucD1BLcmv54J2eysk7ppDJns3H13opmF4Qj1Xmy5VftG3V3QKow==",
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@signalapp/mock-server/-/mock-server-6.7.0.tgz",
|
||||
"integrity": "sha512-ueF3RTp07Y3kxdIg3un3dyE87VdA3y+E37wNxG9HbAb8fk5WP4LYlRwa7VvJBRuI28IU8LbrrC0d7ItXGdN3sA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@signalapp/libsignal-client": "^0.45.0",
|
||||
"@tus/file-store": "^1.4.0",
|
||||
"@tus/server": "^1.7.0",
|
||||
"debug": "^4.3.2",
|
||||
"long": "^4.0.0",
|
||||
"micro": "^9.3.4",
|
||||
|
@ -10525,6 +10542,94 @@
|
|||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tus/file-store": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@tus/file-store/-/file-store-1.4.0.tgz",
|
||||
"integrity": "sha512-r+K4vGEvjlF9EEKZSgh1q9pLwbt87tcWUJDgjYyzYVMSPP98tifSOzFuPqQ2GwtQgIlVNLnyYm/PNqPd3RUNFw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@tus/utils": "^0.3.0",
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@redis/client": "^1.5.13"
|
||||
}
|
||||
},
|
||||
"node_modules/@tus/file-store/node_modules/debug": {
|
||||
"version": "4.3.6",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
|
||||
"integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@tus/file-store/node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@tus/server": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@tus/server/-/server-1.7.0.tgz",
|
||||
"integrity": "sha512-2RlQXkTw3+fMFUbIO4AIrgF8C/OI6WtSQ2R0iWEzpSUD9i8TqJNxa7gNAGFe4SQJUtGLTq7OxUWb6+Dndblr+Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@tus/utils": "^0.3.0",
|
||||
"debug": "^4.3.4",
|
||||
"lodash.throttle": "^4.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@redis/client": "^1.5.13"
|
||||
}
|
||||
},
|
||||
"node_modules/@tus/server/node_modules/debug": {
|
||||
"version": "4.3.6",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
|
||||
"integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@tus/server/node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@tus/utils": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@tus/utils/-/utils-0.3.0.tgz",
|
||||
"integrity": "sha512-Wt/phitrYEP6T9Tq0ikhJdGKpeEEkOT+vEVUKQKBXBUZdtWubLQKvR2V9jtzekFhLIoqm0KS5uOb7abZgebT3A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/aria-query": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.2.tgz",
|
||||
|
@ -15642,6 +15747,16 @@
|
|||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/cluster-key-slot": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
|
||||
"integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/co": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
|
||||
|
@ -21494,6 +21609,16 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/generic-pool": {
|
||||
"version": "3.9.0",
|
||||
"resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz",
|
||||
"integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/gensync": {
|
||||
"version": "1.0.0-beta.2",
|
||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
||||
|
|
|
@ -210,7 +210,7 @@
|
|||
"@indutny/parallel-prettier": "3.0.0",
|
||||
"@indutny/rezip-electron": "1.3.1",
|
||||
"@indutny/symbolicate-mac": "2.3.0",
|
||||
"@signalapp/mock-server": "6.6.0",
|
||||
"@signalapp/mock-server": "6.7.0",
|
||||
"@storybook/addon-a11y": "8.1.11",
|
||||
"@storybook/addon-actions": "8.1.11",
|
||||
"@storybook/addon-controls": "8.1.11",
|
||||
|
|
|
@ -49,6 +49,7 @@ export const CompositionUpload = forwardRef<HTMLInputElement, PropsType>(
|
|||
|
||||
return (
|
||||
<input
|
||||
data-testid="attachfile-input"
|
||||
hidden
|
||||
multiple
|
||||
onChange={onFileInputChange}
|
||||
|
|
|
@ -158,14 +158,17 @@ export class Bootstrap {
|
|||
private privDesktop?: Device;
|
||||
private storagePath?: string;
|
||||
private backupPath?: string;
|
||||
private cdn3Path: string;
|
||||
private timestamp: number = Date.now() - durations.WEEK;
|
||||
private lastApp?: App;
|
||||
private readonly randomId = crypto.randomBytes(8).toString('hex');
|
||||
|
||||
constructor(options: BootstrapOptions = {}) {
|
||||
this.cdn3Path = path.join(os.tmpdir(), 'mock-signal-cdn3-');
|
||||
this.server = new Server({
|
||||
// Limit number of storage read keys for easier testing
|
||||
maxStorageReadKeys: MAX_STORAGE_READ_KEYS,
|
||||
cdn3Path: this.cdn3Path,
|
||||
});
|
||||
|
||||
this.options = {
|
||||
|
@ -286,12 +289,9 @@ export class Bootstrap {
|
|||
|
||||
await Promise.race([
|
||||
Promise.all([
|
||||
this.storagePath
|
||||
? fs.rm(this.storagePath, { recursive: true })
|
||||
: Promise.resolve(),
|
||||
this.backupPath
|
||||
? fs.rm(this.backupPath, { recursive: true })
|
||||
: Promise.resolve(),
|
||||
...[this.storagePath, this.backupPath, this.cdn3Path].map(tmpPath =>
|
||||
tmpPath ? fs.rm(tmpPath, { recursive: true }) : Promise.resolve()
|
||||
),
|
||||
this.server.close(),
|
||||
this.lastApp?.close(),
|
||||
]),
|
||||
|
@ -649,6 +649,7 @@ export class Bootstrap {
|
|||
cdn: {
|
||||
'0': url,
|
||||
'2': url,
|
||||
'3': `${url}/cdn3`,
|
||||
},
|
||||
updatesEnabled: false,
|
||||
|
||||
|
|
|
@ -139,12 +139,14 @@ export function sendTextMessage({
|
|||
from,
|
||||
to,
|
||||
text,
|
||||
attachments,
|
||||
desktop,
|
||||
timestamp = Date.now(),
|
||||
}: {
|
||||
from: PrimaryDevice;
|
||||
to: PrimaryDevice | Device | GroupInfo;
|
||||
text: string;
|
||||
attachments?: Array<Proto.IAttachmentPointer>;
|
||||
desktop: Device;
|
||||
timestamp?: number;
|
||||
}): Promise<void> {
|
||||
|
@ -158,6 +160,7 @@ export function sendTextMessage({
|
|||
to: to as PrimaryDevice,
|
||||
dataMessage: {
|
||||
body: text,
|
||||
attachments,
|
||||
timestamp: Long.fromNumber(timestamp),
|
||||
groupV2: groupInfo
|
||||
? {
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
// Copyright 2024 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import createDebug from 'debug';
|
||||
import { expect } from 'playwright/test';
|
||||
import { type PrimaryDevice, StorageState } from '@signalapp/mock-server';
|
||||
import * as path from 'path';
|
||||
import type { App } from '../playwright';
|
||||
import { Bootstrap } from '../bootstrap';
|
||||
import {
|
||||
getMessageInTimelineByTimestamp,
|
||||
getTimeline,
|
||||
sendTextMessage,
|
||||
typeIntoInput,
|
||||
} from '../helpers';
|
||||
import * as durations from '../../util/durations';
|
||||
import { strictAssert } from '../../util/assert';
|
||||
|
||||
export const debug = createDebug('mock:test:attachments');
|
||||
|
||||
describe('attachments', function (this: Mocha.Suite) {
|
||||
this.timeout(durations.MINUTE);
|
||||
|
||||
let bootstrap: Bootstrap;
|
||||
let app: App;
|
||||
let pinned: PrimaryDevice;
|
||||
|
||||
beforeEach(async () => {
|
||||
bootstrap = new Bootstrap();
|
||||
await bootstrap.init();
|
||||
|
||||
let state = StorageState.getEmpty();
|
||||
|
||||
const { phone, contacts } = bootstrap;
|
||||
[pinned] = contacts;
|
||||
|
||||
state = state.addContact(pinned, {
|
||||
identityKey: pinned.publicKey.serialize(),
|
||||
profileKey: pinned.profileKey.serialize(),
|
||||
whitelisted: true,
|
||||
});
|
||||
|
||||
state = state.pin(pinned);
|
||||
await phone.setStorageState(state);
|
||||
|
||||
app = await bootstrap.link();
|
||||
});
|
||||
|
||||
afterEach(async function (this: Mocha.Context) {
|
||||
if (!bootstrap) {
|
||||
return;
|
||||
}
|
||||
|
||||
await bootstrap.maybeSaveLogs(this.currentTest, app);
|
||||
await app.close();
|
||||
await bootstrap.teardown();
|
||||
});
|
||||
|
||||
it('can upload attachment to CDN3 and download incoming attachment', async () => {
|
||||
const page = await app.getWindow();
|
||||
|
||||
await page.getByTestId(pinned.device.aci).click();
|
||||
await page
|
||||
.getByTestId('attachfile-input')
|
||||
.setInputFiles(
|
||||
path.join(__dirname, '..', '..', '..', 'fixtures', 'cat-screenshot.png')
|
||||
);
|
||||
const input = await app.waitForEnabledComposer();
|
||||
await typeIntoInput(input, 'This is my cat');
|
||||
await input.press('Enter');
|
||||
|
||||
const allMessagesLocator = getTimeline(page).getByRole('article');
|
||||
await expect(allMessagesLocator).toHaveCount(1);
|
||||
|
||||
const allMessages = await allMessagesLocator.all();
|
||||
const message = allMessages[0];
|
||||
|
||||
await message.getByText('This is my cat').waitFor();
|
||||
await message
|
||||
.locator('.module-message__metadata__status-icon--sent')
|
||||
.waitFor();
|
||||
|
||||
const timestamp = await message
|
||||
.locator('.module-message.module-message--outgoing')
|
||||
.getAttribute('data-testid');
|
||||
|
||||
strictAssert(timestamp, 'timestamp must exist');
|
||||
|
||||
// For this test, just send back the same attachment that was uploaded to test a
|
||||
// round-trip
|
||||
const receivedMessage = await pinned.waitForMessage();
|
||||
const attachment = receivedMessage.dataMessage.attachments?.[0];
|
||||
strictAssert(attachment, 'attachment must exist');
|
||||
|
||||
const incomingTimestamp = Date.now();
|
||||
await sendTextMessage({
|
||||
from: pinned,
|
||||
to: bootstrap.desktop,
|
||||
desktop: bootstrap.desktop,
|
||||
text: 'Wait, that is MY cat!',
|
||||
attachments: [attachment],
|
||||
timestamp: incomingTimestamp,
|
||||
});
|
||||
|
||||
await expect(
|
||||
getMessageInTimelineByTimestamp(page, incomingTimestamp).locator(
|
||||
'img.module-image__image'
|
||||
)
|
||||
).toBeVisible();
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue