なんかもうめっちゃ変えた

This commit is contained in:
syuilo 2022-09-18 03:27:08 +09:00 committed by GitHub
parent d9ab03f086
commit b75184ec8e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
946 changed files with 41219 additions and 28839 deletions

View file

@ -6,6 +6,6 @@ module.exports = {
extends: ['../.eslintrc.cjs'],
env: {
node: true,
mocha: true,
jest: true,
},
};

View file

@ -2,20 +2,20 @@ process.env.NODE_ENV = 'test';
import * as assert from 'assert';
import * as childProcess from 'child_process';
import { async, signup, request, post, startServer, shutdownServer } from './utils.js';
import { signup, request, post, startServer, shutdownServer } from '../utils.js';
describe('API visibility', () => {
let p: childProcess.ChildProcess;
before(async () => {
beforeAll(async () => {
p = await startServer();
});
}, 1000 * 30);
after(async () => {
afterAll(async () => {
await shutdownServer(p);
});
describe('Note visibility', async () => {
describe('Note visibility', () => {
//#region vars
/** ヒロイン */
let alice: any;
@ -65,7 +65,7 @@ describe('API visibility', () => {
}, by);
};
before(async () => {
beforeAll(async () => {
//#region prepare
// signup
alice = await signup({ username: 'alice' });
@ -100,377 +100,378 @@ describe('API visibility', () => {
//#region show post
// public
it('[show] public-postを自分が見れる', async(async () => {
it('[show] public-postを自分が見れる', async () => {
const res = await show(pub.id, alice);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] public-postをフォロワーが見れる', async(async () => {
it('[show] public-postをフォロワーが見れる', async () => {
const res = await show(pub.id, follower);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] public-postを非フォロワーが見れる', async(async () => {
it('[show] public-postを非フォロワーが見れる', async () => {
const res = await show(pub.id, other);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] public-postを未認証が見れる', async(async () => {
it('[show] public-postを未認証が見れる', async () => {
const res = await show(pub.id, null);
assert.strictEqual(res.body.text, 'x');
}));
});
// home
it('[show] home-postを自分が見れる', async(async () => {
it('[show] home-postを自分が見れる', async () => {
const res = await show(home.id, alice);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] home-postをフォロワーが見れる', async(async () => {
it('[show] home-postをフォロワーが見れる', async () => {
const res = await show(home.id, follower);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] home-postを非フォロワーが見れる', async(async () => {
it('[show] home-postを非フォロワーが見れる', async () => {
const res = await show(home.id, other);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] home-postを未認証が見れる', async(async () => {
it('[show] home-postを未認証が見れる', async () => {
const res = await show(home.id, null);
assert.strictEqual(res.body.text, 'x');
}));
});
// followers
it('[show] followers-postを自分が見れる', async(async () => {
it('[show] followers-postを自分が見れる', async () => {
const res = await show(fol.id, alice);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] followers-postをフォロワーが見れる', async(async () => {
it('[show] followers-postをフォロワーが見れる', async () => {
const res = await show(fol.id, follower);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] followers-postを非フォロワーが見れない', async(async () => {
it('[show] followers-postを非フォロワーが見れない', async () => {
const res = await show(fol.id, other);
assert.strictEqual(res.body.isHidden, true);
}));
});
it('[show] followers-postを未認証が見れない', async(async () => {
it('[show] followers-postを未認証が見れない', async () => {
const res = await show(fol.id, null);
assert.strictEqual(res.body.isHidden, true);
}));
});
// specified
it('[show] specified-postを自分が見れる', async(async () => {
it('[show] specified-postを自分が見れる', async () => {
const res = await show(spe.id, alice);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] specified-postを指定ユーザーが見れる', async(async () => {
it('[show] specified-postを指定ユーザーが見れる', async () => {
const res = await show(spe.id, target);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] specified-postをフォロワーが見れない', async(async () => {
it('[show] specified-postをフォロワーが見れない', async () => {
const res = await show(spe.id, follower);
assert.strictEqual(res.body.isHidden, true);
}));
});
it('[show] specified-postを非フォロワーが見れない', async(async () => {
it('[show] specified-postを非フォロワーが見れない', async () => {
const res = await show(spe.id, other);
assert.strictEqual(res.body.isHidden, true);
}));
});
it('[show] specified-postを未認証が見れない', async(async () => {
it('[show] specified-postを未認証が見れない', async () => {
const res = await show(spe.id, null);
assert.strictEqual(res.body.isHidden, true);
}));
});
//#endregion
//#region show reply
// public
it('[show] public-replyを自分が見れる', async(async () => {
it('[show] public-replyを自分が見れる', async () => {
const res = await show(pubR.id, alice);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] public-replyをされた人が見れる', async(async () => {
it('[show] public-replyをされた人が見れる', async () => {
const res = await show(pubR.id, target);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] public-replyをフォロワーが見れる', async(async () => {
it('[show] public-replyをフォロワーが見れる', async () => {
const res = await show(pubR.id, follower);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] public-replyを非フォロワーが見れる', async(async () => {
it('[show] public-replyを非フォロワーが見れる', async () => {
const res = await show(pubR.id, other);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] public-replyを未認証が見れる', async(async () => {
it('[show] public-replyを未認証が見れる', async () => {
const res = await show(pubR.id, null);
assert.strictEqual(res.body.text, 'x');
}));
});
// home
it('[show] home-replyを自分が見れる', async(async () => {
it('[show] home-replyを自分が見れる', async () => {
const res = await show(homeR.id, alice);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] home-replyをされた人が見れる', async(async () => {
it('[show] home-replyをされた人が見れる', async () => {
const res = await show(homeR.id, target);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] home-replyをフォロワーが見れる', async(async () => {
it('[show] home-replyをフォロワーが見れる', async () => {
const res = await show(homeR.id, follower);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] home-replyを非フォロワーが見れる', async(async () => {
it('[show] home-replyを非フォロワーが見れる', async () => {
const res = await show(homeR.id, other);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] home-replyを未認証が見れる', async(async () => {
it('[show] home-replyを未認証が見れる', async () => {
const res = await show(homeR.id, null);
assert.strictEqual(res.body.text, 'x');
}));
});
// followers
it('[show] followers-replyを自分が見れる', async(async () => {
it('[show] followers-replyを自分が見れる', async () => {
const res = await show(folR.id, alice);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] followers-replyを非フォロワーでもリプライされていれば見れる', async(async () => {
it('[show] followers-replyを非フォロワーでもリプライされていれば見れる', async () => {
const res = await show(folR.id, target);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] followers-replyをフォロワーが見れる', async(async () => {
it('[show] followers-replyをフォロワーが見れる', async () => {
const res = await show(folR.id, follower);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] followers-replyを非フォロワーが見れない', async(async () => {
it('[show] followers-replyを非フォロワーが見れない', async () => {
const res = await show(folR.id, other);
assert.strictEqual(res.body.isHidden, true);
}));
});
it('[show] followers-replyを未認証が見れない', async(async () => {
it('[show] followers-replyを未認証が見れない', async () => {
const res = await show(folR.id, null);
assert.strictEqual(res.body.isHidden, true);
}));
});
// specified
it('[show] specified-replyを自分が見れる', async(async () => {
it('[show] specified-replyを自分が見れる', async () => {
const res = await show(speR.id, alice);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] specified-replyを指定ユーザーが見れる', async(async () => {
it('[show] specified-replyを指定ユーザーが見れる', async () => {
const res = await show(speR.id, target);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] specified-replyをされた人が指定されてなくても見れる', async(async () => {
it('[show] specified-replyをされた人が指定されてなくても見れる', async () => {
const res = await show(speR.id, target);
assert.strictEqual(res.body.text, 'x');
}));
});
it('[show] specified-replyをフォロワーが見れない', async(async () => {
it('[show] specified-replyをフォロワーが見れない', async () => {
const res = await show(speR.id, follower);
assert.strictEqual(res.body.isHidden, true);
}));
});
it('[show] specified-replyを非フォロワーが見れない', async(async () => {
it('[show] specified-replyを非フォロワーが見れない', async () => {
const res = await show(speR.id, other);
assert.strictEqual(res.body.isHidden, true);
}));
});
it('[show] specified-replyを未認証が見れない', async(async () => {
it('[show] specified-replyを未認証が見れない', async () => {
const res = await show(speR.id, null);
assert.strictEqual(res.body.isHidden, true);
}));
});
//#endregion
//#region show mention
// public
it('[show] public-mentionを自分が見れる', async(async () => {
it('[show] public-mentionを自分が見れる', async () => {
const res = await show(pubM.id, alice);
assert.strictEqual(res.body.text, '@target x');
}));
});
it('[show] public-mentionをされた人が見れる', async(async () => {
it('[show] public-mentionをされた人が見れる', async () => {
const res = await show(pubM.id, target);
assert.strictEqual(res.body.text, '@target x');
}));
});
it('[show] public-mentionをフォロワーが見れる', async(async () => {
it('[show] public-mentionをフォロワーが見れる', async () => {
const res = await show(pubM.id, follower);
assert.strictEqual(res.body.text, '@target x');
}));
});
it('[show] public-mentionを非フォロワーが見れる', async(async () => {
it('[show] public-mentionを非フォロワーが見れる', async () => {
const res = await show(pubM.id, other);
assert.strictEqual(res.body.text, '@target x');
}));
});
it('[show] public-mentionを未認証が見れる', async(async () => {
it('[show] public-mentionを未認証が見れる', async () => {
const res = await show(pubM.id, null);
assert.strictEqual(res.body.text, '@target x');
}));
});
// home
it('[show] home-mentionを自分が見れる', async(async () => {
it('[show] home-mentionを自分が見れる', async () => {
const res = await show(homeM.id, alice);
assert.strictEqual(res.body.text, '@target x');
}));
});
it('[show] home-mentionをされた人が見れる', async(async () => {
it('[show] home-mentionをされた人が見れる', async () => {
const res = await show(homeM.id, target);
assert.strictEqual(res.body.text, '@target x');
}));
});
it('[show] home-mentionをフォロワーが見れる', async(async () => {
it('[show] home-mentionをフォロワーが見れる', async () => {
const res = await show(homeM.id, follower);
assert.strictEqual(res.body.text, '@target x');
}));
});
it('[show] home-mentionを非フォロワーが見れる', async(async () => {
it('[show] home-mentionを非フォロワーが見れる', async () => {
const res = await show(homeM.id, other);
assert.strictEqual(res.body.text, '@target x');
}));
});
it('[show] home-mentionを未認証が見れる', async(async () => {
it('[show] home-mentionを未認証が見れる', async () => {
const res = await show(homeM.id, null);
assert.strictEqual(res.body.text, '@target x');
}));
});
// followers
it('[show] followers-mentionを自分が見れる', async(async () => {
it('[show] followers-mentionを自分が見れる', async () => {
const res = await show(folM.id, alice);
assert.strictEqual(res.body.text, '@target x');
}));
});
it('[show] followers-mentionをメンションされていれば非フォロワーでも見れる', async(async () => {
it('[show] followers-mentionをメンションされていれば非フォロワーでも見れる', async () => {
const res = await show(folM.id, target);
assert.strictEqual(res.body.text, '@target x');
}));
});
it('[show] followers-mentionをフォロワーが見れる', async(async () => {
it('[show] followers-mentionをフォロワーが見れる', async () => {
const res = await show(folM.id, follower);
assert.strictEqual(res.body.text, '@target x');
}));
});
it('[show] followers-mentionを非フォロワーが見れない', async(async () => {
it('[show] followers-mentionを非フォロワーが見れない', async () => {
const res = await show(folM.id, other);
assert.strictEqual(res.body.isHidden, true);
}));
});
it('[show] followers-mentionを未認証が見れない', async(async () => {
it('[show] followers-mentionを未認証が見れない', async () => {
const res = await show(folM.id, null);
assert.strictEqual(res.body.isHidden, true);
}));
});
// specified
it('[show] specified-mentionを自分が見れる', async(async () => {
it('[show] specified-mentionを自分が見れる', async () => {
const res = await show(speM.id, alice);
assert.strictEqual(res.body.text, '@target2 x');
}));
});
it('[show] specified-mentionを指定ユーザーが見れる', async(async () => {
it('[show] specified-mentionを指定ユーザーが見れる', async () => {
const res = await show(speM.id, target);
assert.strictEqual(res.body.text, '@target2 x');
}));
});
it('[show] specified-mentionをされた人が指定されてなかったら見れない', async(async () => {
it('[show] specified-mentionをされた人が指定されてなかったら見れない', async () => {
const res = await show(speM.id, target2);
assert.strictEqual(res.body.isHidden, true);
}));
});
it('[show] specified-mentionをフォロワーが見れない', async(async () => {
it('[show] specified-mentionをフォロワーが見れない', async () => {
const res = await show(speM.id, follower);
assert.strictEqual(res.body.isHidden, true);
}));
});
it('[show] specified-mentionを非フォロワーが見れない', async(async () => {
it('[show] specified-mentionを非フォロワーが見れない', async () => {
const res = await show(speM.id, other);
assert.strictEqual(res.body.isHidden, true);
}));
});
it('[show] specified-mentionを未認証が見れない', async(async () => {
it('[show] specified-mentionを未認証が見れない', async () => {
const res = await show(speM.id, null);
assert.strictEqual(res.body.isHidden, true);
}));
});
//#endregion
//#region HTL
it('[HTL] public-post が 自分が見れる', async(async () => {
it('[HTL] public-post が 自分が見れる', async () => {
const res = await request('/notes/timeline', { limit: 100 }, alice);
assert.strictEqual(res.status, 200);
const notes = res.body.filter((n: any) => n.id == pub.id);
const notes = res.body.filter((n: any) => n.id === pub.id);
assert.strictEqual(notes[0].text, 'x');
}));
});
it('[HTL] public-post が 非フォロワーから見れない', async(async () => {
it('[HTL] public-post が 非フォロワーから見れない', async () => {
const res = await request('/notes/timeline', { limit: 100 }, other);
assert.strictEqual(res.status, 200);
const notes = res.body.filter((n: any) => n.id == pub.id);
const notes = res.body.filter((n: any) => n.id === pub.id);
assert.strictEqual(notes.length, 0);
}));
});
it('[HTL] followers-post が フォロワーから見れる', async(async () => {
it('[HTL] followers-post が フォロワーから見れる', async () => {
const res = await request('/notes/timeline', { limit: 100 }, follower);
assert.strictEqual(res.status, 200);
const notes = res.body.filter((n: any) => n.id == fol.id);
const notes = res.body.filter((n: any) => n.id === fol.id);
assert.strictEqual(notes[0].text, 'x');
}));
});
//#endregion
//#region RTL
it('[replies] followers-reply が フォロワーから見れる', async(async () => {
it('[replies] followers-reply が フォロワーから見れる', async () => {
const res = await request('/notes/replies', { noteId: tgt.id, limit: 100 }, follower);
assert.strictEqual(res.status, 200);
const notes = res.body.filter((n: any) => n.id == folR.id);
const notes = res.body.filter((n: any) => n.id === folR.id);
assert.strictEqual(notes[0].text, 'x');
}));
});
it('[replies] followers-reply が 非フォロワー (リプライ先ではない) から見れない', async(async () => {
it('[replies] followers-reply が 非フォロワー (リプライ先ではない) から見れない', async () => {
const res = await request('/notes/replies', { noteId: tgt.id, limit: 100 }, other);
assert.strictEqual(res.status, 200);
const notes = res.body.filter((n: any) => n.id == folR.id);
const notes = res.body.filter((n: any) => n.id === folR.id);
assert.strictEqual(notes.length, 0);
}));
});
it('[replies] followers-reply が 非フォロワー (リプライ先である) から見れる', async(async () => {
it('[replies] followers-reply が 非フォロワー (リプライ先である) から見れる', async () => {
const res = await request('/notes/replies', { noteId: tgt.id, limit: 100 }, target);
assert.strictEqual(res.status, 200);
const notes = res.body.filter((n: any) => n.id == folR.id);
const notes = res.body.filter((n: any) => n.id === folR.id);
assert.strictEqual(notes[0].text, 'x');
}));
});
//#endregion
//#region MTL
it('[mentions] followers-reply が 非フォロワー (リプライ先である) から見れる', async(async () => {
it('[mentions] followers-reply が 非フォロワー (リプライ先である) から見れる', async () => {
const res = await request('/notes/mentions', { limit: 100 }, target);
assert.strictEqual(res.status, 200);
const notes = res.body.filter((n: any) => n.id == folR.id);
const notes = res.body.filter((n: any) => n.id === folR.id);
assert.strictEqual(notes[0].text, 'x');
}));
});
it('[mentions] followers-mention が 非フォロワー (メンション先である) から見れる', async(async () => {
it('[mentions] followers-mention が 非フォロワー (メンション先である) から見れる', async () => {
const res = await request('/notes/mentions', { limit: 100 }, target);
assert.strictEqual(res.status, 200);
const notes = res.body.filter((n: any) => n.id == folM.id);
const notes = res.body.filter((n: any) => n.id === folM.id);
assert.strictEqual(notes[0].text, '@target x');
}));
});
//#endregion
});
});
*/

View file

@ -2,7 +2,7 @@ process.env.NODE_ENV = 'test';
import * as assert from 'assert';
import * as childProcess from 'child_process';
import { async, signup, request, post, react, uploadFile, startServer, shutdownServer } from './utils.js';
import { async, signup, request, post, react, uploadFile, startServer, shutdownServer } from '../utils.js';
describe('API', () => {
let p: childProcess.ChildProcess;
@ -10,14 +10,14 @@ describe('API', () => {
let bob: any;
let carol: any;
before(async () => {
beforeAll(async () => {
p = await startServer();
alice = await signup({ username: 'alice' });
bob = await signup({ username: 'bob' });
carol = await signup({ username: 'carol' });
});
}, 1000 * 30);
after(async () => {
afterAll(async () => {
await shutdownServer(p);
});

View file

@ -2,7 +2,7 @@ process.env.NODE_ENV = 'test';
import * as assert from 'assert';
import * as childProcess from 'child_process';
import { async, signup, request, post, startServer, shutdownServer } from './utils.js';
import { signup, request, post, startServer, shutdownServer } from '../utils.js';
describe('Block', () => {
let p: childProcess.ChildProcess;
@ -12,64 +12,64 @@ describe('Block', () => {
let bob: any;
let carol: any;
before(async () => {
beforeAll(async () => {
p = await startServer();
alice = await signup({ username: 'alice' });
bob = await signup({ username: 'bob' });
carol = await signup({ username: 'carol' });
});
}, 1000 * 30);
after(async () => {
afterAll(async () => {
await shutdownServer(p);
});
it('Block作成', async(async () => {
it('Block作成', async () => {
const res = await request('/blocking/create', {
userId: bob.id,
}, alice);
assert.strictEqual(res.status, 200);
}));
});
it('ブロックされているユーザーをフォローできない', async(async () => {
it('ブロックされているユーザーをフォローできない', async () => {
const res = await request('/following/create', { userId: alice.id }, bob);
assert.strictEqual(res.status, 400);
assert.strictEqual(res.body.error.id, 'c4ab57cc-4e41-45e9-bfd9-584f61e35ce0');
}));
});
it('ブロックされているユーザーにリアクションできない', async(async () => {
it('ブロックされているユーザーにリアクションできない', async () => {
const note = await post(alice, { text: 'hello' });
const res = await request('/notes/reactions/create', { noteId: note.id, reaction: '👍' }, bob);
assert.strictEqual(res.status, 400);
assert.strictEqual(res.body.error.id, '20ef5475-9f38-4e4c-bd33-de6d979498ec');
}));
});
it('ブロックされているユーザーに返信できない', async(async () => {
it('ブロックされているユーザーに返信できない', async () => {
const note = await post(alice, { text: 'hello' });
const res = await request('/notes/create', { replyId: note.id, text: 'yo' }, bob);
assert.strictEqual(res.status, 400);
assert.strictEqual(res.body.error.id, 'b390d7e1-8a5e-46ed-b625-06271cafd3d3');
}));
});
it('ブロックされているユーザーのートをRenoteできない', async(async () => {
it('ブロックされているユーザーのートをRenoteできない', async () => {
const note = await post(alice, { text: 'hello' });
const res = await request('/notes/create', { renoteId: note.id, text: 'yo' }, bob);
assert.strictEqual(res.status, 400);
assert.strictEqual(res.body.error.id, 'b390d7e1-8a5e-46ed-b625-06271cafd3d3');
}));
});
// TODO: ユーザーリストに入れられないテスト
// TODO: ユーザーリストから除外されるテスト
it('タイムライン(LTL)にブロックされているユーザーの投稿が含まれない', async(async () => {
it('タイムライン(LTL)にブロックされているユーザーの投稿が含まれない', async () => {
const aliceNote = await post(alice);
const bobNote = await post(bob);
const carolNote = await post(carol);
@ -81,5 +81,5 @@ describe('Block', () => {
assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), false);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), true);
}));
});
});

View file

@ -3,7 +3,7 @@ process.env.NODE_ENV = 'test';
import * as assert from 'assert';
import * as childProcess from 'child_process';
import * as openapi from '@redocly/openapi-core';
import { async, startServer, signup, post, request, simpleGet, port, shutdownServer } from './utils.js';
import { startServer, signup, post, request, simpleGet, port, shutdownServer } from '../utils.js';
// Request Accept
const ONLY_AP = 'application/activity+json';
@ -22,51 +22,51 @@ describe('Fetch resource', () => {
let alice: any;
let alicesPost: any;
before(async () => {
beforeAll(async () => {
p = await startServer();
alice = await signup({ username: 'alice' });
alicesPost = await post(alice, {
text: 'test',
});
});
}, 1000 * 30);
after(async () => {
afterAll(async () => {
await shutdownServer(p);
});
describe('Common', () => {
it('meta', async(async () => {
it('meta', async () => {
const res = await request('/meta', {
});
assert.strictEqual(res.status, 200);
}));
});
it('GET root', async(async () => {
it('GET root', async () => {
const res = await simpleGet('/');
assert.strictEqual(res.status, 200);
assert.strictEqual(res.type, HTML);
}));
});
it('GET docs', async(async () => {
it('GET docs', async () => {
const res = await simpleGet('/docs/ja-JP/about');
assert.strictEqual(res.status, 200);
assert.strictEqual(res.type, HTML);
}));
});
it('GET api-doc', async(async () => {
it('GET api-doc', async () => {
const res = await simpleGet('/api-doc');
assert.strictEqual(res.status, 200);
assert.strictEqual(res.type, HTML);
}));
});
it('GET api.json', async(async () => {
it('GET api.json', async () => {
const res = await simpleGet('/api.json');
assert.strictEqual(res.status, 200);
assert.strictEqual(res.type, JSON);
}));
});
it('Validate api.json', async(async () => {
it('Validate api.json', async () => {
const config = await openapi.loadConfig();
const result = await openapi.bundle({
config,
@ -78,128 +78,128 @@ describe('Fetch resource', () => {
}
assert.strictEqual(result.problems.length, 0);
}));
});
it('GET favicon.ico', async(async () => {
it('GET favicon.ico', async () => {
const res = await simpleGet('/favicon.ico');
assert.strictEqual(res.status, 200);
assert.strictEqual(res.type, 'image/x-icon');
}));
});
it('GET apple-touch-icon.png', async(async () => {
it('GET apple-touch-icon.png', async () => {
const res = await simpleGet('/apple-touch-icon.png');
assert.strictEqual(res.status, 200);
assert.strictEqual(res.type, 'image/png');
}));
});
it('GET twemoji svg', async(async () => {
it('GET twemoji svg', async () => {
const res = await simpleGet('/twemoji/2764.svg');
assert.strictEqual(res.status, 200);
assert.strictEqual(res.type, 'image/svg+xml');
}));
});
it('GET twemoji svg with hyphen', async(async () => {
it('GET twemoji svg with hyphen', async () => {
const res = await simpleGet('/twemoji/2764-fe0f-200d-1f525.svg');
assert.strictEqual(res.status, 200);
assert.strictEqual(res.type, 'image/svg+xml');
}));
});
});
describe('/@:username', () => {
it('Only AP => AP', async(async () => {
it('Only AP => AP', async () => {
const res = await simpleGet(`/@${alice.username}`, ONLY_AP);
assert.strictEqual(res.status, 200);
assert.strictEqual(res.type, AP);
}));
});
it('Prefer AP => AP', async(async () => {
it('Prefer AP => AP', async () => {
const res = await simpleGet(`/@${alice.username}`, PREFER_AP);
assert.strictEqual(res.status, 200);
assert.strictEqual(res.type, AP);
}));
});
it('Prefer HTML => HTML', async(async () => {
it('Prefer HTML => HTML', async () => {
const res = await simpleGet(`/@${alice.username}`, PREFER_HTML);
assert.strictEqual(res.status, 200);
assert.strictEqual(res.type, HTML);
}));
});
it('Unspecified => HTML', async(async () => {
it('Unspecified => HTML', async () => {
const res = await simpleGet(`/@${alice.username}`, UNSPECIFIED);
assert.strictEqual(res.status, 200);
assert.strictEqual(res.type, HTML);
}));
});
});
describe('/users/:id', () => {
it('Only AP => AP', async(async () => {
it('Only AP => AP', async () => {
const res = await simpleGet(`/users/${alice.id}`, ONLY_AP);
assert.strictEqual(res.status, 200);
assert.strictEqual(res.type, AP);
}));
});
it('Prefer AP => AP', async(async () => {
it('Prefer AP => AP', async () => {
const res = await simpleGet(`/users/${alice.id}`, PREFER_AP);
assert.strictEqual(res.status, 200);
assert.strictEqual(res.type, AP);
}));
});
it('Prefer HTML => Redirect to /@:username', async(async () => {
it('Prefer HTML => Redirect to /@:username', async () => {
const res = await simpleGet(`/users/${alice.id}`, PREFER_HTML);
assert.strictEqual(res.status, 302);
assert.strictEqual(res.location, `/@${alice.username}`);
}));
});
it('Undecided => HTML', async(async () => {
it('Undecided => HTML', async () => {
const res = await simpleGet(`/users/${alice.id}`, UNSPECIFIED);
assert.strictEqual(res.status, 302);
assert.strictEqual(res.location, `/@${alice.username}`);
}));
});
});
describe('/notes/:id', () => {
it('Only AP => AP', async(async () => {
it('Only AP => AP', async () => {
const res = await simpleGet(`/notes/${alicesPost.id}`, ONLY_AP);
assert.strictEqual(res.status, 200);
assert.strictEqual(res.type, AP);
}));
});
it('Prefer AP => AP', async(async () => {
it('Prefer AP => AP', async () => {
const res = await simpleGet(`/notes/${alicesPost.id}`, PREFER_AP);
assert.strictEqual(res.status, 200);
assert.strictEqual(res.type, AP);
}));
});
it('Prefer HTML => HTML', async(async () => {
it('Prefer HTML => HTML', async () => {
const res = await simpleGet(`/notes/${alicesPost.id}`, PREFER_HTML);
assert.strictEqual(res.status, 200);
assert.strictEqual(res.type, HTML);
}));
});
it('Unspecified => HTML', async(async () => {
it('Unspecified => HTML', async () => {
const res = await simpleGet(`/notes/${alicesPost.id}`, UNSPECIFIED);
assert.strictEqual(res.status, 200);
assert.strictEqual(res.type, HTML);
}));
});
});
describe('Feeds', () => {
it('RSS', async(async () => {
it('RSS', async () => {
const res = await simpleGet(`/@${alice.username}.rss`, UNSPECIFIED);
assert.strictEqual(res.status, 200);
assert.strictEqual(res.type, 'application/rss+xml; charset=utf-8');
}));
});
it('ATOM', async(async () => {
it('ATOM', async () => {
const res = await simpleGet(`/@${alice.username}.atom`, UNSPECIFIED);
assert.strictEqual(res.status, 200);
assert.strictEqual(res.type, 'application/atom+xml; charset=utf-8');
}));
});
it('JSON', async(async () => {
it('JSON', async () => {
const res = await simpleGet(`/@${alice.username}.json`, UNSPECIFIED);
assert.strictEqual(res.status, 200);
assert.strictEqual(res.type, 'application/json; charset=utf-8');
}));
});
});
});

View file

@ -2,7 +2,7 @@ process.env.NODE_ENV = 'test';
import * as assert from 'assert';
import * as childProcess from 'child_process';
import { async, signup, request, post, react, connectStream, startServer, shutdownServer, simpleGet } from './utils.js';
import { signup, request, post, react, connectStream, startServer, shutdownServer, simpleGet } from '../utils.js';
describe('FF visibility', () => {
let p: childProcess.ChildProcess;
@ -11,18 +11,18 @@ describe('FF visibility', () => {
let bob: any;
let carol: any;
before(async () => {
beforeAll(async () => {
p = await startServer();
alice = await signup({ username: 'alice' });
bob = await signup({ username: 'bob' });
carol = await signup({ username: 'carol' });
});
}, 1000 * 30);
after(async () => {
afterAll(async () => {
await shutdownServer(p);
});
it('ffVisibility が public なユーザーのフォロー/フォロワーを誰でも見れる', async(async () => {
it('ffVisibility が public なユーザーのフォロー/フォロワーを誰でも見れる', async () => {
await request('/i/update', {
ffVisibility: 'public',
}, alice);
@ -38,9 +38,9 @@ describe('FF visibility', () => {
assert.strictEqual(Array.isArray(followingRes.body), true);
assert.strictEqual(followersRes.status, 200);
assert.strictEqual(Array.isArray(followersRes.body), true);
}));
});
it('ffVisibility が followers なユーザーのフォロー/フォロワーを自分で見れる', async(async () => {
it('ffVisibility が followers なユーザーのフォロー/フォロワーを自分で見れる', async () => {
await request('/i/update', {
ffVisibility: 'followers',
}, alice);
@ -56,9 +56,9 @@ describe('FF visibility', () => {
assert.strictEqual(Array.isArray(followingRes.body), true);
assert.strictEqual(followersRes.status, 200);
assert.strictEqual(Array.isArray(followersRes.body), true);
}));
});
it('ffVisibility が followers なユーザーのフォロー/フォロワーを非フォロワーが見れない', async(async () => {
it('ffVisibility が followers なユーザーのフォロー/フォロワーを非フォロワーが見れない', async () => {
await request('/i/update', {
ffVisibility: 'followers',
}, alice);
@ -72,9 +72,9 @@ describe('FF visibility', () => {
assert.strictEqual(followingRes.status, 400);
assert.strictEqual(followersRes.status, 400);
}));
});
it('ffVisibility が followers なユーザーのフォロー/フォロワーをフォロワーが見れる', async(async () => {
it('ffVisibility が followers なユーザーのフォロー/フォロワーをフォロワーが見れる', async () => {
await request('/i/update', {
ffVisibility: 'followers',
}, alice);
@ -94,9 +94,9 @@ describe('FF visibility', () => {
assert.strictEqual(Array.isArray(followingRes.body), true);
assert.strictEqual(followersRes.status, 200);
assert.strictEqual(Array.isArray(followersRes.body), true);
}));
});
it('ffVisibility が private なユーザーのフォロー/フォロワーを自分で見れる', async(async () => {
it('ffVisibility が private なユーザーのフォロー/フォロワーを自分で見れる', async () => {
await request('/i/update', {
ffVisibility: 'private',
}, alice);
@ -112,9 +112,9 @@ describe('FF visibility', () => {
assert.strictEqual(Array.isArray(followingRes.body), true);
assert.strictEqual(followersRes.status, 200);
assert.strictEqual(Array.isArray(followersRes.body), true);
}));
});
it('ffVisibility が private なユーザーのフォロー/フォロワーを他人が見れない', async(async () => {
it('ffVisibility が private なユーザーのフォロー/フォロワーを他人が見れない', async () => {
await request('/i/update', {
ffVisibility: 'private',
}, alice);
@ -128,10 +128,10 @@ describe('FF visibility', () => {
assert.strictEqual(followingRes.status, 400);
assert.strictEqual(followersRes.status, 400);
}));
});
describe('AP', () => {
it('ffVisibility が public 以外ならばAPからは取得できない', async(async () => {
it('ffVisibility が public 以外ならばAPからは取得できない', async () => {
{
await request('/i/update', {
ffVisibility: 'public',
@ -162,6 +162,6 @@ describe('FF visibility', () => {
assert.strictEqual(followingRes.status, 403);
assert.strictEqual(followersRes.status, 403);
}
}));
});
});
});

View file

@ -2,7 +2,7 @@ process.env.NODE_ENV = 'test';
import * as assert from 'assert';
import * as childProcess from 'child_process';
import { async, signup, request, post, react, startServer, shutdownServer, waitFire } from './utils.js';
import { signup, request, post, react, startServer, shutdownServer, waitFire } from '../utils.js';
describe('Mute', () => {
let p: childProcess.ChildProcess;
@ -12,26 +12,26 @@ describe('Mute', () => {
let bob: any;
let carol: any;
before(async () => {
beforeAll(async () => {
p = await startServer();
alice = await signup({ username: 'alice' });
bob = await signup({ username: 'bob' });
carol = await signup({ username: 'carol' });
});
}, 1000 * 30);
after(async () => {
afterAll(async () => {
await shutdownServer(p);
});
it('ミュート作成', async(async () => {
it('ミュート作成', async () => {
const res = await request('/mute/create', {
userId: carol.id,
}, alice);
assert.strictEqual(res.status, 204);
}));
});
it('「自分宛ての投稿」にミュートしているユーザーの投稿が含まれない', async(async () => {
it('「自分宛ての投稿」にミュートしているユーザーの投稿が含まれない', async () => {
const bobNote = await post(bob, { text: '@alice hi' });
const carolNote = await post(carol, { text: '@alice hi' });
@ -41,9 +41,9 @@ describe('Mute', () => {
assert.strictEqual(Array.isArray(res.body), true);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
}));
});
it('ミュートしているユーザーからメンションされても、hasUnreadMentions が true にならない', async(async () => {
it('ミュートしているユーザーからメンションされても、hasUnreadMentions が true にならない', async () => {
// 状態リセット
await request('/i/read-all-unread-notes', {}, alice);
@ -53,7 +53,7 @@ describe('Mute', () => {
assert.strictEqual(res.status, 200);
assert.strictEqual(res.body.hasUnreadMentions, false);
}));
});
it('ミュートしているユーザーからメンションされても、ストリームに unreadMention イベントが流れてこない', async () => {
// 状態リセット
@ -75,7 +75,7 @@ describe('Mute', () => {
});
describe('Timeline', () => {
it('タイムラインにミュートしているユーザーの投稿が含まれない', async(async () => {
it('タイムラインにミュートしているユーザーの投稿が含まれない', async () => {
const aliceNote = await post(alice);
const bobNote = await post(bob);
const carolNote = await post(carol);
@ -87,9 +87,9 @@ describe('Mute', () => {
assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
}));
});
it('タイムラインにミュートしているユーザーの投稿のRenoteが含まれない', async(async () => {
it('タイムラインにミュートしているユーザーの投稿のRenoteが含まれない', async () => {
const aliceNote = await post(alice);
const carolNote = await post(carol);
const bobNote = await post(bob, {
@ -103,11 +103,11 @@ describe('Mute', () => {
assert.strictEqual(res.body.some((note: any) => note.id === aliceNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
assert.strictEqual(res.body.some((note: any) => note.id === carolNote.id), false);
}));
});
});
describe('Notification', () => {
it('通知にミュートしているユーザーの通知が含まれない(リアクション)', async(async () => {
it('通知にミュートしているユーザーの通知が含まれない(リアクション)', async () => {
const aliceNote = await post(alice);
await react(bob, aliceNote, 'like');
await react(carol, aliceNote, 'like');
@ -118,6 +118,6 @@ describe('Mute', () => {
assert.strictEqual(Array.isArray(res.body), true);
assert.strictEqual(res.body.some((notification: any) => notification.userId === bob.id), true);
assert.strictEqual(res.body.some((notification: any) => notification.userId === carol.id), false);
}));
});
});
});

View file

@ -2,8 +2,8 @@ process.env.NODE_ENV = 'test';
import * as assert from 'assert';
import * as childProcess from 'child_process';
import { Note } from '../src/models/entities/note.js';
import { async, signup, request, post, uploadUrl, startServer, shutdownServer, initTestDb, api } from './utils.js';
import { Note } from '../../src/models/entities/note.js';
import { async, signup, request, post, uploadUrl, startServer, shutdownServer, initTestDb, api } from '../utils.js';
describe('Note', () => {
let p: childProcess.ChildProcess;
@ -12,19 +12,19 @@ describe('Note', () => {
let alice: any;
let bob: any;
before(async () => {
beforeAll(async () => {
p = await startServer();
const connection = await initTestDb(true);
Notes = connection.getRepository(Note);
alice = await signup({ username: 'alice' });
bob = await signup({ username: 'bob' });
});
}, 1000 * 30);
after(async () => {
afterAll(async () => {
await shutdownServer(p);
});
it('投稿できる', async(async () => {
it('投稿できる', async () => {
const post = {
text: 'test',
};
@ -34,9 +34,9 @@ describe('Note', () => {
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 () => {
it('ファイルを添付できる', async () => {
const file = await uploadUrl(alice, 'https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/Lenna.jpg');
const res = await request('/notes/create', {
@ -46,9 +46,9 @@ describe('Note', () => {
assert.strictEqual(res.status, 200);
assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
assert.deepStrictEqual(res.body.createdNote.fileIds, [file.id]);
}));
}, 1000 * 10);
it('他人のファイルは無視', async(async () => {
it('他人のファイルは無視', async () => {
const file = await uploadUrl(bob, 'https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/Lenna.jpg');
const res = await request('/notes/create', {
@ -59,9 +59,9 @@ describe('Note', () => {
assert.strictEqual(res.status, 200);
assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
assert.deepStrictEqual(res.body.createdNote.fileIds, []);
}));
}, 1000 * 10);
it('存在しないファイルは無視', async(async () => {
it('存在しないファイルは無視', async () => {
const res = await request('/notes/create', {
text: 'test',
fileIds: ['000000000000000000000000'],
@ -70,18 +70,18 @@ describe('Note', () => {
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 () => {
it('不正なファイルIDは無視', async () => {
const res = await request('/notes/create', {
fileIds: ['kyoppie'],
}, 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 () => {
it('返信できる', async () => {
const bobPost = await post(bob, {
text: 'foo',
});
@ -98,9 +98,9 @@ describe('Note', () => {
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 () => {
it('renoteできる', async () => {
const bobPost = await post(bob, {
text: 'test',
});
@ -115,9 +115,9 @@ describe('Note', () => {
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 () => {
it('引用renoteできる', async () => {
const bobPost = await post(bob, {
text: 'test',
});
@ -134,59 +134,59 @@ describe('Note', () => {
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 () => {
it('文字数ぎりぎりで怒られない', async () => {
const post = {
text: '!'.repeat(3000),
};
const res = await request('/notes/create', post, alice);
assert.strictEqual(res.status, 200);
}));
});
it('文字数オーバーで怒られる', async(async () => {
it('文字数オーバーで怒られる', async () => {
const post = {
text: '!'.repeat(3001),
};
const res = await request('/notes/create', post, alice);
assert.strictEqual(res.status, 400);
}));
});
it('存在しないリプライ先で怒られる', async(async () => {
it('存在しないリプライ先で怒られる', async () => {
const post = {
text: 'test',
replyId: '000000000000000000000000',
};
const res = await request('/notes/create', post, alice);
assert.strictEqual(res.status, 400);
}));
});
it('存在しないrenote対象で怒られる', async(async () => {
it('存在しないrenote対象で怒られる', async () => {
const post = {
renoteId: '000000000000000000000000',
};
const res = await request('/notes/create', post, alice);
assert.strictEqual(res.status, 400);
}));
});
it('不正なリプライ先IDで怒られる', async(async () => {
it('不正なリプライ先IDで怒られる', 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 () => {
it('不正なrenote対象IDで怒られる', async () => {
const post = {
renoteId: 'foo',
};
const res = await request('/notes/create', post, alice);
assert.strictEqual(res.status, 400);
}));
});
it('存在しないユーザーにメンションできる', async(async () => {
it('存在しないユーザーにメンションできる', async () => {
const post = {
text: '@ghost yo',
};
@ -196,9 +196,9 @@ describe('Note', () => {
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 () => {
it('同じユーザーに複数メンションしても内部的にまとめられる', async () => {
const post = {
text: '@bob @bob @bob yo',
};
@ -211,10 +211,10 @@ describe('Note', () => {
const noteDoc = await Notes.findOneBy({ id: res.body.createdNote.id });
assert.deepStrictEqual(noteDoc.mentions, [bob.id]);
}));
});
describe('notes/create', () => {
it('投票を添付できる', async(async () => {
it('投票を添付できる', async () => {
const res = await request('/notes/create', {
text: 'test',
poll: {
@ -225,34 +225,34 @@ describe('Note', () => {
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 () => {
it('投票の選択肢が無くて怒られる', async () => {
const res = await request('/notes/create', {
poll: {},
}, alice);
assert.strictEqual(res.status, 400);
}));
});
it('投票の選択肢が無くて怒られる (空の配列)', async(async () => {
it('投票の選択肢が無くて怒られる (空の配列)', async () => {
const res = await request('/notes/create', {
poll: {
choices: [],
},
}, alice);
assert.strictEqual(res.status, 400);
}));
});
it('投票の選択肢が1つで怒られる', async(async () => {
it('投票の選択肢が1つで怒られる', async () => {
const res = await request('/notes/create', {
poll: {
choices: ['Strawberry Pasta'],
},
}, alice);
assert.strictEqual(res.status, 400);
}));
});
it('投票できる', async(async () => {
it('投票できる', async () => {
const { body } = await request('/notes/create', {
text: 'test',
poll: {
@ -266,9 +266,9 @@ describe('Note', () => {
}, alice);
assert.strictEqual(res.status, 204);
}));
});
it('複数投票できない', async(async () => {
it('複数投票できない', async () => {
const { body } = await request('/notes/create', {
text: 'test',
poll: {
@ -287,9 +287,9 @@ describe('Note', () => {
}, alice);
assert.strictEqual(res.status, 400);
}));
});
it('許可されている場合は複数投票できる', async(async () => {
it('許可されている場合は複数投票できる', async () => {
const { body } = await request('/notes/create', {
text: 'test',
poll: {
@ -314,9 +314,9 @@ describe('Note', () => {
}, alice);
assert.strictEqual(res.status, 204);
}));
});
it('締め切られている場合は投票できない', async(async () => {
it('締め切られている場合は投票できない', async () => {
const { body } = await request('/notes/create', {
text: 'test',
poll: {
@ -333,11 +333,11 @@ describe('Note', () => {
}, alice);
assert.strictEqual(res.status, 400);
}));
});
});
describe('notes/delete', () => {
it('delete a reply', async(async () => {
it('delete a reply', async () => {
const mainNoteRes = await api('notes/create', {
text: 'main post',
}, alice);
@ -365,6 +365,6 @@ describe('Note', () => {
assert.strictEqual(deleteTwoRes.status, 204);
mainNote = await Notes.findOneBy({ id: mainNoteRes.body.createdNote.id });
assert.strictEqual(mainNote.repliesCount, 0);
}));
});
});
});

View file

@ -2,8 +2,8 @@ process.env.NODE_ENV = 'test';
import * as assert from 'assert';
import * as childProcess from 'child_process';
import { Following } from '../src/models/entities/following.js';
import { connectStream, signup, api, post, startServer, shutdownServer, initTestDb, waitFire } from './utils.js';
import { Following } from '../../src/models/entities/following.js';
import { connectStream, signup, api, post, startServer, shutdownServer, initTestDb, waitFire } from '../utils.js';
describe('Streaming', () => {
let p: childProcess.ChildProcess;
@ -37,7 +37,7 @@ describe('Streaming', () => {
let kyokoNote: any;
let list: any;
before(async () => {
beforeAll(async () => {
p = await startServer();
const connection = await initTestDb(true);
Followings = connection.getRepository(Following);
@ -71,9 +71,9 @@ describe('Streaming', () => {
listId: list.id,
userId: kyoko.id,
}, chitose);
});
}, 1000 * 30);
after(async () => {
afterAll(async () => {
await shutdownServer(p);
});
@ -82,7 +82,7 @@ describe('Streaming', () => {
const fired = await waitFire(
kyoko, 'main', // kyoko:main
() => post(ayano, { text: 'foo @kyoko bar' }), // ayano mention => kyoko
msg => msg.type === 'mention' && msg.body.userId === ayano.id // wait ayano
msg => msg.type === 'mention' && msg.body.userId === ayano.id, // wait ayano
);
assert.strictEqual(fired, true);
@ -92,7 +92,7 @@ describe('Streaming', () => {
const fired = await waitFire(
kyoko, 'main', // kyoko:main
() => post(ayano, { renoteId: kyokoNote.id }), // ayano renote
msg => msg.type === 'renote' && msg.body.renoteId === kyokoNote.id // wait renote
msg => msg.type === 'renote' && msg.body.renoteId === kyokoNote.id, // wait renote
);
assert.strictEqual(fired, true);
@ -104,7 +104,7 @@ describe('Streaming', () => {
const fired = await waitFire(
ayano, 'homeTimeline', // ayano:Home
() => api('notes/create', { text: 'foo' }, ayano), // ayano posts
msg => msg.type === 'note' && msg.body.text === 'foo'
msg => msg.type === 'note' && msg.body.text === 'foo',
);
assert.strictEqual(fired, true);
@ -114,7 +114,7 @@ describe('Streaming', () => {
const fired = await waitFire(
ayano, 'homeTimeline', // ayano:home
() => api('notes/create', { text: 'foo' }, kyoko), // kyoko posts
msg => msg.type === 'note' && msg.body.userId === kyoko.id // wait kyoko
msg => msg.type === 'note' && msg.body.userId === kyoko.id, // wait kyoko
);
assert.strictEqual(fired, true);
@ -124,7 +124,7 @@ describe('Streaming', () => {
const fired = await waitFire(
kyoko, 'homeTimeline', // kyoko:home
() => api('notes/create', { text: 'foo' }, ayano), // ayano posts
msg => msg.type === 'note' && msg.body.userId === ayano.id // wait ayano
msg => msg.type === 'note' && msg.body.userId === ayano.id, // wait ayano
);
assert.strictEqual(fired, false);
@ -133,8 +133,8 @@ describe('Streaming', () => {
it('フォローしているユーザーのダイレクト投稿が流れる', async () => {
const fired = await waitFire(
ayano, 'homeTimeline', // ayano:home
() => api('notes/create', { text: 'foo', visibility: 'specified', visibleUserIds: [ayano.id], }, kyoko), // kyoko dm => ayano
msg => msg.type === 'note' && msg.body.userId === kyoko.id // wait kyoko
() => api('notes/create', { text: 'foo', visibility: 'specified', visibleUserIds: [ayano.id] }, kyoko), // kyoko dm => ayano
msg => msg.type === 'note' && msg.body.userId === kyoko.id, // wait kyoko
);
assert.strictEqual(fired, true);
@ -143,8 +143,8 @@ describe('Streaming', () => {
it('フォローしているユーザーでも自分が指定されていないダイレクト投稿は流れない', async () => {
const fired = await waitFire(
ayano, 'homeTimeline', // ayano:home
() => api('notes/create', { text: 'foo', visibility: 'specified', visibleUserIds: [chitose.id], }, kyoko), // kyoko dm => chitose
msg => msg.type === 'note' && msg.body.userId === kyoko.id // wait kyoko
() => api('notes/create', { text: 'foo', visibility: 'specified', visibleUserIds: [chitose.id] }, kyoko), // kyoko dm => chitose
msg => msg.type === 'note' && msg.body.userId === kyoko.id, // wait kyoko
);
assert.strictEqual(fired, false);
@ -156,7 +156,7 @@ describe('Streaming', () => {
const fired = await waitFire(
ayano, 'localTimeline', // ayano:Local
() => api('notes/create', { text: 'foo' }, ayano), // ayano posts
msg => msg.type === 'note' && msg.body.text === 'foo'
msg => msg.type === 'note' && msg.body.text === 'foo',
);
assert.strictEqual(fired, true);
@ -166,7 +166,7 @@ describe('Streaming', () => {
const fired = await waitFire(
ayano, 'localTimeline', // ayano:Local
() => api('notes/create', { text: 'foo' }, chitose), // chitose posts
msg => msg.type === 'note' && msg.body.userId === chitose.id // wait chitose
msg => msg.type === 'note' && msg.body.userId === chitose.id, // wait chitose
);
assert.strictEqual(fired, true);
@ -176,7 +176,7 @@ describe('Streaming', () => {
const fired = await waitFire(
ayano, 'localTimeline', // ayano:Local
() => api('notes/create', { text: 'foo' }, chinatsu), // chinatsu posts
msg => msg.type === 'note' && msg.body.userId === chinatsu.id // wait chinatsu
msg => msg.type === 'note' && msg.body.userId === chinatsu.id, // wait chinatsu
);
assert.strictEqual(fired, false);
@ -186,7 +186,7 @@ describe('Streaming', () => {
const fired = await waitFire(
ayano, 'localTimeline', // ayano:Local
() => api('notes/create', { text: 'foo' }, akari), // akari posts
msg => msg.type === 'note' && msg.body.userId === akari.id // wait akari
msg => msg.type === 'note' && msg.body.userId === akari.id, // wait akari
);
assert.strictEqual(fired, false);
@ -196,7 +196,7 @@ describe('Streaming', () => {
const fired = await waitFire(
ayano, 'localTimeline', // ayano:Local
() => api('notes/create', { text: 'foo', visibility: 'home' }, kyoko), // kyoko home posts
msg => msg.type === 'note' && msg.body.userId === kyoko.id // wait kyoko
msg => msg.type === 'note' && msg.body.userId === kyoko.id, // wait kyoko
);
assert.strictEqual(fired, false);
@ -206,7 +206,7 @@ describe('Streaming', () => {
const fired = await waitFire(
ayano, 'localTimeline', // ayano:Local
() => api('notes/create', { text: 'foo', visibility: 'specified', visibleUserIds: [ayano.id] }, kyoko), // kyoko DM => ayano
msg => msg.type === 'note' && msg.body.userId === kyoko.id // wait kyoko
msg => msg.type === 'note' && msg.body.userId === kyoko.id, // wait kyoko
);
assert.strictEqual(fired, false);
@ -216,7 +216,7 @@ describe('Streaming', () => {
const fired = await waitFire(
ayano, 'localTimeline', // ayano:Local
() => api('notes/create', { text: 'foo', visibility: 'followers' }, chitose),
msg => msg.type === 'note' && msg.body.userId === chitose.id // wait chitose
msg => msg.type === 'note' && msg.body.userId === chitose.id, // wait chitose
);
assert.strictEqual(fired, false);
@ -228,7 +228,7 @@ describe('Streaming', () => {
const fired = await waitFire(
ayano, 'hybridTimeline', // ayano:Hybrid
() => api('notes/create', { text: 'foo' }, ayano), // ayano posts
msg => msg.type === 'note' && msg.body.text === 'foo'
msg => msg.type === 'note' && msg.body.text === 'foo',
);
assert.strictEqual(fired, true);
@ -238,7 +238,7 @@ describe('Streaming', () => {
const fired = await waitFire(
ayano, 'hybridTimeline', // ayano:Hybrid
() => api('notes/create', { text: 'foo' }, chitose), // chitose posts
msg => msg.type === 'note' && msg.body.userId === chitose.id // wait chitose
msg => msg.type === 'note' && msg.body.userId === chitose.id, // wait chitose
);
assert.strictEqual(fired, true);
@ -248,7 +248,7 @@ describe('Streaming', () => {
const fired = await waitFire(
ayano, 'hybridTimeline', // ayano:Hybrid
() => api('notes/create', { text: 'foo' }, akari), // akari posts
msg => msg.type === 'note' && msg.body.userId === akari.id // wait akari
msg => msg.type === 'note' && msg.body.userId === akari.id, // wait akari
);
assert.strictEqual(fired, true);
@ -258,7 +258,7 @@ describe('Streaming', () => {
const fired = await waitFire(
ayano, 'hybridTimeline', // ayano:Hybrid
() => api('notes/create', { text: 'foo' }, chinatsu), // chinatsu posts
msg => msg.type === 'note' && msg.body.userId === chinatsu.id // wait chinatsu
msg => msg.type === 'note' && msg.body.userId === chinatsu.id, // wait chinatsu
);
assert.strictEqual(fired, false);
@ -268,7 +268,7 @@ describe('Streaming', () => {
const fired = await waitFire(
ayano, 'hybridTimeline', // ayano:Hybrid
() => api('notes/create', { text: 'foo', visibility: 'specified', visibleUserIds: [ayano.id] }, kyoko),
msg => msg.type === 'note' && msg.body.userId === kyoko.id // wait kyoko
msg => msg.type === 'note' && msg.body.userId === kyoko.id, // wait kyoko
);
assert.strictEqual(fired, true);
@ -278,7 +278,7 @@ describe('Streaming', () => {
const fired = await waitFire(
ayano, 'hybridTimeline', // ayano:Hybrid
() => api('notes/create', { text: 'foo', visibility: 'home' }, kyoko),
msg => msg.type === 'note' && msg.body.userId === kyoko.id // wait kyoko
msg => msg.type === 'note' && msg.body.userId === kyoko.id, // wait kyoko
);
assert.strictEqual(fired, true);
@ -288,17 +288,17 @@ describe('Streaming', () => {
const fired = await waitFire(
ayano, 'hybridTimeline', // ayano:Hybrid
() => api('notes/create', { text: 'foo', visibility: 'home' }, chitose),
msg => msg.type === 'note' && msg.body.userId === chitose.id
msg => msg.type === 'note' && msg.body.userId === chitose.id,
);
assert.strictEqual(fired, false);
});
it('フォローしていないローカルユーザーのフォロワー宛て投稿は流れない', () => async () => {
it('フォローしていないローカルユーザーのフォロワー宛て投稿は流れない', async () => {
const fired = await waitFire(
ayano, 'hybridTimeline', // ayano:Hybrid
() => api('notes/create', { text: 'foo', visibility: 'followers' }, chitose),
msg => msg.type === 'note' && msg.body.userId === chitose.id
msg => msg.type === 'note' && msg.body.userId === chitose.id,
);
assert.strictEqual(fired, false);
@ -306,31 +306,31 @@ describe('Streaming', () => {
});
describe('Global Timeline', () => {
it('フォローしていないローカルユーザーの投稿が流れる', () => async () => {
it('フォローしていないローカルユーザーの投稿が流れる', async () => {
const fired = await waitFire(
ayano, 'globalTimeline', // ayano:Global
() => api('notes/create', { text: 'foo' }, chitose), // chitose posts
msg => msg.type === 'note' && msg.body.userId === chitose.id // wait chitose
msg => msg.type === 'note' && msg.body.userId === chitose.id, // wait chitose
);
assert.strictEqual(fired, true);
});
it('フォローしていないリモートユーザーの投稿が流れる', () => async () => {
it('フォローしていないリモートユーザーの投稿が流れる', async () => {
const fired = await waitFire(
ayano, 'globalTimeline', // ayano:Global
() => api('notes/create', { text: 'foo' }, chinatsu), // chinatsu posts
msg => msg.type === 'note' && msg.body.userId === chinatsu.id // wait chinatsu
msg => msg.type === 'note' && msg.body.userId === chinatsu.id, // wait chinatsu
);
assert.strictEqual(fired, true);
});
it('ホーム投稿は流れない', () => async () => {
it('ホーム投稿は流れない', async () => {
const fired = await waitFire(
ayano, 'globalTimeline', // ayano:Global
() => api('notes/create', { text: 'foo', visibility: 'home' }, kyoko), // kyoko posts
msg => msg.type === 'note' && msg.body.userId === kyoko.id // wait kyoko
msg => msg.type === 'note' && msg.body.userId === kyoko.id, // wait kyoko
);
assert.strictEqual(fired, false);
@ -338,47 +338,47 @@ describe('Streaming', () => {
});
describe('UserList Timeline', () => {
it('リストに入れているユーザーの投稿が流れる', () => async () => {
it('リストに入れているユーザーの投稿が流れる', async () => {
const fired = await waitFire(
chitose, 'userList',
() => api('notes/create', { text: 'foo' }, ayano),
msg => msg.type === 'note' && msg.body.userId === ayano.id,
{ listId: list.id, }
{ listId: list.id },
);
assert.strictEqual(fired, true);
});
it('リストに入れていないユーザーの投稿は流れない', () => async () => {
it('リストに入れていないユーザーの投稿は流れない', async () => {
const fired = await waitFire(
chitose, 'userList',
() => api('notes/create', { text: 'foo' }, chinatsu),
msg => msg.type === 'note' && msg.body.userId === chinatsu.id,
{ listId: list.id, }
{ listId: list.id },
);
assert.strictEqual(fired, false);
});
// #4471
it('リストに入れているユーザーのダイレクト投稿が流れる', () => async () => {
it('リストに入れているユーザーのダイレクト投稿が流れる', async () => {
const fired = await waitFire(
chitose, 'userList',
() => api('notes/create', { text: 'foo', visibility: 'specified', visibleUserIds: [chitose.id] }, ayano),
msg => msg.type === 'note' && msg.body.userId === ayano.id,
{ listId: list.id, }
{ listId: list.id },
);
assert.strictEqual(fired, true);
});
// #4335
it('リストに入れているがフォローはしてないユーザーのフォロワー宛て投稿は流れない', () => async () => {
it('リストに入れているがフォローはしてないユーザーのフォロワー宛て投稿は流れない', async () => {
const fired = await waitFire(
chitose, 'userList',
() => api('notes/create', { text: 'foo', visibility: 'followers' }, kyoko),
msg => msg.type === 'note' && msg.body.userId === kyoko.id,
{ listId: list.id, }
{ listId: list.id },
);
assert.strictEqual(fired, false);
@ -388,7 +388,7 @@ describe('Streaming', () => {
describe('Hashtag Timeline', () => {
it('指定したハッシュタグの投稿が流れる', () => new Promise<void>(async done => {
const ws = await connectStream(chitose, 'hashtag', ({ type, body }) => {
if (type == 'note') {
if (type === 'note') {
assert.deepStrictEqual(body.text, '#foo');
ws.close();
done();
@ -410,7 +410,7 @@ describe('Streaming', () => {
let fooBarCount = 0;
const ws = await connectStream(chitose, 'hashtag', ({ type, body }) => {
if (type == 'note') {
if (type === 'note') {
if (body.text === '#foo') fooCount++;
if (body.text === '#bar') barCount++;
if (body.text === '#foo #bar') fooBarCount++;
@ -449,7 +449,7 @@ describe('Streaming', () => {
let piyoCount = 0;
const ws = await connectStream(chitose, 'hashtag', ({ type, body }) => {
if (type == 'note') {
if (type === 'note') {
if (body.text === '#foo') fooCount++;
if (body.text === '#bar') barCount++;
if (body.text === '#foo #bar') fooBarCount++;
@ -496,7 +496,7 @@ describe('Streaming', () => {
let waaaCount = 0;
const ws = await connectStream(chitose, 'hashtag', ({ type, body }) => {
if (type == 'note') {
if (type === 'note') {
if (body.text === '#foo') fooCount++;
if (body.text === '#bar') barCount++;
if (body.text === '#foo #bar') fooBarCount++;

View file

@ -2,7 +2,7 @@ process.env.NODE_ENV = 'test';
import * as assert from 'assert';
import * as childProcess from 'child_process';
import { async, signup, request, post, react, connectStream, startServer, shutdownServer } from './utils.js';
import { signup, request, post, react, connectStream, startServer, shutdownServer } from '../utils.js';
describe('Note thread mute', () => {
let p: childProcess.ChildProcess;
@ -11,18 +11,18 @@ describe('Note thread mute', () => {
let bob: any;
let carol: any;
before(async () => {
beforeAll(async () => {
p = await startServer();
alice = await signup({ username: 'alice' });
bob = await signup({ username: 'bob' });
carol = await signup({ username: 'carol' });
});
}, 1000 * 30);
after(async () => {
afterAll(async () => {
await shutdownServer(p);
});
it('notes/mentions にミュートしているスレッドの投稿が含まれない', async(async () => {
it('notes/mentions にミュートしているスレッドの投稿が含まれない', async () => {
const bobNote = await post(bob, { text: '@alice @carol root note' });
const aliceReply = await post(alice, { replyId: bobNote.id, text: '@bob @carol child note' });
@ -38,9 +38,9 @@ describe('Note thread mute', () => {
assert.strictEqual(res.body.some((note: any) => note.id === bobNote.id), false);
assert.strictEqual(res.body.some((note: any) => note.id === carolReply.id), false);
assert.strictEqual(res.body.some((note: any) => note.id === carolReplyWithoutMention.id), false);
}));
});
it('ミュートしているスレッドからメンションされても、hasUnreadMentions が true にならない', async(async () => {
it('ミュートしているスレッドからメンションされても、hasUnreadMentions が true にならない', async () => {
// 状態リセット
await request('/i/read-all-unread-notes', {}, alice);
@ -54,7 +54,7 @@ describe('Note thread mute', () => {
assert.strictEqual(res.status, 200);
assert.strictEqual(res.body.hasUnreadMentions, false);
}));
});
it('ミュートしているスレッドからメンションされても、ストリームに unreadMention イベントが流れてこない', () => new Promise(async done => {
// 状態リセット
@ -82,7 +82,7 @@ describe('Note thread mute', () => {
}, 5000);
}));
it('i/notifications にミュートしているスレッドの通知が含まれない', async(async () => {
it('i/notifications にミュートしているスレッドの通知が含まれない', async () => {
const bobNote = await post(bob, { text: '@alice @carol root note' });
const aliceReply = await post(alice, { replyId: bobNote.id, text: '@bob @carol child note' });
@ -99,5 +99,5 @@ describe('Note thread mute', () => {
assert.strictEqual(res.body.some((notification: any) => notification.note.id === carolReplyWithoutMention.id), false);
// NOTE: bobの投稿はスレッドミュート前に行われたため通知に含まれていてもよい
}));
});
});

View file

@ -2,7 +2,7 @@ process.env.NODE_ENV = 'test';
import * as assert from 'assert';
import * as childProcess from 'child_process';
import { async, signup, request, post, uploadUrl, startServer, shutdownServer } from './utils.js';
import { signup, request, post, uploadUrl, startServer, shutdownServer } from '../utils.js';
describe('users/notes', () => {
let p: childProcess.ChildProcess;
@ -12,7 +12,7 @@ describe('users/notes', () => {
let pngNote: any;
let jpgPngNote: any;
before(async () => {
beforeAll(async () => {
p = await startServer();
alice = await signup({ username: 'alice' });
const jpg = await uploadUrl(alice, 'https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/Lenna.jpg');
@ -26,13 +26,13 @@ describe('users/notes', () => {
jpgPngNote = await post(alice, {
fileIds: [jpg.id, png.id],
});
});
}, 1000 * 30);
after(async() => {
afterAll(async() => {
await shutdownServer(p);
});
it('ファイルタイプ指定 (jpg)', async(async () => {
it('ファイルタイプ指定 (jpg)', async () => {
const res = await request('/users/notes', {
userId: alice.id,
fileType: ['image/jpeg'],
@ -43,9 +43,9 @@ describe('users/notes', () => {
assert.strictEqual(res.body.length, 2);
assert.strictEqual(res.body.some((note: any) => note.id === jpgNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === jpgPngNote.id), true);
}));
});
it('ファイルタイプ指定 (jpg or png)', async(async () => {
it('ファイルタイプ指定 (jpg or png)', async () => {
const res = await request('/users/notes', {
userId: alice.id,
fileType: ['image/jpeg', 'image/png'],
@ -57,5 +57,5 @@ describe('users/notes', () => {
assert.strictEqual(res.body.some((note: any) => note.id === jpgNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === pngNote.id), true);
assert.strictEqual(res.body.some((note: any) => note.id === jpgPngNote.id), true);
}));
});
});

View file

@ -1,5 +1,5 @@
import * as assert from 'assert';
import { just, nothing } from '../../src/prelude/maybe.js';
import { just, nothing } from '../../src/misc/prelude/maybe.js';
describe('just', () => {
it('has a value', () => {

View file

@ -1,5 +1,5 @@
import * as assert from 'assert';
import { query } from '../../src/prelude/url.js';
import { query } from '../../src/misc/prelude/url.js';
describe('url', () => {
it('query', () => {

View file

@ -2,15 +2,8 @@ process.env.NODE_ENV = 'test';
import * as assert from 'assert';
import rndstr from 'rndstr';
import { initDb } from '../src/db/postgre.js';
import { initTestDb } from './utils.js';
describe('ActivityPub', () => {
before(async () => {
//await initTestDb();
await initDb();
});
describe('Parse minimum object', () => {
const host = 'https://host1.test';
const preferredUsername = `${rndstr('A-Z', 4)}${rndstr('a-z', 4)}`;
@ -35,8 +28,8 @@ describe('ActivityPub', () => {
};
it('Minimum Actor', async () => {
const { MockResolver } = await import('./misc/mock-resolver.js');
const { createPerson } = await import('../src/remote/activitypub/models/person.js');
const { MockResolver } = await import('../misc/mock-resolver.js');
const { createPerson } = await import('../../src/remote/activitypub/models/person.js');
const resolver = new MockResolver();
resolver._register(actor.id, actor);
@ -49,8 +42,8 @@ describe('ActivityPub', () => {
});
it('Minimum Note', async () => {
const { MockResolver } = await import('./misc/mock-resolver.js');
const { createNote } = await import('../src/remote/activitypub/models/note.js');
const { MockResolver } = await import('../misc/mock-resolver.js');
const { createNote } = await import('../../src/remote/activitypub/models/note.js');
const resolver = new MockResolver();
resolver._register(actor.id, actor);
@ -82,8 +75,8 @@ describe('ActivityPub', () => {
};
it('Actor', async () => {
const { MockResolver } = await import('./misc/mock-resolver.js');
const { createPerson } = await import('../src/remote/activitypub/models/person.js');
const { MockResolver } = await import('../misc/mock-resolver.js');
const { createPerson } = await import('../../src/remote/activitypub/models/person.js');
const resolver = new MockResolver();
resolver._register(actor.id, actor);

View file

@ -1,7 +1,7 @@
import * as assert from 'assert';
import httpSignature from 'http-signature';
import { genRsaKeyPair } from '../src/misc/gen-key-pair.js';
import { createSignedPost, createSignedGet } from '../src/remote/activitypub/ap-request.js';
import { genRsaKeyPair } from '../../src/misc/gen-key-pair.js';
import { createSignedPost, createSignedGet } from '../../src/remote/activitypub/ap-request.js';
export const buildParsedSignature = (signingString: string, signature: string, algorithm: string) => {
return {

View file

@ -1,7 +1,7 @@
import * as assert from 'assert';
import { parse } from 'mfm-js';
import { extractMentions } from '../src/misc/extract-mentions.js';
import { extractMentions } from '../../src/misc/extract-mentions.js';
describe('Extract mentions', () => {
it('simple', () => {

View file

@ -1,8 +1,8 @@
import * as assert from 'assert';
import * as mfm from 'mfm-js';
import { toHtml } from '../src/mfm/to-html.js';
import { fromHtml } from '../src/mfm/from-html.js';
import { toHtml } from '../../src/mfm/to-html.js';
import { fromHtml } from '../../src/mfm/from-html.js';
describe('toHtml', () => {
it('br', () => {

View file

@ -32,7 +32,8 @@
],
"lib": [
"esnext"
]
],
"types": ["jest"]
},
"compileOnSave": false,
"include": [

View file

@ -1,16 +1,62 @@
process.env.NODE_ENV = 'test';
import * as assert from 'assert';
import { fileURLToPath } from 'node:url';
import { dirname } from 'node:path';
import { getFileInfo } from '../src/misc/get-file-info.js';
import { async } from './utils.js';
import { ModuleMocker } from 'jest-mock';
import { Test } from '@nestjs/testing';
import { GlobalModule } from '@/GlobalModule.js';
import { FileInfoService } from '@/core/FileInfoService.js';
import { DI } from '@/di-symbols.js';
import { AiService } from '@/core/AiService.js';
import type { TestingModule } from '@nestjs/testing';
import type { jest } from '@jest/globals';
import type { MockFunctionMetadata } from 'jest-mock';
const _filename = fileURLToPath(import.meta.url);
const _dirname = dirname(_filename);
const resources = `${_dirname}/../resources`;
describe('Get file info', () => {
it('Empty file', async (async () => {
const path = `${_dirname}/resources/emptyfile`;
const info = await getFileInfo(path, { skipSensitiveDetection: true }) as any;
const moduleMocker = new ModuleMocker(global);
describe('FileInfoService', () => {
let app: TestingModule;
let fileInfoService: FileInfoService;
beforeAll(async () => {
app = await Test.createTestingModule({
imports: [
GlobalModule,
],
providers: [
AiService,
FileInfoService,
],
})
.useMocker((token) => {
//if (token === AiService) {
// return { };
//}
if (typeof token === 'function') {
const mockMetadata = moduleMocker.getMetadata(token) as MockFunctionMetadata<any, any>;
const Mock = moduleMocker.generateFromMetadata(mockMetadata);
return new Mock();
}
})
.compile();
app.enableShutdownHooks();
fileInfoService = app.get<FileInfoService>(FileInfoService);
});
afterAll(async () => {
await app.close();
});
it('Empty file', async () => {
const path = `${resources}/emptyfile`;
const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
delete info.warnings;
delete info.blurhash;
delete info.sensitive;
@ -26,11 +72,11 @@ describe('Get file info', () => {
height: undefined,
orientation: undefined,
});
}));
});
it('Generic JPEG', async (async () => {
const path = `${_dirname}/resources/Lenna.jpg`;
const info = await getFileInfo(path, { skipSensitiveDetection: true }) as any;
it('Generic JPEG', async () => {
const path = `${resources}/Lenna.jpg`;
const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
delete info.warnings;
delete info.blurhash;
delete info.sensitive;
@ -46,11 +92,11 @@ describe('Get file info', () => {
height: 512,
orientation: undefined,
});
}));
});
it('Generic APNG', async (async () => {
const path = `${_dirname}/resources/anime.png`;
const info = await getFileInfo(path, { skipSensitiveDetection: true }) as any;
it('Generic APNG', async () => {
const path = `${resources}/anime.png`;
const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
delete info.warnings;
delete info.blurhash;
delete info.sensitive;
@ -66,11 +112,11 @@ describe('Get file info', () => {
height: 256,
orientation: undefined,
});
}));
});
it('Generic AGIF', async (async () => {
const path = `${_dirname}/resources/anime.gif`;
const info = await getFileInfo(path, { skipSensitiveDetection: true }) as any;
it('Generic AGIF', async () => {
const path = `${resources}/anime.gif`;
const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
delete info.warnings;
delete info.blurhash;
delete info.sensitive;
@ -86,11 +132,11 @@ describe('Get file info', () => {
height: 256,
orientation: undefined,
});
}));
});
it('PNG with alpha', async (async () => {
const path = `${_dirname}/resources/with-alpha.png`;
const info = await getFileInfo(path, { skipSensitiveDetection: true }) as any;
it('PNG with alpha', async () => {
const path = `${resources}/with-alpha.png`;
const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
delete info.warnings;
delete info.blurhash;
delete info.sensitive;
@ -106,11 +152,11 @@ describe('Get file info', () => {
height: 256,
orientation: undefined,
});
}));
});
it('Generic SVG', async (async () => {
const path = `${_dirname}/resources/image.svg`;
const info = await getFileInfo(path, { skipSensitiveDetection: true }) as any;
it('Generic SVG', async () => {
const path = `${resources}/image.svg`;
const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
delete info.warnings;
delete info.blurhash;
delete info.sensitive;
@ -126,12 +172,12 @@ describe('Get file info', () => {
height: 256,
orientation: undefined,
});
}));
});
it('SVG with XML definition', async (async () => {
it('SVG with XML definition', async () => {
// https://github.com/misskey-dev/misskey/issues/4413
const path = `${_dirname}/resources/with-xml-def.svg`;
const info = await getFileInfo(path, { skipSensitiveDetection: true }) as any;
const path = `${resources}/with-xml-def.svg`;
const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
delete info.warnings;
delete info.blurhash;
delete info.sensitive;
@ -147,11 +193,11 @@ describe('Get file info', () => {
height: 256,
orientation: undefined,
});
}));
});
it('Dimension limit', async (async () => {
const path = `${_dirname}/resources/25000x25000.png`;
const info = await getFileInfo(path, { skipSensitiveDetection: true }) as any;
it('Dimension limit', async () => {
const path = `${resources}/25000x25000.png`;
const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
delete info.warnings;
delete info.blurhash;
delete info.sensitive;
@ -167,11 +213,11 @@ describe('Get file info', () => {
height: 25000,
orientation: undefined,
});
}));
});
it('Rotate JPEG', async (async () => {
const path = `${_dirname}/resources/rotate.jpg`;
const info = await getFileInfo(path, { skipSensitiveDetection: true }) as any;
it('Rotate JPEG', async () => {
const path = `${resources}/rotate.jpg`;
const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
delete info.warnings;
delete info.blurhash;
delete info.sensitive;
@ -187,5 +233,5 @@ describe('Get file info', () => {
height: 256,
orientation: 8,
});
}));
});
});

View file

@ -0,0 +1,96 @@
process.env.NODE_ENV = 'test';
import { jest } from '@jest/globals';
import { ModuleMocker } from 'jest-mock';
import { Test } from '@nestjs/testing';
import { GlobalModule } from '@/GlobalModule.js';
import { RelayService } from '@/core/RelayService.js';
import { ApRendererService } from '@/core/remote/activitypub/ApRendererService.js';
import { CreateSystemUserService } from '@/core/CreateSystemUserService.js';
import { QueueService } from '@/core/QueueService.js';
import { IdService } from '@/core/IdService.js';
import type { RelaysRepository } from '@/models/index.js';
import { DI } from '@/di-symbols.js';
import type { TestingModule } from '@nestjs/testing';
import type { MockFunctionMetadata } from 'jest-mock';
const moduleMocker = new ModuleMocker(global);
describe('RelayService', () => {
let app: TestingModule;
let relayService: RelayService;
let queueService: jest.Mocked<QueueService>;
let relaysRepository: RelaysRepository;
beforeAll(async () => {
app = await Test.createTestingModule({
imports: [
GlobalModule,
],
providers: [
IdService,
CreateSystemUserService,
ApRendererService,
RelayService,
],
})
.useMocker((token) => {
if (token === QueueService) {
return { deliver: jest.fn() };
}
if (typeof token === 'function') {
const mockMetadata = moduleMocker.getMetadata(token) as MockFunctionMetadata<any, any>;
const Mock = moduleMocker.generateFromMetadata(mockMetadata);
return new Mock();
}
})
.compile();
app.enableShutdownHooks();
relayService = app.get<RelayService>(RelayService);
queueService = app.get<QueueService>(QueueService) as jest.Mocked<QueueService>;
relaysRepository = app.get<RelaysRepository>(DI.relaysRepository);
});
afterAll(async () => {
await app.close();
});
it('addRelay', async () => {
const result = await relayService.addRelay('https://example.com');
expect(result.inbox).toBe('https://example.com');
expect(result.status).toBe('requesting');
expect(queueService.deliver).toHaveBeenCalled();
expect(queueService.deliver.mock.lastCall![1].type).toBe('Follow');
expect(queueService.deliver.mock.lastCall![2]).toBe('https://example.com');
//expect(queueService.deliver.mock.lastCall![0].username).toBe('relay.actor');
});
it('listRelay', async () => {
const result = await relayService.listRelay();
expect(result.length).toBe(1);
expect(result[0].inbox).toBe('https://example.com');
expect(result[0].status).toBe('requesting');
});
it('removeRelay: succ', async () => {
await relayService.removeRelay('https://example.com');
expect(queueService.deliver).toHaveBeenCalled();
expect(queueService.deliver.mock.lastCall![1].type).toBe('Undo');
expect(queueService.deliver.mock.lastCall![1].object.type).toBe('Follow');
expect(queueService.deliver.mock.lastCall![2]).toBe('https://example.com');
//expect(queueService.deliver.mock.lastCall![0].username).toBe('relay.actor');
const list = await relayService.listRelay();
expect(list.length).toBe(0);
});
it('removeRelay: fail', async () => {
await expect(relayService.removeRelay('https://x.example.com'))
.rejects.toThrow('relay not found');
});
});

View file

@ -1,14 +1,28 @@
process.env.NODE_ENV = 'test';
import * as assert from 'assert';
import { jest } from '@jest/globals';
import * as lolex from '@sinonjs/fake-timers';
import TestChart from '../src/services/chart/charts/test.js';
import TestGroupedChart from '../src/services/chart/charts/test-grouped.js';
import TestUniqueChart from '../src/services/chart/charts/test-unique.js';
import TestIntersectionChart from '../src/services/chart/charts/test-intersection.js';
import { initDb } from '../src/db/postgre.js';
import { DataSource } from 'typeorm';
import TestChart from '@/core/chart/charts/test.js';
import TestGroupedChart from '@/core/chart/charts/test-grouped.js';
import TestUniqueChart from '@/core/chart/charts/test-unique.js';
import TestIntersectionChart from '@/core/chart/charts/test-intersection.js';
import { entity as TestChartEntity } from '@/core/chart/charts/entities/test.js';
import { entity as TestGroupedChartEntity } from '@/core/chart/charts/entities/test-grouped.js';
import { entity as TestUniqueChartEntity } from '@/core/chart/charts/entities/test-unique.js';
import { entity as TestIntersectionChartEntity } from '@/core/chart/charts/entities/test-intersection.js';
import { loadConfig } from '@/config.js';
import type { AppLockService } from '@/core/AppLockService';
describe('Chart', () => {
const config = loadConfig();
const appLockService = {
getChartInsertLock: jest.fn().mockImplementation(() => Promise.resolve(() => {})),
} as unknown as jest.Mocked<AppLockService>;
let db: DataSource | undefined;
let testChart: TestChart;
let testGroupedChart: TestGroupedChart;
let testUniqueChart: TestUniqueChart;
@ -16,12 +30,37 @@ describe('Chart', () => {
let clock: lolex.InstalledClock;
beforeEach(async () => {
await initDb(true);
if (db) db.destroy();
testChart = new TestChart();
testGroupedChart = new TestGroupedChart();
testUniqueChart = new TestUniqueChart();
testIntersectionChart = new TestIntersectionChart();
db = new DataSource({
type: 'postgres',
host: config.db.host,
port: config.db.port,
username: config.db.user,
password: config.db.pass,
database: config.db.db,
extra: {
statement_timeout: 1000 * 10,
...config.db.extra,
},
synchronize: true,
dropSchema: true,
maxQueryExecutionTime: 300,
entities: [
TestChartEntity.hour, TestChartEntity.day,
TestGroupedChartEntity.hour, TestGroupedChartEntity.day,
TestUniqueChartEntity.hour, TestUniqueChartEntity.day,
TestIntersectionChartEntity.hour, TestIntersectionChartEntity.day,
],
migrations: ['../../migration/*.js'],
});
await db.initialize();
testChart = new TestChart(db, appLockService);
testGroupedChart = new TestGroupedChart(db, appLockService);
testUniqueChart = new TestUniqueChart(db, appLockService);
testIntersectionChart = new TestIntersectionChart(db, appLockService);
clock = lolex.install({
now: new Date(Date.UTC(2000, 0, 1, 0, 0, 0)),
@ -33,6 +72,10 @@ describe('Chart', () => {
clock.uninstall();
});
afterAll(async () => {
if (db) await db.destroy();
});
it('Can updates', async () => {
await testChart.increment();
await testChart.save();

View file

@ -6,13 +6,13 @@ import * as childProcess from 'child_process';
import * as http from 'node:http';
import { SIGKILL } from 'constants';
import WebSocket from 'ws';
import * as misskey from 'misskey-js';
import fetch from 'node-fetch';
import FormData from 'form-data';
import { DataSource } from 'typeorm';
import got, { RequestError } from 'got';
import loadConfig from '../src/config/load.js';
import { entities } from '../src/db/postgre.js';
import got from 'got';
import { entities } from '../src/postgre.js';
import type * as misskey from 'misskey-js';
const _filename = fileURLToPath(import.meta.url);
const _dirname = dirname(_filename);
@ -20,56 +20,53 @@ const _dirname = dirname(_filename);
const config = loadConfig();
export const port = config.port;
export const async = (fn: Function) => (done: Function) => {
fn().then(() => {
done();
}, (err: Error) => {
done(err);
});
};
export const api = async (endpoint: string, params: any, me?: any) => {
endpoint = endpoint.replace(/^\//, '');
const auth = me ? {
i: me.token
i: me.token,
} : {};
const res = await got<string>(`http://localhost:${port}/api/${endpoint}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(Object.assign(auth, params)),
retry: {
limit: 0,
},
hooks: {
beforeError: [
error => {
const { response } = error;
if (response && response.body) console.warn(response.body);
return error;
}
]
},
});
try {
const res = await got<string>(`http://localhost:${port}/api/${endpoint}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(Object.assign(auth, params)),
retry: {
limit: 0,
},
});
const status = res.statusCode;
const body = res.statusCode !== 204 ? await JSON.parse(res.body) : null;
const status = res.statusCode;
const body = res.statusCode !== 204 ? await JSON.parse(res.body) : null;
return {
status,
body
};
return {
status,
body,
};
} catch (err: unknown) {
if (err instanceof RequestError && err.response) {
const status = err.response.statusCode;
const body = await JSON.parse(err.response.body as string);
return {
status,
body,
};
} else {
throw err;
}
}
};
export const request = async (endpoint: string, params: any, me?: any): Promise<{ body: any, status: number }> => {
export const request = async (path: string, params: any, me?: any): Promise<{ body: any, status: number }> => {
const auth = me ? {
i: me.token,
} : {};
const res = await fetch(`http://localhost:${port}/api${endpoint}`, {
const res = await fetch(`http://localhost:${port}/${path}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@ -78,7 +75,7 @@ export const request = async (endpoint: string, params: any, me?: any): Promise<
});
const status = res.status;
const body = res.status !== 204 ? await res.json().catch() : null;
const body = res.status === 200 ? await res.json().catch() : null;
return {
body, status,
@ -141,19 +138,21 @@ export const uploadFile = async (user: any, _path?: string): Promise<any> => {
export const uploadUrl = async (user: any, url: string) => {
let file: any;
const marker = Math.random().toString();
const ws = await connectStream(user, 'main', (msg) => {
if (msg.type === 'driveFileCreated') {
file = msg.body;
if (msg.type === 'urlUploadFinished' && msg.body.marker === marker) {
file = msg.body.file;
}
});
await api('drive/files/upload-from-url', {
url,
marker,
force: true,
}, user);
await sleep(5000);
await sleep(7000);
ws.close();
return file;
@ -217,7 +216,7 @@ export const waitFire = async (user: any, channel: string, trgr: () => any, cond
if (timer) clearTimeout(timer);
rej(e);
}
})
});
};
export const simpleGet = async (path: string, accept = '*/*'): Promise<{ status?: number, type?: string, location?: string }> => {
@ -268,7 +267,7 @@ export async function initTestDb(justBorrow = false, initEntities?: any[]) {
database: config.db.db,
synchronize: true && !justBorrow,
dropSchema: true && !justBorrow,
entities: initEntities || entities,
entities: initEntities ?? entities,
});
await db.initialize();
@ -299,7 +298,8 @@ export function startServer(timeout = 60 * 1000): Promise<childProcess.ChildProc
});
}
export function shutdownServer(p: childProcess.ChildProcess, timeout = 20 * 1000) {
export function shutdownServer(p: childProcess.ChildProcess | undefined, timeout = 20 * 1000) {
if (p == null) return Promise.resolve('nop');
return new Promise((res, rej) => {
const t = setTimeout(() => {
p.kill(SIGKILL);