fix: エンドポイントにまつわるテストをunitからe2eに移動

This commit is contained in:
kakkokari-gtyih 2026-04-19 01:56:12 +09:00
commit c72df2b8a5
2 changed files with 123 additions and 218 deletions

View file

@ -10,7 +10,7 @@ import { describe, beforeAll, test, expect } from 'vitest';
// node-fetch only supports it's own Blob yet
// https://github.com/node-fetch/node-fetch/pull/1664
import { Blob } from 'node-fetch';
import { api, castAsError, initTestDb, post, signup, simpleGet, uploadFile } from '../utils.js';
import { api, castAsError, initTestDb, post, role, signup, simpleGet, uploadFile } from '../utils.js';
import type * as misskey from 'misskey-js';
import { MiUser } from '@/models/_.js';
@ -582,6 +582,30 @@ describe('Endpoints', () => {
});
describe('drive/files/create', () => {
const assignRole = async (userId: string, policies: Record<string, unknown>) => {
const createdRole = await role(alice, {}, policies);
const assign = await api('admin/roles/assign', {
userId,
roleId: createdRole.id,
}, alice);
assert.strictEqual(assign.status, 204);
return createdRole;
};
const cleanupRole = async (userId: string, roleId: string) => {
await api('admin/roles/unassign', {
userId,
roleId,
}, alice);
await api('admin/roles/delete', {
roleId,
}, alice);
};
test('ファイルを作成できる', async () => {
const res = await uploadFile(alice);
@ -660,6 +684,104 @@ describe('Endpoints', () => {
assert.strictEqual(webpublicType, 'image/webp');
});
}
test('uploadableFileTypes が */* なら任意のファイルをアップロードできる', async () => {
const createdRole = await assignRole(bob.id, {
uploadableFileTypes: {
useDefault: false,
priority: 1,
value: ['*/*'],
},
});
try {
const res = await uploadFile(bob, {
blob: new Blob([new Uint8Array(10)]),
});
assert.strictEqual(res.status, 200);
} finally {
await cleanupRole(bob.id, createdRole.id);
}
});
test('uploadableFileTypes に含まれない MIME type は拒否される', async () => {
const createdRole = await assignRole(bob.id, {
uploadableFileTypes: {
useDefault: false,
priority: 1,
value: ['image/png'],
},
});
try {
const res = await uploadFile(bob, { path: '192.jpg' });
assert.strictEqual(res.status, 400);
assert.ok(res.body);
assert.strictEqual(castAsError(res.body).error.code, 'UNALLOWED_FILE_TYPE');
} finally {
await cleanupRole(bob.id, createdRole.id);
}
});
test('maxFileSizeMb 制限付きロールでも制限内ならアップロードできる', async () => {
const allowAllTypesRole = await assignRole(bob.id, {
uploadableFileTypes: {
useDefault: false,
priority: 1,
value: ['*/*'],
},
});
const tinyAttachmentRole = await assignRole(bob.id, {
maxFileSizeMb: {
useDefault: false,
priority: 1,
value: 10 / 1024 / 1024, // 10バイト
},
});
try {
const res = await uploadFile(bob, {
blob: new Blob([new Uint8Array(10)]),
});
assert.strictEqual(res.status, 200);
} finally {
await cleanupRole(bob.id, tinyAttachmentRole.id);
await cleanupRole(bob.id, allowAllTypesRole.id);
}
});
test('maxFileSizeMb 制限を超えると 413 になる', async () => {
const allowAllTypesRole = await assignRole(bob.id, {
uploadableFileTypes: {
useDefault: false,
priority: 1,
value: ['*/*'],
},
});
const tinyAttachmentRole = await assignRole(bob.id, {
maxFileSizeMb: {
useDefault: false,
priority: 1,
value: 10 / 1024 / 1024, // 10バイト
},
});
try {
const res = await uploadFile(bob, {
blob: new Blob([new Uint8Array(11)]),
});
assert.strictEqual(res.status, 413);
assert.ok(res.body);
assert.strictEqual(castAsError(res.body).error.code, 'MAX_FILE_SIZE_EXCEEDED');
} finally {
await cleanupRole(bob.id, tinyAttachmentRole.id);
await cleanupRole(bob.id, allowAllTypesRole.id);
}
});
});
describe('drive/files/update', () => {

View file

@ -1,217 +0,0 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { describe, expect, beforeAll, afterAll, beforeEach, test } from 'vitest';
import { Test, TestingModule } from '@nestjs/testing';
import { FastifyInstance } from 'fastify';
import request from 'supertest';
import { randomString } from '../../../../../utils.js';
import { CoreModule } from '@/core/CoreModule.js';
import { RoleService } from '@/core/RoleService.js';
import { DI } from '@/di-symbols.js';
import { GlobalModule } from '@/GlobalModule.js';
import { DriveFoldersRepository, MiDriveFolder, MiRole, UserProfilesRepository, UsersRepository } from '@/models/_.js';
import { MiUser } from '@/models/User.js';
import { ServerModule } from '@/server/ServerModule.js';
import { ServerService } from '@/server/ServerService.js';
import { IdService } from '@/core/IdService.js';
// TODO: uploadableFileTypes で許可されていないファイルが弾かれるかのテスト
describe('/drive/files/create', () => {
let module: TestingModule;
let server: FastifyInstance;
let roleService: RoleService;
let idService: IdService;
let root: MiUser;
let role_tinyAttachment: MiRole;
let role_imageOnly: MiRole;
let role_allowAllTypes: MiRole;
let folder: MiDriveFolder;
beforeAll(async () => {
module = await Test.createTestingModule({
imports: [GlobalModule, CoreModule, ServerModule],
}).compile();
module.enableShutdownHooks();
const serverService = module.get<ServerService>(ServerService);
await serverService.launch();
server = serverService.fastify;
idService = module.get(IdService);
const usersRepository = module.get<UsersRepository>(DI.usersRepository);
await usersRepository.createQueryBuilder().delete().execute();
root = await usersRepository.insert({
id: idService.gen(),
username: 'root',
usernameLower: 'root',
token: '1234567890123456',
}).then(x => usersRepository.findOneByOrFail(x.identifiers[0]));
const userProfilesRepository = module.get<UserProfilesRepository>(DI.userProfilesRepository);
await userProfilesRepository.createQueryBuilder().delete().execute();
await userProfilesRepository.insert({
userId: root.id,
});
const driveFoldersRepository = module.get<DriveFoldersRepository>(DI.driveFoldersRepository);
folder = await driveFoldersRepository.insertOne({
id: idService.gen(),
name: 'root-folder',
parentId: null,
userId: root.id,
});
roleService = module.get<RoleService>(RoleService);
role_imageOnly = await roleService.create({
name: 'test-role001',
description: 'Test role001 description',
target: 'manual',
policies: {
uploadableFileTypes: {
useDefault: false,
priority: 1,
value: ['image/png'],
},
},
});
role_allowAllTypes = await roleService.create({
name: 'test-role002',
description: 'Test role002 description',
target: 'manual',
policies: {
uploadableFileTypes: {
useDefault: false,
priority: 1,
value: ['*/*'],
},
},
});
role_tinyAttachment = await roleService.create({
name: 'test-role003',
description: 'Test role003 description',
target: 'manual',
policies: {
maxFileSizeMb: {
useDefault: false,
priority: 1,
// 10byte
value: 10 / 1024 / 1024,
},
},
});
});
beforeEach(async () => {
await roleService.unassign(root.id, role_tinyAttachment.id).catch(() => {
});
await roleService.unassign(root.id, role_imageOnly.id).catch(() => {
});
await roleService.unassign(root.id, role_allowAllTypes.id).catch(() => {
});
});
afterAll(async () => {
await server.close();
await module.close();
});
async function postFile(props: {
name: string,
comment: string,
isSensitive: boolean,
force: boolean,
fileContent: Buffer | string,
}) {
const { name, comment, isSensitive, force, fileContent } = props;
return await request(server.server)
.post('/api/drive/files/create')
.set('Content-Type', 'multipart/form-data')
.attach('file', fileContent)
.field('name', name)
.field('comment', comment)
.field('isSensitive', isSensitive)
.field('force', force)
.field('folderId', folder.id)
.field('i', root.token ?? '');
}
test('200 ok (all types allowed)', async () => {
await roleService.assign(root.id, role_allowAllTypes.id);
const name = randomString();
const comment = randomString();
const result = await postFile({
name: name,
comment: comment,
isSensitive: true,
force: true,
fileContent: Buffer.from('a'.repeat(1000 * 1000)),
});
expect(result.statusCode).toBe(200);
expect(result.body.name).toBe(name + '.unknown');
expect(result.body.comment).toBe(comment);
expect(result.body.isSensitive).toBe(true);
expect(result.body.folderId).toBe(folder.id);
});
test('400 when not allowed type', async () => {
await roleService.assign(root.id, role_imageOnly.id);
const name = randomString();
const comment = randomString();
const result = await postFile({
name: name,
comment: comment,
isSensitive: true,
force: true,
fileContent: Buffer.from('a'.repeat(10)),
});
expect(result.statusCode).toBe(400);
expect(result.body.error.code).toBe('UNALLOWED_FILE_TYPE');
});
test('200 ok (with size limited role)', async () => {
await roleService.assign(root.id, role_allowAllTypes.id);
await roleService.assign(root.id, role_tinyAttachment.id);
const name = randomString();
const comment = randomString();
const result = await postFile({
name: name,
comment: comment,
isSensitive: true,
force: true,
fileContent: Buffer.from('a'.repeat(10)),
});
expect(result.statusCode).toBe(200);
expect(result.body.name).toBe(name + '.unknown');
expect(result.body.comment).toBe(comment);
expect(result.body.isSensitive).toBe(true);
expect(result.body.folderId).toBe(folder.id);
});
test('413 too large', async () => {
await roleService.assign(root.id, role_allowAllTypes.id);
await roleService.assign(root.id, role_tinyAttachment.id);
const name = randomString();
const comment = randomString();
const result = await postFile({
name: name,
comment: comment,
isSensitive: true,
force: true,
fileContent: Buffer.from('a'.repeat(11)),
});
expect(result.statusCode).toBe(413);
expect(result.body.error.code).toBe('MAX_FILE_SIZE_EXCEEDED');
});
});