summaryrefslogtreecommitdiff
path: root/packages/backend/test
diff options
context:
space:
mode:
authorKagami Sascha Rosylight <saschanaz@outlook.com>2024-01-07 02:35:58 +0100
committerGitHub <noreply@github.com>2024-01-07 10:35:58 +0900
commit2a9db983fcd79e1993d5ea5b03e4979c1a578d7d (patch)
tree8b079c5ce14301087bc08b0f3fdea31a46c53f6b /packages/backend/test
parentFix: リストライムラインの「リノートを表示」が正しく機... (diff)
downloadsharkey-2a9db983fcd79e1993d5ea5b03e4979c1a578d7d.tar.gz
sharkey-2a9db983fcd79e1993d5ea5b03e4979c1a578d7d.tar.bz2
sharkey-2a9db983fcd79e1993d5ea5b03e4979c1a578d7d.zip
feat: export clips (#12931)
* feat: export clips * Update CHANGELOG.md
Diffstat (limited to 'packages/backend/test')
-rw-r--r--packages/backend/test/e2e/exports.ts194
-rw-r--r--packages/backend/test/utils.ts2
2 files changed, 195 insertions, 1 deletions
diff --git a/packages/backend/test/e2e/exports.ts b/packages/backend/test/e2e/exports.ts
new file mode 100644
index 0000000000..9686f2b7fd
--- /dev/null
+++ b/packages/backend/test/e2e/exports.ts
@@ -0,0 +1,194 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and other misskey contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+process.env.NODE_ENV = 'test';
+
+import * as assert from 'assert';
+import { signup, api, startServer, startJobQueue, port, post } from '../utils.js';
+import type { INestApplicationContext } from '@nestjs/common';
+import type * as misskey from 'misskey-js';
+
+describe('export-clips', () => {
+ let app: INestApplicationContext;
+ let alice: misskey.entities.SignupResponse;
+ let bob: misskey.entities.SignupResponse;
+
+ // XXX: Any better way to get the result?
+ async function pollFirstDriveFile() {
+ while (true) {
+ const files = (await api('/drive/files', {}, alice)).body;
+ if (!files.length) {
+ await new Promise(r => setTimeout(r, 100));
+ continue;
+ }
+ if (files.length > 1) {
+ throw new Error('Too many files?');
+ }
+ const file = (await api('/drive/files/show', { fileId: files[0].id }, alice)).body;
+ const res = await fetch(new URL(new URL(file.url).pathname, `http://127.0.0.1:${port}`));
+ return await res.json();
+ }
+ }
+
+ beforeAll(async () => {
+ app = await startServer();
+ await startJobQueue();
+ alice = await signup({ username: 'alice' });
+ bob = await signup({ username: 'bob' });
+ }, 1000 * 60 * 2);
+
+ afterAll(async () => {
+ await app.close();
+ });
+
+ beforeEach(async () => {
+ // Clean all clips and files of alice
+ const clips = (await api('/clips/list', {}, alice)).body;
+ for (const clip of clips) {
+ const res = await api('/clips/delete', { clipId: clip.id }, alice);
+ if (res.status !== 204) {
+ throw new Error('Failed to delete clip');
+ }
+ }
+ const files = (await api('/drive/files', {}, alice)).body;
+ for (const file of files) {
+ const res = await api('/drive/files/delete', { fileId: file.id }, alice);
+ if (res.status !== 204) {
+ throw new Error('Failed to delete file');
+ }
+ }
+ });
+
+ test('basic export', async () => {
+ let res = await api('/clips/create', {
+ name: 'foo',
+ description: 'bar',
+ }, alice);
+ assert.strictEqual(res.status, 200);
+
+ res = await api('/i/export-clips', {}, alice);
+ assert.strictEqual(res.status, 204);
+
+ const exported = await pollFirstDriveFile();
+ assert.strictEqual(exported[0].name, 'foo');
+ assert.strictEqual(exported[0].description, 'bar');
+ assert.strictEqual(exported[0].clipNotes.length, 0);
+ });
+
+ test('export with notes', async () => {
+ let res = await api('/clips/create', {
+ name: 'foo',
+ description: 'bar',
+ }, alice);
+ assert.strictEqual(res.status, 200);
+ const clip = res.body;
+
+ const note1 = await post(alice, {
+ text: 'baz1',
+ });
+
+ const note2 = await post(alice, {
+ text: 'baz2',
+ poll: {
+ choices: ['sakura', 'izumi', 'ako'],
+ },
+ });
+
+ for (const note of [note1, note2]) {
+ res = await api('/clips/add-note', {
+ clipId: clip.id,
+ noteId: note.id,
+ }, alice);
+ assert.strictEqual(res.status, 204);
+ }
+
+ res = await api('/i/export-clips', {}, alice);
+ assert.strictEqual(res.status, 204);
+
+ const exported = await pollFirstDriveFile();
+ assert.strictEqual(exported[0].name, 'foo');
+ assert.strictEqual(exported[0].description, 'bar');
+ assert.strictEqual(exported[0].clipNotes.length, 2);
+ assert.strictEqual(exported[0].clipNotes[0].note.text, 'baz1');
+ assert.strictEqual(exported[0].clipNotes[1].note.text, 'baz2');
+ assert.deepStrictEqual(exported[0].clipNotes[1].note.poll.choices[0], 'sakura');
+ });
+
+ test('multiple clips', async () => {
+ let res = await api('/clips/create', {
+ name: 'kawaii',
+ description: 'kawaii',
+ }, alice);
+ assert.strictEqual(res.status, 200);
+ const clip1 = res.body;
+
+ res = await api('/clips/create', {
+ name: 'yuri',
+ description: 'yuri',
+ }, alice);
+ assert.strictEqual(res.status, 200);
+ const clip2 = res.body;
+
+ const note1 = await post(alice, {
+ text: 'baz1',
+ });
+
+ const note2 = await post(alice, {
+ text: 'baz2',
+ });
+
+ res = await api('/clips/add-note', {
+ clipId: clip1.id,
+ noteId: note1.id,
+ }, alice);
+ assert.strictEqual(res.status, 204);
+
+ res = await api('/clips/add-note', {
+ clipId: clip2.id,
+ noteId: note2.id,
+ }, alice);
+ assert.strictEqual(res.status, 204);
+
+ res = await api('/i/export-clips', {}, alice);
+ assert.strictEqual(res.status, 204);
+
+ const exported = await pollFirstDriveFile();
+ assert.strictEqual(exported[0].name, 'kawaii');
+ assert.strictEqual(exported[0].clipNotes.length, 1);
+ assert.strictEqual(exported[0].clipNotes[0].note.text, 'baz1');
+ assert.strictEqual(exported[1].name, 'yuri');
+ assert.strictEqual(exported[1].clipNotes.length, 1);
+ assert.strictEqual(exported[1].clipNotes[0].note.text, 'baz2');
+ });
+
+ test('Clipping other user\'s note', async () => {
+ let res = await api('/clips/create', {
+ name: 'kawaii',
+ description: 'kawaii',
+ }, alice);
+ assert.strictEqual(res.status, 200);
+ const clip = res.body;
+
+ const note = await post(bob, {
+ text: 'baz',
+ visibility: 'followers',
+ });
+
+ res = await api('/clips/add-note', {
+ clipId: clip.id,
+ noteId: note.id,
+ }, alice);
+ assert.strictEqual(res.status, 204);
+
+ res = await api('/i/export-clips', {}, alice);
+ assert.strictEqual(res.status, 204);
+
+ const exported = await pollFirstDriveFile();
+ assert.strictEqual(exported[0].name, 'kawaii');
+ assert.strictEqual(exported[0].clipNotes.length, 1);
+ assert.strictEqual(exported[0].clipNotes[0].note.text, 'baz');
+ assert.strictEqual(exported[0].clipNotes[0].note.user.username, 'bob');
+ });
+});
diff --git a/packages/backend/test/utils.ts b/packages/backend/test/utils.ts
index 46b8ea9cdd..7c9428d476 100644
--- a/packages/backend/test/utils.ts
+++ b/packages/backend/test/utils.ts
@@ -17,7 +17,7 @@ import { entities } from '../src/postgres.js';
import { loadConfig } from '../src/config.js';
import type * as misskey from 'misskey-js';
-export { server as startServer } from '@/boot/common.js';
+export { server as startServer, jobQueue as startJobQueue } from '@/boot/common.js';
interface UserToken {
token: string;