Skip to content
Snippets Groups Projects
  • rinsuki's avatar
    Add GitHub Actions (#5522) · 3ecb0ab1
    rinsuki authored
    
    * add .github/workflows/nodejs.yml
    
    * fix
    
    * GitHub Actions: Node.js 8.xはサポートしない
    
    * add .github/workflows/docker.yml
    
    * Dockerビルドをキャッシュするように
    
    * Run test in github actions
    
    * 同リポジトリ内からのプルリクだと無駄に二回走るのを抑制
    
    * 6925c00のdocker.ymlへの適応忘れ
    
    * fix .circleci/misskey/test.yml
    
    * test実行時にDBとかredisとか動かすように
    
    * fix
    
    * fix tests (#5544)
    
    * fix test
    
    * fix compile errors
    
    * PATH引き継ぎでchild_process.spawn時のENOENTを修正
    
    *  サーバー起動処理を共通化
    
    * fix coding style
    
    * fd=4をipcに使うように
    
    * fix port
    
    * fix
    
    * fix ws port
    
    * #4033 にテストケースを追従
    
    * fix?
    
    * fix??
    
    * fix
    
    * fix
    
    * fix
    
    * maybe fix
    
    * fix
    
    * node 10.xサポートしてなかった
    
    * 11.10じゃないとだめだった
    
    * fix
    
    * remove chart test
    
    * fix
    
    * chart test復活
    
    * fix
    
    * 一回一回コネクションを閉じる
    
    * Revert "一回一回コネクションを閉じる"
    
    This reverts commit 56e35cf4f83070744c8dd852f1a7075011d88828.
    
    * 一回一回sync→dropしてるのをやめてみる
    
    * fix
    
    * fix
    
    * …
    
    * キャッシュを切ってみる
    
    * add ts to require target
    
    * omg fix
    
    * Revert "キャッシュを切ってみる"
    
    This reverts commit 88161c59d2ea769ddf87143ba4fd4660a06afdf2.
    
    * done呼び忘れ
    
    * 実際の文字数リミットと違ってたので対応
    
    * テストケースがバグってたので修正
    
    * Revert "一回一回sync→dropしてるのをやめてみる"
    
    This reverts commit a9e543ba2eef790ac7a14ae8799b898765748e35.
    
    * fix
    
    * fix
    
    * fix
    
    * fix?
    
    * fix
    
    * chartのconnectionを分離する
    
    * fix
    
    * fix
    
    * fix tsconfig?
    
    * Revert "fix tsconfig?"
    
    This reverts commit ba9269eaf65507ff97ec1dd2e27260fb2cf0510b.
    
    * fix
    
    * TS_NODE_FILES を scripts の方で指定
    
    * Windowsェ
    
    * Circle CIの実行条件をmasterへのpushのみに
    
    Co-authored-by: default avatarsyuilo <Syuilotan@yahoo.co.jp>
    3ecb0ab1
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
note.ts 9.41 KiB
/*
 * Tests of Note
 *
 * How to run the tests:
 * > npx mocha test/note.ts --require ts-node/register
 *
 * To specify test:
 * > npx mocha test/note.ts --require ts-node/register -g 'test name'
 *
 * If the tests not start, try set following enviroment variables:
 * TS_NODE_FILES=true and TS_NODE_TRANSPILE_ONLY=true
 * for more details, please see: https://github.com/TypeStrong/ts-node/issues/754
 */

process.env.NODE_ENV = 'test';

import * as assert from 'assert';
import * as childProcess from 'child_process';
import { async, signup, request, post, uploadFile, launchServer } from './utils';
import { Note } from '../src/models/entities/note';
import { initDb } from '../src/db/postgre';

describe('Note', () => {
	let p: childProcess.ChildProcess;
	let Notes: any;

	let alice: any;
	let bob: any;

	before(launchServer(g => p = g, async () => {
		const connection = await initDb(true);
		Notes = connection.getRepository(Note);
		alice = await signup({ username: 'alice' });
		bob = await signup({ username: 'bob' });
	}));

	after(() => {
		p.kill();
	});

	it('投稿できる', async(async () => {
		const post = {
			text: 'test'
		};

		const res = await request('/notes/create', post, alice);

		assert.strictEqual(res.status, 200);
		assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
		assert.strictEqual(res.body.createdNote.text, post.text);
	}));

	it('ファイルを添付できる', async(async () => {
		const file = await uploadFile(alice);

		const res = await request('/notes/create', {
			fileIds: [file.id]
		}, alice);

		assert.strictEqual(res.status, 200);
		assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
		assert.deepStrictEqual(res.body.createdNote.fileIds, [file.id]);
	}));

	it('他人のファイルは無視', async(async () => {
		const file = await uploadFile(bob);

		const res = await request('/notes/create', {
			text: 'test',
			fileIds: [file.id]
		}, alice);

		assert.strictEqual(res.status, 200);
		assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
		assert.deepStrictEqual(res.body.createdNote.fileIds, []);
	}));

	it('存在しないファイルは無視', async(async () => {
		const res = await request('/notes/create', {
			text: 'test',
			fileIds: ['000000000000000000000000']
		}, alice);

		assert.strictEqual(res.status, 200);
		assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
		assert.deepStrictEqual(res.body.createdNote.fileIds, []);
	}));

	it('不正なファイルIDで怒られる', async(async () => {
		const res = await request('/notes/create', {
			fileIds: ['kyoppie']
		}, alice);
		assert.strictEqual(res.status, 400);
	}));

	it('返信できる', async(async () => {
		const bobPost = await post(bob, {
			text: 'foo'
		});

		const alicePost = {
			text: 'bar',
			replyId: bobPost.id
		};

		const res = await request('/notes/create', alicePost, alice);

		assert.strictEqual(res.status, 200);
		assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
		assert.strictEqual(res.body.createdNote.text, alicePost.text);
		assert.strictEqual(res.body.createdNote.replyId, alicePost.replyId);
		assert.strictEqual(res.body.createdNote.reply.text, bobPost.text);
	}));

	it('renoteできる', async(async () => {
		const bobPost = await post(bob, {
			text: 'test'
		});

		const alicePost = {
			renoteId: bobPost.id
		};

		const res = await request('/notes/create', alicePost, alice);

		assert.strictEqual(res.status, 200);
		assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
		assert.strictEqual(res.body.createdNote.renoteId, alicePost.renoteId);
		assert.strictEqual(res.body.createdNote.renote.text, bobPost.text);
	}));

	it('引用renoteできる', async(async () => {
		const bobPost = await post(bob, {
			text: 'test'
		});

		const alicePost = {
			text: 'test',
			renoteId: bobPost.id
		};

		const res = await request('/notes/create', alicePost, alice);

		assert.strictEqual(res.status, 200);
		assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
		assert.strictEqual(res.body.createdNote.text, alicePost.text);
		assert.strictEqual(res.body.createdNote.renoteId, alicePost.renoteId);
		assert.strictEqual(res.body.createdNote.renote.text, bobPost.text);
	}));

	it('文字数ぎりぎりで怒られない', async(async () => {
		const post = {
			text: '!'.repeat(500)
		};
		const res = await request('/notes/create', post, alice);
		assert.strictEqual(res.status, 200);
	}));

	it('文字数オーバーで怒られる', async(async () => {
		const post = {
			text: '!'.repeat(501)
		};
		const res = await request('/notes/create', post, alice);
		assert.strictEqual(res.status, 400);
	}));

	it('存在しないリプライ先で怒られる', async(async () => {
		const post = {
			text: 'test',
			replyId: '000000000000000000000000'
		};
		const res = await request('/notes/create', post, alice);
		assert.strictEqual(res.status, 400);
	}));

	it('存在しないrenote対象で怒られる', async(async () => {
		const post = {
			renoteId: '000000000000000000000000'
		};
		const res = await request('/notes/create', post, alice);
		assert.strictEqual(res.status, 400);
	}));

	it('不正なリプライ先IDで怒られる', async(async () => {
		const post = {
			text: 'test',
			replyId: 'foo'
		};
		const res = await request('/notes/create', post, alice);
		assert.strictEqual(res.status, 400);
	}));

	it('不正なrenote対象IDで怒られる', async(async () => {
		const post = {
			renoteId: 'foo'
		};
		const res = await request('/notes/create', post, alice);
		assert.strictEqual(res.status, 400);
	}));

	it('存在しないユーザーにメンションできる', async(async () => {
		const post = {
			text: '@ghost yo'
		};

		const res = await request('/notes/create', post, alice);

		assert.strictEqual(res.status, 200);
		assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
		assert.strictEqual(res.body.createdNote.text, post.text);
	}));

	it('同じユーザーに複数メンションしても内部的にまとめられる', async(async () => {
		const post = {
			text: '@bob @bob @bob yo'
		};

		const res = await request('/notes/create', post, alice);

		assert.strictEqual(res.status, 200);
		assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
		assert.strictEqual(res.body.createdNote.text, post.text);

		const noteDoc = await Notes.findOne(res.body.createdNote.id);
		assert.deepStrictEqual(noteDoc.mentions, [bob.id]);
	}));

	describe('notes/create', () => {
		it('投票を添付できる', async(async () => {
			const res = await request('/notes/create', {
				text: 'test',
				poll: {
					choices: ['foo', 'bar']
				}
			}, alice);

			assert.strictEqual(res.status, 200);
			assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
			assert.strictEqual(res.body.createdNote.poll != null, true);
		}));

		it('投票の選択肢が無くて怒られる', async(async () => {
			const res = await request('/notes/create', {
				poll: {}
			}, alice);
			assert.strictEqual(res.status, 400);
		}));

		it('投票の選択肢が無くて怒られる (空の配列)', async(async () => {
			const res = await request('/notes/create', {
				poll: {
					choices: []
				}
			}, alice);
			assert.strictEqual(res.status, 400);
		}));

		it('投票の選択肢が1つで怒られる', async(async () => {
			const res = await request('/notes/create', {
				poll: {
					choices: ['Strawberry Pasta']
				}
			}, alice);
			assert.strictEqual(res.status, 400);
		}));

		it('投票できる', async(async () => {
			const { body } = await request('/notes/create', {
				text: 'test',
				poll: {
					choices: ['sakura', 'izumi', 'ako']
				}
			}, alice);

			const res = await request('/notes/polls/vote', {
				noteId: body.createdNote.id,
				choice: 1
			}, alice);

			assert.strictEqual(res.status, 204);
		}));

		it('複数投票できない', async(async () => {
			const { body } = await request('/notes/create', {
				text: 'test',
				poll: {
					choices: ['sakura', 'izumi', 'ako']
				}
			}, alice);

			await request('/notes/polls/vote', {
				noteId: body.createdNote.id,
				choice: 0
			}, alice);

			const res = await request('/notes/polls/vote', {
				noteId: body.createdNote.id,
				choice: 2
			}, alice);

			assert.strictEqual(res.status, 400);
		}));

		it('許可されている場合は複数投票できる', async(async () => {
			const { body } = await request('/notes/create', {
				text: 'test',
				poll: {
					choices: ['sakura', 'izumi', 'ako'],
					multiple: true
				}
			}, alice);

			await request('/notes/polls/vote', {
				noteId: body.createdNote.id,
				choice: 0
			}, alice);

			await request('/notes/polls/vote', {
				noteId: body.createdNote.id,
				choice: 1
			}, alice);

			const res = await request('/notes/polls/vote', {
				noteId: body.createdNote.id,
				choice: 2
			}, alice);

			assert.strictEqual(res.status, 204);
		}));

		it('締め切られている場合は投票できない', async(async () => {
			const { body } = await request('/notes/create', {
				text: 'test',
				poll: {
					choices: ['sakura', 'izumi', 'ako'],
					expiredAfter: 1
				}
			}, alice);

			await new Promise(x => setTimeout(x, 2));

			const res = await request('/notes/polls/vote', {
				noteId: body.createdNote.id,
				choice: 1
			}, alice);

			assert.strictEqual(res.status, 400);
		}));
	});
});