バグがある(かつすぐに修正できそうにない) & まだレビュー途中で意図せずマージされたため
This commit is contained in:
syuilo 2024-07-20 21:33:20 +09:00
parent efb04293bb
commit 337b42bcb1
52 changed files with 691 additions and 1099 deletions

View file

@ -378,7 +378,7 @@ describe('Timelines', () => {
assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true);
assert.strictEqual(res.body.some(note => note.id === carolNote1.id), false);
assert.strictEqual(res.body.some(note => note.id === carolNote2.id), false);
});
}, 1000 * 10);
test.concurrent('フォローしているユーザーのチャンネル投稿が含まれない', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
@ -672,7 +672,7 @@ describe('Timelines', () => {
assert.strictEqual(res.body.some(note => note.id === bobNote1.id), false);
assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true);
});
}, 1000 * 10);
});
describe('Social TL', () => {
@ -812,7 +812,7 @@ describe('Timelines', () => {
assert.strictEqual(res.body.some(note => note.id === bobNote1.id), false);
assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true);
});
}, 1000 * 10);
});
describe('User List TL', () => {
@ -1025,7 +1025,7 @@ describe('Timelines', () => {
assert.strictEqual(res.body.some(note => note.id === bobNote1.id), false);
assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true);
});
}, 1000 * 10);
test.concurrent('リスインしているユーザーの自身宛ての visibility: specified なノートが含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);
@ -1184,7 +1184,7 @@ describe('Timelines', () => {
assert.strictEqual(res.body.some(note => note.id === bobNote1.id), false);
assert.strictEqual(res.body.some(note => note.id === bobNote2.id), true);
});
}, 1000 * 10);
test.concurrent('[withChannelNotes: true] チャンネル投稿が含まれる', async () => {
const [alice, bob] = await Promise.all([signup(), signup()]);

View file

@ -14,7 +14,6 @@ import type { InstanceActorService } from '@/core/InstanceActorService.js';
import type { LoggerService } from '@/core/LoggerService.js';
import type { MetaService } from '@/core/MetaService.js';
import type { UtilityService } from '@/core/UtilityService.js';
import type { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
import { bindThis } from '@/decorators.js';
import type {
FollowRequestsRepository,
@ -48,7 +47,6 @@ export class MockResolver extends Resolver {
{} as HttpRequestService,
{} as ApRendererService,
{} as ApDbResolverService,
{} as FederatedInstanceService,
loggerService,
);
}

View file

@ -75,61 +75,62 @@ describe('FetchInstanceMetadataService', () => {
test('Lock and update', async () => {
redisClient.set = mockRedis();
const now = Date.now();
federatedInstanceService.fetch.mockResolvedValue({ infoUpdatedAt: new Date(now - 10 * 1000 * 60 * 60 * 24) } as any);
federatedInstanceService.fetch.mockResolvedValue({ infoUpdatedAt: { getTime: () => { return now - 10 * 1000 * 60 * 60 * 24; } } } as any);
httpRequestService.getJson.mockImplementation(() => { throw Error(); });
const tryLockSpy = jest.spyOn(fetchInstanceMetadataService, 'tryLock');
const unlockSpy = jest.spyOn(fetchInstanceMetadataService, 'unlock');
await fetchInstanceMetadataService.fetchInstanceMetadata({ host: 'example.com' } as any);
expect(federatedInstanceService.fetch).toHaveBeenCalledTimes(1);
expect(tryLockSpy).toHaveBeenCalledTimes(1);
expect(unlockSpy).toHaveBeenCalledTimes(1);
expect(federatedInstanceService.fetch).toHaveBeenCalledTimes(1);
expect(httpRequestService.getJson).toHaveBeenCalled();
});
test('Don\'t lock and update if recently updated', async () => {
test('Lock and don\'t update', async () => {
redisClient.set = mockRedis();
federatedInstanceService.fetch.mockResolvedValue({ infoUpdatedAt: new Date() } as any);
const now = Date.now();
federatedInstanceService.fetch.mockResolvedValue({ infoUpdatedAt: { getTime: () => now } } as any);
httpRequestService.getJson.mockImplementation(() => { throw Error(); });
const tryLockSpy = jest.spyOn(fetchInstanceMetadataService, 'tryLock');
const unlockSpy = jest.spyOn(fetchInstanceMetadataService, 'unlock');
await fetchInstanceMetadataService.fetchInstanceMetadata({ host: 'example.com' } as any);
expect(tryLockSpy).toHaveBeenCalledTimes(1);
expect(unlockSpy).toHaveBeenCalledTimes(1);
expect(federatedInstanceService.fetch).toHaveBeenCalledTimes(1);
expect(tryLockSpy).toHaveBeenCalledTimes(0);
expect(unlockSpy).toHaveBeenCalledTimes(0);
expect(httpRequestService.getJson).toHaveBeenCalledTimes(0);
});
test('Do nothing when lock not acquired', async () => {
redisClient.set = mockRedis();
const now = Date.now();
federatedInstanceService.fetch.mockResolvedValue({ infoUpdatedAt: new Date(now - 10 * 1000 * 60 * 60 * 24) } as any);
federatedInstanceService.fetch.mockResolvedValue({ infoUpdatedAt: { getTime: () => now - 10 * 1000 * 60 * 60 * 24 } } as any);
httpRequestService.getJson.mockImplementation(() => { throw Error(); });
await fetchInstanceMetadataService.tryLock('example.com');
const tryLockSpy = jest.spyOn(fetchInstanceMetadataService, 'tryLock');
const unlockSpy = jest.spyOn(fetchInstanceMetadataService, 'unlock');
await fetchInstanceMetadataService.fetchInstanceMetadata({ host: 'example.com' } as any);
expect(federatedInstanceService.fetch).toHaveBeenCalledTimes(1);
expect(tryLockSpy).toHaveBeenCalledTimes(1);
expect(unlockSpy).toHaveBeenCalledTimes(0);
expect(federatedInstanceService.fetch).toHaveBeenCalledTimes(0);
expect(httpRequestService.getJson).toHaveBeenCalledTimes(0);
});
test('Do when forced', async () => {
test('Do when lock not acquired but forced', async () => {
redisClient.set = mockRedis();
const now = Date.now();
federatedInstanceService.fetch.mockResolvedValue({ infoUpdatedAt: new Date(now - 10 * 1000 * 60 * 60 * 24) } as any);
federatedInstanceService.fetch.mockResolvedValue({ infoUpdatedAt: { getTime: () => now - 10 * 1000 * 60 * 60 * 24 } } as any);
httpRequestService.getJson.mockImplementation(() => { throw Error(); });
await fetchInstanceMetadataService.tryLock('example.com');
const tryLockSpy = jest.spyOn(fetchInstanceMetadataService, 'tryLock');
const unlockSpy = jest.spyOn(fetchInstanceMetadataService, 'unlock');
await fetchInstanceMetadataService.fetchInstanceMetadata({ host: 'example.com' } as any, true);
expect(federatedInstanceService.fetch).toHaveBeenCalledTimes(0);
expect(tryLockSpy).toHaveBeenCalledTimes(0);
expect(unlockSpy).toHaveBeenCalledTimes(1);
expect(federatedInstanceService.fetch).toHaveBeenCalledTimes(0);
expect(httpRequestService.getJson).toHaveBeenCalled();
});
});

View file

@ -4,8 +4,10 @@
*/
import * as assert from 'assert';
import { verifyDraftSignature, parseRequestSignature, genEd25519KeyPair, genRsaKeyPair, importPrivateKey } from '@misskey-dev/node-http-message-signatures';
import { createSignedGet, createSignedPost } from '@/core/activitypub/ApRequestService.js';
import httpSignature from '@peertube/http-signature';
import { genRsaKeyPair } from '@/misc/gen-key-pair.js';
import { ApRequestCreator } from '@/core/activitypub/ApRequestService.js';
export const buildParsedSignature = (signingString: string, signature: string, algorithm: string) => {
return {
@ -22,68 +24,38 @@ export const buildParsedSignature = (signingString: string, signature: string, a
};
};
async function getKeyPair(level: string) {
if (level === '00') {
return await genRsaKeyPair();
} else if (level === '01') {
return await genEd25519KeyPair();
}
throw new Error('Invalid level');
}
describe('ap-request', () => {
test('createSignedPost with verify', async () => {
const keypair = await genRsaKeyPair();
const key = { keyId: 'x', 'privateKeyPem': keypair.privateKey };
const url = 'https://example.com/inbox';
const activity = { a: 1 };
const body = JSON.stringify(activity);
const headers = {
'User-Agent': 'UA',
};
describe('ap-request post', () => {
const url = 'https://example.com/inbox';
const activity = { a: 1 };
const body = JSON.stringify(activity);
const headers = {
'User-Agent': 'UA',
};
const req = ApRequestCreator.createSignedPost({ key, url, body, additionalHeaders: headers });
describe.each(['00', '01'])('createSignedPost with verify', (level) => {
test('pem', async () => {
const keypair = await getKeyPair(level);
const key = { keyId: 'x', 'privateKeyPem': keypair.privateKey };
const parsed = buildParsedSignature(req.signingString, req.signature, 'rsa-sha256');
const req = await createSignedPost({ level, key, url, body, additionalHeaders: headers });
const result = httpSignature.verifySignature(parsed, keypair.publicKey);
assert.deepStrictEqual(result, true);
});
const parsed = parseRequestSignature(req.request);
expect(parsed.version).toBe('draft');
expect(Array.isArray(parsed.value)).toBe(false);
const verify = await verifyDraftSignature(parsed.value as any, keypair.publicKey);
assert.deepStrictEqual(verify, true);
});
test('imported', async () => {
const keypair = await getKeyPair(level);
const key = { keyId: 'x', 'privateKey': await importPrivateKey(keypair.privateKey) };
test('createSignedGet with verify', async () => {
const keypair = await genRsaKeyPair();
const key = { keyId: 'x', 'privateKeyPem': keypair.privateKey };
const url = 'https://example.com/outbox';
const headers = {
'User-Agent': 'UA',
};
const req = await createSignedPost({ level, key, url, body, additionalHeaders: headers });
const req = ApRequestCreator.createSignedGet({ key, url, additionalHeaders: headers });
const parsed = parseRequestSignature(req.request);
expect(parsed.version).toBe('draft');
expect(Array.isArray(parsed.value)).toBe(false);
const verify = await verifyDraftSignature(parsed.value as any, keypair.publicKey);
assert.deepStrictEqual(verify, true);
});
});
});
describe('ap-request get', () => {
describe.each(['00', '01'])('createSignedGet with verify', (level) => {
test('pass', async () => {
const keypair = await getKeyPair(level);
const key = { keyId: 'x', 'privateKeyPem': keypair.privateKey };
const url = 'https://example.com/outbox';
const headers = {
'User-Agent': 'UA',
};
const req = await createSignedGet({ level, key, url, additionalHeaders: headers });
const parsed = parseRequestSignature(req.request);
expect(parsed.version).toBe('draft');
expect(Array.isArray(parsed.value)).toBe(false);
const verify = await verifyDraftSignature(parsed.value as any, keypair.publicKey);
assert.deepStrictEqual(verify, true);
});
const parsed = buildParsedSignature(req.signingString, req.signature, 'rsa-sha256');
const result = httpSignature.verifySignature(parsed, keypair.publicKey);
assert.deepStrictEqual(result, true);
});
});