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

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

@ -0,0 +1,237 @@
process.env.NODE_ENV = 'test';
import * as assert from 'assert';
import { fileURLToPath } from 'node:url';
import { dirname } from 'node:path';
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`;
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;
delete info.porn;
assert.deepStrictEqual(info, {
size: 0,
md5: 'd41d8cd98f00b204e9800998ecf8427e',
type: {
mime: 'application/octet-stream',
ext: null,
},
width: undefined,
height: undefined,
orientation: undefined,
});
});
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;
delete info.porn;
assert.deepStrictEqual(info, {
size: 25360,
md5: '091b3f259662aa31e2ffef4519951168',
type: {
mime: 'image/jpeg',
ext: 'jpg',
},
width: 512,
height: 512,
orientation: undefined,
});
});
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;
delete info.porn;
assert.deepStrictEqual(info, {
size: 1868,
md5: '08189c607bea3b952704676bb3c979e0',
type: {
mime: 'image/apng',
ext: 'apng',
},
width: 256,
height: 256,
orientation: undefined,
});
});
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;
delete info.porn;
assert.deepStrictEqual(info, {
size: 2248,
md5: '32c47a11555675d9267aee1a86571e7e',
type: {
mime: 'image/gif',
ext: 'gif',
},
width: 256,
height: 256,
orientation: undefined,
});
});
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;
delete info.porn;
assert.deepStrictEqual(info, {
size: 3772,
md5: 'f73535c3e1e27508885b69b10cf6e991',
type: {
mime: 'image/png',
ext: 'png',
},
width: 256,
height: 256,
orientation: undefined,
});
});
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;
delete info.porn;
assert.deepStrictEqual(info, {
size: 505,
md5: 'b6f52b4b021e7b92cdd04509c7267965',
type: {
mime: 'image/svg+xml',
ext: 'svg',
},
width: 256,
height: 256,
orientation: undefined,
});
});
it('SVG with XML definition', async () => {
// https://github.com/misskey-dev/misskey/issues/4413
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;
delete info.porn;
assert.deepStrictEqual(info, {
size: 544,
md5: '4b7a346cde9ccbeb267e812567e33397',
type: {
mime: 'image/svg+xml',
ext: 'svg',
},
width: 256,
height: 256,
orientation: undefined,
});
});
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;
delete info.porn;
assert.deepStrictEqual(info, {
size: 75933,
md5: '268c5dde99e17cf8fe09f1ab3f97df56',
type: {
mime: 'application/octet-stream', // do not treat as image
ext: null,
},
width: 25000,
height: 25000,
orientation: undefined,
});
});
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;
delete info.porn;
assert.deepStrictEqual(info, {
size: 12624,
md5: '68d5b2d8d1d1acbbce99203e3ec3857e',
type: {
mime: 'image/jpeg',
ext: 'jpg',
},
width: 512,
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

@ -0,0 +1,574 @@
process.env.NODE_ENV = 'test';
import * as assert from 'assert';
import { jest } from '@jest/globals';
import * as lolex from '@sinonjs/fake-timers';
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;
let testIntersectionChart: TestIntersectionChart;
let clock: lolex.InstalledClock;
beforeEach(async () => {
if (db) db.destroy();
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)),
shouldClearNativeTimers: true,
});
});
afterEach(() => {
clock.uninstall();
});
afterAll(async () => {
if (db) await db.destroy();
});
it('Can updates', async () => {
await testChart.increment();
await testChart.save();
const chartHours = await testChart.getChart('hour', 3, null);
const chartDays = await testChart.getChart('day', 3, null);
assert.deepStrictEqual(chartHours, {
foo: {
dec: [0, 0, 0],
inc: [1, 0, 0],
total: [1, 0, 0],
},
});
assert.deepStrictEqual(chartDays, {
foo: {
dec: [0, 0, 0],
inc: [1, 0, 0],
total: [1, 0, 0],
},
});
});
it('Can updates (dec)', async () => {
await testChart.decrement();
await testChart.save();
const chartHours = await testChart.getChart('hour', 3, null);
const chartDays = await testChart.getChart('day', 3, null);
assert.deepStrictEqual(chartHours, {
foo: {
dec: [1, 0, 0],
inc: [0, 0, 0],
total: [-1, 0, 0],
},
});
assert.deepStrictEqual(chartDays, {
foo: {
dec: [1, 0, 0],
inc: [0, 0, 0],
total: [-1, 0, 0],
},
});
});
it('Empty chart', async () => {
const chartHours = await testChart.getChart('hour', 3, null);
const chartDays = await testChart.getChart('day', 3, null);
assert.deepStrictEqual(chartHours, {
foo: {
dec: [0, 0, 0],
inc: [0, 0, 0],
total: [0, 0, 0],
},
});
assert.deepStrictEqual(chartDays, {
foo: {
dec: [0, 0, 0],
inc: [0, 0, 0],
total: [0, 0, 0],
},
});
});
it('Can updates at multiple times at same time', async () => {
await testChart.increment();
await testChart.increment();
await testChart.increment();
await testChart.save();
const chartHours = await testChart.getChart('hour', 3, null);
const chartDays = await testChart.getChart('day', 3, null);
assert.deepStrictEqual(chartHours, {
foo: {
dec: [0, 0, 0],
inc: [3, 0, 0],
total: [3, 0, 0],
},
});
assert.deepStrictEqual(chartDays, {
foo: {
dec: [0, 0, 0],
inc: [3, 0, 0],
total: [3, 0, 0],
},
});
});
it('複数回saveされてもデータの更新は一度だけ', async () => {
await testChart.increment();
await testChart.save();
await testChart.save();
await testChart.save();
const chartHours = await testChart.getChart('hour', 3, null);
const chartDays = await testChart.getChart('day', 3, null);
assert.deepStrictEqual(chartHours, {
foo: {
dec: [0, 0, 0],
inc: [1, 0, 0],
total: [1, 0, 0],
},
});
assert.deepStrictEqual(chartDays, {
foo: {
dec: [0, 0, 0],
inc: [1, 0, 0],
total: [1, 0, 0],
},
});
});
it('Can updates at different times', async () => {
await testChart.increment();
await testChart.save();
clock.tick('01:00:00');
await testChart.increment();
await testChart.save();
const chartHours = await testChart.getChart('hour', 3, null);
const chartDays = await testChart.getChart('day', 3, null);
assert.deepStrictEqual(chartHours, {
foo: {
dec: [0, 0, 0],
inc: [1, 1, 0],
total: [2, 1, 0],
},
});
assert.deepStrictEqual(chartDays, {
foo: {
dec: [0, 0, 0],
inc: [2, 0, 0],
total: [2, 0, 0],
},
});
});
// 仕様上はこうなってほしいけど、実装は難しそうなのでskip
/*
it('Can updates at different times without save', async () => {
await testChart.increment();
clock.tick('01:00:00');
await testChart.increment();
await testChart.save();
const chartHours = await testChart.getChart('hour', 3, null);
const chartDays = await testChart.getChart('day', 3, null);
assert.deepStrictEqual(chartHours, {
foo: {
dec: [0, 0, 0],
inc: [1, 1, 0],
total: [2, 1, 0]
},
});
assert.deepStrictEqual(chartDays, {
foo: {
dec: [0, 0, 0],
inc: [2, 0, 0],
total: [2, 0, 0]
},
});
});
*/
it('Can padding', async () => {
await testChart.increment();
await testChart.save();
clock.tick('02:00:00');
await testChart.increment();
await testChart.save();
const chartHours = await testChart.getChart('hour', 3, null);
const chartDays = await testChart.getChart('day', 3, null);
assert.deepStrictEqual(chartHours, {
foo: {
dec: [0, 0, 0],
inc: [1, 0, 1],
total: [2, 1, 1],
},
});
assert.deepStrictEqual(chartDays, {
foo: {
dec: [0, 0, 0],
inc: [2, 0, 0],
total: [2, 0, 0],
},
});
});
// 要求された範囲にログがひとつもない場合でもパディングできる
it('Can padding from past range', async () => {
await testChart.increment();
await testChart.save();
clock.tick('05:00:00');
const chartHours = await testChart.getChart('hour', 3, null);
const chartDays = await testChart.getChart('day', 3, null);
assert.deepStrictEqual(chartHours, {
foo: {
dec: [0, 0, 0],
inc: [0, 0, 0],
total: [1, 1, 1],
},
});
assert.deepStrictEqual(chartDays, {
foo: {
dec: [0, 0, 0],
inc: [1, 0, 0],
total: [1, 0, 0],
},
});
});
// 要求された範囲の最も古い箇所に位置するログが存在しない場合でもパディングできる
// Issue #3190
it('Can padding from past range 2', async () => {
await testChart.increment();
await testChart.save();
clock.tick('05:00:00');
await testChart.increment();
await testChart.save();
const chartHours = await testChart.getChart('hour', 3, null);
const chartDays = await testChart.getChart('day', 3, null);
assert.deepStrictEqual(chartHours, {
foo: {
dec: [0, 0, 0],
inc: [1, 0, 0],
total: [2, 1, 1],
},
});
assert.deepStrictEqual(chartDays, {
foo: {
dec: [0, 0, 0],
inc: [2, 0, 0],
total: [2, 0, 0],
},
});
});
it('Can specify offset', async () => {
await testChart.increment();
await testChart.save();
clock.tick('01:00:00');
await testChart.increment();
await testChart.save();
const chartHours = await testChart.getChart('hour', 3, new Date(Date.UTC(2000, 0, 1, 0, 0, 0)));
const chartDays = await testChart.getChart('day', 3, new Date(Date.UTC(2000, 0, 1, 0, 0, 0)));
assert.deepStrictEqual(chartHours, {
foo: {
dec: [0, 0, 0],
inc: [1, 0, 0],
total: [1, 0, 0],
},
});
assert.deepStrictEqual(chartDays, {
foo: {
dec: [0, 0, 0],
inc: [2, 0, 0],
total: [2, 0, 0],
},
});
});
it('Can specify offset (floor time)', async () => {
clock.tick('00:30:00');
await testChart.increment();
await testChart.save();
clock.tick('01:30:00');
await testChart.increment();
await testChart.save();
const chartHours = await testChart.getChart('hour', 3, new Date(Date.UTC(2000, 0, 1, 0, 0, 0)));
const chartDays = await testChart.getChart('day', 3, new Date(Date.UTC(2000, 0, 1, 0, 0, 0)));
assert.deepStrictEqual(chartHours, {
foo: {
dec: [0, 0, 0],
inc: [1, 0, 0],
total: [1, 0, 0],
},
});
assert.deepStrictEqual(chartDays, {
foo: {
dec: [0, 0, 0],
inc: [2, 0, 0],
total: [2, 0, 0],
},
});
});
describe('Grouped', () => {
it('Can updates', async () => {
await testGroupedChart.increment('alice');
await testGroupedChart.save();
const aliceChartHours = await testGroupedChart.getChart('hour', 3, null, 'alice');
const aliceChartDays = await testGroupedChart.getChart('day', 3, null, 'alice');
const bobChartHours = await testGroupedChart.getChart('hour', 3, null, 'bob');
const bobChartDays = await testGroupedChart.getChart('day', 3, null, 'bob');
assert.deepStrictEqual(aliceChartHours, {
foo: {
dec: [0, 0, 0],
inc: [1, 0, 0],
total: [1, 0, 0],
},
});
assert.deepStrictEqual(aliceChartDays, {
foo: {
dec: [0, 0, 0],
inc: [1, 0, 0],
total: [1, 0, 0],
},
});
assert.deepStrictEqual(bobChartHours, {
foo: {
dec: [0, 0, 0],
inc: [0, 0, 0],
total: [0, 0, 0],
},
});
assert.deepStrictEqual(bobChartDays, {
foo: {
dec: [0, 0, 0],
inc: [0, 0, 0],
total: [0, 0, 0],
},
});
});
});
describe('Unique increment', () => {
it('Can updates', async () => {
await testUniqueChart.uniqueIncrement('alice');
await testUniqueChart.uniqueIncrement('alice');
await testUniqueChart.uniqueIncrement('bob');
await testUniqueChart.save();
const chartHours = await testUniqueChart.getChart('hour', 3, null);
const chartDays = await testUniqueChart.getChart('day', 3, null);
assert.deepStrictEqual(chartHours, {
foo: [2, 0, 0],
});
assert.deepStrictEqual(chartDays, {
foo: [2, 0, 0],
});
});
describe('Intersection', () => {
it('条件が満たされていない場合はカウントされない', async () => {
await testIntersectionChart.addA('alice');
await testIntersectionChart.addA('bob');
await testIntersectionChart.addB('carol');
await testIntersectionChart.save();
const chartHours = await testIntersectionChart.getChart('hour', 3, null);
const chartDays = await testIntersectionChart.getChart('day', 3, null);
assert.deepStrictEqual(chartHours, {
a: [2, 0, 0],
b: [1, 0, 0],
aAndB: [0, 0, 0],
});
assert.deepStrictEqual(chartDays, {
a: [2, 0, 0],
b: [1, 0, 0],
aAndB: [0, 0, 0],
});
});
it('条件が満たされている場合にカウントされる', async () => {
await testIntersectionChart.addA('alice');
await testIntersectionChart.addA('bob');
await testIntersectionChart.addB('carol');
await testIntersectionChart.addB('alice');
await testIntersectionChart.save();
const chartHours = await testIntersectionChart.getChart('hour', 3, null);
const chartDays = await testIntersectionChart.getChart('day', 3, null);
assert.deepStrictEqual(chartHours, {
a: [2, 0, 0],
b: [2, 0, 0],
aAndB: [1, 0, 0],
});
assert.deepStrictEqual(chartDays, {
a: [2, 0, 0],
b: [2, 0, 0],
aAndB: [1, 0, 0],
});
});
});
});
describe('Resync', () => {
it('Can resync', async () => {
testChart.total = 1;
await testChart.resync();
const chartHours = await testChart.getChart('hour', 3, null);
const chartDays = await testChart.getChart('day', 3, null);
assert.deepStrictEqual(chartHours, {
foo: {
dec: [0, 0, 0],
inc: [0, 0, 0],
total: [1, 0, 0],
},
});
assert.deepStrictEqual(chartDays, {
foo: {
dec: [0, 0, 0],
inc: [0, 0, 0],
total: [1, 0, 0],
},
});
});
it('Can resync (2)', async () => {
await testChart.increment();
await testChart.save();
clock.tick('01:00:00');
testChart.total = 100;
await testChart.resync();
const chartHours = await testChart.getChart('hour', 3, null);
const chartDays = await testChart.getChart('day', 3, null);
assert.deepStrictEqual(chartHours, {
foo: {
dec: [0, 0, 0],
inc: [0, 1, 0],
total: [100, 1, 0],
},
});
assert.deepStrictEqual(chartDays, {
foo: {
dec: [0, 0, 0],
inc: [1, 0, 0],
total: [100, 0, 0],
},
});
});
});
});