OMDSCloud/dictation_server/src/features/tasks/tasks.service.spec.ts

7614 lines
230 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {
makeDefaultAdb2cServiceMockValue,
makeDefaultNotificationhubServiceMockValue,
makeDefaultTasksRepositoryMockValue,
makeDefaultUserGroupsRepositoryMockValue,
makeDefaultUsersRepositoryMockValue,
makeTasksServiceMock,
} from './test/tasks.service.mock';
import { HttpException, HttpStatus } from '@nestjs/common';
import { makeErrorResponse } from '../../common/error/makeErrorResponse';
import { TasksService } from './tasks.service';
import { DataSource } from 'typeorm';
import {
createAudioFile,
createCheckoutPermissions,
createTask,
createUserGroup,
getAudioFile,
getAudioOptionItems,
getCheckoutPermissions,
getTask,
makeTaskTestingModuleWithNotificaiton,
} from './test/utility';
import { Adb2cTooManyRequestsError } from '../../gateways/adb2c/adb2c.service';
import { Context, makeContext } from '../../common/log';
import {
createSortCriteria,
makeTestAccount,
makeTestSimpleAccount,
makeTestUser,
updateSortCriteria,
updateTaskFilter,
} from '../../common/test/utility';
import {
ADB2C_SIGN_IN_TYPE,
ADMIN_ROLES,
LICENSE_ALLOCATED_STATUS,
LICENSE_TYPE,
TASK_STATUS,
USER_ROLES,
} from '../../constants';
import { makeTestingModule } from '../../common/test/modules';
import { createWorktype } from '../accounts/test/utility';
import {
createWorkflow,
createWorkflowTypist,
} from '../workflows/test/utility';
import { createTemplateFile } from '../templates/test/utility';
import { NotificationhubService } from '../../gateways/notificationhub/notificationhub.service';
import { Roles } from '../../common/types/role';
import { TasksRepositoryService } from '../../repositories/tasks/tasks.repository.service';
import {
overrideAdB2cService,
overrideBlobstorageService,
overrideSendgridService,
} from '../../common/test/overrides';
import { BlobstorageService } from '../../gateways/blobstorage/blobstorage.service';
import { truncateAllTable } from '../../common/test/init';
import { makeDefaultLicensesRepositoryMockValue } from '../accounts/test/accounts.service.mock';
import { DateWithZeroTime } from '../licenses/types/types';
import { createLicense } from '../licenses/test/utility';
import { TestLogger } from '../../common/test/logger';
import { FILE } from 'node:dns';
describe('TasksService', () => {
it('タスク一覧を取得できるadmin', async () => {
const tasksRepositoryMockValue = makeDefaultTasksRepositoryMockValue();
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
const userGroupsRepositoryMockValue =
makeDefaultUserGroupsRepositoryMockValue();
const adb2cServiceMockValue = makeDefaultAdb2cServiceMockValue();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const licensesRepositoryMockValue =
makeDefaultLicensesRepositoryMockValue();
const service = await makeTasksServiceMock(
tasksRepositoryMockValue,
usersRepositoryMockValue,
userGroupsRepositoryMockValue,
adb2cServiceMockValue,
notificationhubServiceMockValue,
licensesRepositoryMockValue,
);
const userId = 'userId';
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
expect(
await service.tasksService.getTasks(
makeContext('trackingId', 'requestId'),
userId,
[ADMIN_ROLES.ADMIN, USER_ROLES.NONE],
offset,
limit,
status,
paramName,
direction,
),
).toEqual({
tasks: [
{
assignees: [{ typistName: 'XXXX XXX', typistUserId: 1 }],
audioCreatedDate: '2023-01-01T01:01:01.000Z',
audioDuration: '123000',
audioFileId: 1,
audioFinishedDate: '2023-01-01T01:01:01.000Z',
audioFormat: 'DS',
audioUploadedDate: '2023-01-01T01:01:01.000Z',
authorId: 'AUTHOR',
comment: 'comment',
fileName: 'test.zip',
rawFileName: 'test.zip',
fileSize: 123000,
isEncrypted: true,
jobNumber: '00000001',
optionItemList: [
{ optionItemLabel: 'label01', optionItemValue: 'value01' },
{ optionItemLabel: 'label02', optionItemValue: 'value02' },
{ optionItemLabel: 'label03', optionItemValue: 'value03' },
{ optionItemLabel: 'label04', optionItemValue: 'value04' },
{ optionItemLabel: 'label05', optionItemValue: 'value05' },
{ optionItemLabel: 'label06', optionItemValue: 'value06' },
{ optionItemLabel: 'label07', optionItemValue: 'value07' },
{ optionItemLabel: 'label08', optionItemValue: 'value08' },
{ optionItemLabel: 'label09', optionItemValue: 'value09' },
{ optionItemLabel: 'label10', optionItemValue: 'value10' },
],
priority: '00',
status: 'Uploaded',
transcriptionFinishedDate: undefined,
transcriptionStartedDate: undefined,
typist: undefined,
url: 'test/test.zip',
workType: 'WorkType',
},
],
total: 1,
});
});
it('アカウント情報の取得に失敗した場合、エラーを返却する', async () => {
const tasksRepositoryMockValue = makeDefaultTasksRepositoryMockValue();
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
const userGroupsRepositoryMockValue =
makeDefaultUserGroupsRepositoryMockValue();
const adb2cServiceMockValue = makeDefaultAdb2cServiceMockValue();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const licensesRepositoryMockValue =
makeDefaultLicensesRepositoryMockValue();
usersRepositoryMockValue.findUserByExternalId = new Error('DB failed');
const service = await makeTasksServiceMock(
tasksRepositoryMockValue,
usersRepositoryMockValue,
userGroupsRepositoryMockValue,
adb2cServiceMockValue,
notificationhubServiceMockValue,
licensesRepositoryMockValue,
);
const userId = 'userId';
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
await expect(
service.tasksService.getTasks(
makeContext('trackingId', 'requestId'),
userId,
[ADMIN_ROLES.ADMIN, USER_ROLES.NONE],
offset,
limit,
status,
paramName,
direction,
),
).rejects.toEqual(
new HttpException(
makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR,
),
);
});
it('タスク一覧の取得に失敗した場合、エラーを返却するadmin', async () => {
const tasksRepositoryMockValue = makeDefaultTasksRepositoryMockValue();
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
const userGroupsRepositoryMockValue =
makeDefaultUserGroupsRepositoryMockValue();
const adb2cServiceMockValue = makeDefaultAdb2cServiceMockValue();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const licensesRepositoryMockValue =
makeDefaultLicensesRepositoryMockValue();
tasksRepositoryMockValue.getTasksFromAccountId = new Error('DB failed');
const service = await makeTasksServiceMock(
tasksRepositoryMockValue,
usersRepositoryMockValue,
userGroupsRepositoryMockValue,
adb2cServiceMockValue,
notificationhubServiceMockValue,
licensesRepositoryMockValue,
);
const userId = 'userId';
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
await expect(
service.tasksService.getTasks(
makeContext('trackingId', 'requestId'),
userId,
[ADMIN_ROLES.ADMIN, USER_ROLES.NONE],
offset,
limit,
status,
paramName,
direction,
),
).rejects.toEqual(
new HttpException(
makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR,
),
);
});
it('取得したタスク一覧が不正な形式の場合、エラーを返却する', async () => {
const tasksRepositoryMockValue = makeDefaultTasksRepositoryMockValue();
tasksRepositoryMockValue.getTasksFromAccountId = {
tasks: [
{
id: 1,
job_number: '00000001',
account_id: 1,
is_job_number_enabled: true,
audio_file_id: 1,
status: 'Uploaded',
priority: '00',
created_at: new Date('2023-01-01T01:01:01.000'),
option_items: null, // 存在しない場合でも空配列であるはずのものがnullになっているため形式不正
finished_at: null,
started_at: null,
typist_user_id: null,
template_file_id: null,
typist_user: null,
template_file: null,
created_by: null,
updated_by: null,
updated_at: new Date('2023-01-01T01:01:01.000'),
file: {
id: 1,
account_id: 1,
owner_user_id: 1,
url: 'test/test.zip',
file_name: 'test.zip',
raw_file_name: 'test.zip',
author_id: 'AUTHOR',
work_type_id: 'WorkType',
started_at: new Date('2023-01-01T01:01:01.000'),
duration: '123000',
finished_at: new Date('2023-01-01T01:01:01.000'),
uploaded_at: new Date('2023-01-01T01:01:01.000'),
file_size: 123000,
priority: '00',
audio_format: 'DS',
comment: 'comment',
is_encrypted: true,
deleted_at: null,
task: null,
},
},
],
permissions: [],
count: 1,
};
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
const userGroupsRepositoryMockValue =
makeDefaultUserGroupsRepositoryMockValue();
const adb2cServiceMockValue = makeDefaultAdb2cServiceMockValue();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const licensesRepositoryMockValue =
makeDefaultLicensesRepositoryMockValue();
const service = await makeTasksServiceMock(
tasksRepositoryMockValue,
usersRepositoryMockValue,
userGroupsRepositoryMockValue,
adb2cServiceMockValue,
notificationhubServiceMockValue,
licensesRepositoryMockValue,
);
const userId = 'userId';
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
await expect(
service.tasksService.getTasks(
makeContext('trackingId', 'requestId'),
userId,
[ADMIN_ROLES.ADMIN, USER_ROLES.NONE],
offset,
limit,
status,
paramName,
direction,
),
).rejects.toEqual(
new HttpException(
makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR,
),
);
});
it('タスク一覧を取得できるauthor', async () => {
const tasksRepositoryMockValue = makeDefaultTasksRepositoryMockValue();
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
const userGroupsRepositoryMockValue =
makeDefaultUserGroupsRepositoryMockValue();
const adb2cServiceMockValue = makeDefaultAdb2cServiceMockValue();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const licensesRepositoryMockValue =
makeDefaultLicensesRepositoryMockValue();
if (usersRepositoryMockValue.findUserByExternalId instanceof Error) {
return;
}
usersRepositoryMockValue.findUserByExternalId.role = 'author';
const service = await makeTasksServiceMock(
tasksRepositoryMockValue,
usersRepositoryMockValue,
userGroupsRepositoryMockValue,
adb2cServiceMockValue,
notificationhubServiceMockValue,
licensesRepositoryMockValue,
);
const userId = 'userId';
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const context = makeContext('trackingId', 'requestId');
const result = await service.tasksService.getTasks(
context,
userId,
[USER_ROLES.AUTHOR],
offset,
limit,
status,
paramName,
direction,
);
expect(result).toEqual({
tasks: [
{
assignees: [{ typistName: 'XXXX XXX', typistUserId: 1 }],
audioCreatedDate: '2023-01-01T01:01:01.000Z',
audioDuration: '123000',
audioFileId: 1,
audioFinishedDate: '2023-01-01T01:01:01.000Z',
audioFormat: 'DS',
audioUploadedDate: '2023-01-01T01:01:01.000Z',
authorId: 'AUTHOR',
comment: 'comment',
fileName: 'test.zip',
rawFileName: 'test.zip',
fileSize: 123000,
isEncrypted: true,
jobNumber: '00000001',
optionItemList: [
{ optionItemLabel: 'label01', optionItemValue: 'value01' },
{ optionItemLabel: 'label02', optionItemValue: 'value02' },
{ optionItemLabel: 'label03', optionItemValue: 'value03' },
{ optionItemLabel: 'label04', optionItemValue: 'value04' },
{ optionItemLabel: 'label05', optionItemValue: 'value05' },
{ optionItemLabel: 'label06', optionItemValue: 'value06' },
{ optionItemLabel: 'label07', optionItemValue: 'value07' },
{ optionItemLabel: 'label08', optionItemValue: 'value08' },
{ optionItemLabel: 'label09', optionItemValue: 'value09' },
{ optionItemLabel: 'label10', optionItemValue: 'value10' },
],
priority: '00',
status: 'Uploaded',
transcriptionFinishedDate: undefined,
transcriptionStartedDate: undefined,
typist: undefined,
url: 'test/test.zip',
workType: 'WorkType',
},
],
total: 1,
});
expect(
service.taskRepoService.getTasksFromAuthorIdAndAccountId,
).toHaveBeenCalledWith(
context,
'abcdef',
1,
0,
20,
'JOB_NUMBER',
'ASC',
['Uploaded', 'Backup'],
undefined,
undefined,
);
});
it('タスク一覧の取得に失敗した場合、エラーを返却するauthor', async () => {
const tasksRepositoryMockValue = makeDefaultTasksRepositoryMockValue();
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
const userGroupsRepositoryMockValue =
makeDefaultUserGroupsRepositoryMockValue();
const adb2cServiceMockValue = makeDefaultAdb2cServiceMockValue();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const licensesRepositoryMockValue =
makeDefaultLicensesRepositoryMockValue();
tasksRepositoryMockValue.getTasksFromAuthorIdAndAccountId = new Error(
'DB failed',
);
const service = await makeTasksServiceMock(
tasksRepositoryMockValue,
usersRepositoryMockValue,
userGroupsRepositoryMockValue,
adb2cServiceMockValue,
notificationhubServiceMockValue,
licensesRepositoryMockValue,
);
const userId = 'userId';
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
await expect(
service.tasksService.getTasks(
makeContext('trackingId', 'requestId'),
userId,
[USER_ROLES.AUTHOR],
offset,
limit,
status,
paramName,
direction,
),
).rejects.toEqual(
new HttpException(
makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR,
),
);
});
it('タスク一覧を取得できるtypist', async () => {
const tasksRepositoryMockValue = makeDefaultTasksRepositoryMockValue();
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
const userGroupsRepositoryMockValue =
makeDefaultUserGroupsRepositoryMockValue();
const adb2cServiceMockValue = makeDefaultAdb2cServiceMockValue();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const licensesRepositoryMockValue =
makeDefaultLicensesRepositoryMockValue();
if (usersRepositoryMockValue.findUserByExternalId instanceof Error) {
return;
}
usersRepositoryMockValue.findUserByExternalId.role = 'typist';
const service = await makeTasksServiceMock(
tasksRepositoryMockValue,
usersRepositoryMockValue,
userGroupsRepositoryMockValue,
adb2cServiceMockValue,
notificationhubServiceMockValue,
licensesRepositoryMockValue,
);
const userId = 'userId';
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const context = makeContext('trackingId', 'requestId');
const result = await service.tasksService.getTasks(
context,
userId,
[USER_ROLES.TYPIST],
offset,
limit,
status,
paramName,
direction,
);
expect(result).toEqual({
tasks: [
{
assignees: [{ typistName: 'XXXX XXX', typistUserId: 1 }],
audioCreatedDate: '2023-01-01T01:01:01.000Z',
audioDuration: '123000',
audioFileId: 1,
audioFinishedDate: '2023-01-01T01:01:01.000Z',
audioFormat: 'DS',
audioUploadedDate: '2023-01-01T01:01:01.000Z',
authorId: 'AUTHOR',
comment: 'comment',
fileName: 'test.zip',
rawFileName: 'test.zip',
fileSize: 123000,
isEncrypted: true,
jobNumber: '00000001',
optionItemList: [
{ optionItemLabel: 'label01', optionItemValue: 'value01' },
{ optionItemLabel: 'label02', optionItemValue: 'value02' },
{ optionItemLabel: 'label03', optionItemValue: 'value03' },
{ optionItemLabel: 'label04', optionItemValue: 'value04' },
{ optionItemLabel: 'label05', optionItemValue: 'value05' },
{ optionItemLabel: 'label06', optionItemValue: 'value06' },
{ optionItemLabel: 'label07', optionItemValue: 'value07' },
{ optionItemLabel: 'label08', optionItemValue: 'value08' },
{ optionItemLabel: 'label09', optionItemValue: 'value09' },
{ optionItemLabel: 'label10', optionItemValue: 'value10' },
],
priority: '00',
status: 'Uploaded',
transcriptionFinishedDate: undefined,
transcriptionStartedDate: undefined,
typist: undefined,
url: 'test/test.zip',
workType: 'WorkType',
},
],
total: 1,
});
expect(
service.taskRepoService.getTasksFromTypistRelations,
).toHaveBeenCalledWith(
context,
'userId',
0,
20,
'JOB_NUMBER',
'ASC',
['Uploaded', 'Backup'],
undefined,
undefined,
);
});
it('タスク一覧の取得に失敗した場合、エラーを返却するtypist', async () => {
const tasksRepositoryMockValue = makeDefaultTasksRepositoryMockValue();
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
const userGroupsRepositoryMockValue =
makeDefaultUserGroupsRepositoryMockValue();
const adb2cServiceMockValue = makeDefaultAdb2cServiceMockValue();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
tasksRepositoryMockValue.getTasksFromTypistRelations = new Error(
'DB failed',
);
const licensesRepositoryMockValue =
makeDefaultLicensesRepositoryMockValue();
const service = await makeTasksServiceMock(
tasksRepositoryMockValue,
usersRepositoryMockValue,
userGroupsRepositoryMockValue,
adb2cServiceMockValue,
notificationhubServiceMockValue,
licensesRepositoryMockValue,
);
const userId = 'userId';
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
await expect(
service.tasksService.getTasks(
makeContext('trackingId', 'requestId'),
userId,
[USER_ROLES.TYPIST],
offset,
limit,
status,
paramName,
direction,
),
).rejects.toEqual(
new HttpException(
makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR,
),
);
});
it('AdB2Cのリクエスト上限超過時、専用のエラーを返却する', async () => {
const tasksRepositoryMockValue = makeDefaultTasksRepositoryMockValue();
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
const userGroupsRepositoryMockValue =
makeDefaultUserGroupsRepositoryMockValue();
const adb2cServiceMockValue = makeDefaultAdb2cServiceMockValue();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const licensesRepositoryMockValue =
makeDefaultLicensesRepositoryMockValue();
adb2cServiceMockValue.getUsers = new Adb2cTooManyRequestsError();
const service = await makeTasksServiceMock(
tasksRepositoryMockValue,
usersRepositoryMockValue,
userGroupsRepositoryMockValue,
adb2cServiceMockValue,
notificationhubServiceMockValue,
licensesRepositoryMockValue,
);
const userId = 'userId';
const offset = 0;
const limit = 20;
const status = ['Uploaded,Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
await expect(
service.tasksService.getTasks(
makeContext('trackingId', 'requestId'),
userId,
[ADMIN_ROLES.ADMIN, USER_ROLES.NONE],
offset,
limit,
status,
paramName,
direction,
),
).rejects.toEqual(
new HttpException(
makeErrorResponse('E000301'),
HttpStatus.INTERNAL_SERVER_ERROR,
),
);
});
describe('DBテスト', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
port: 3306,
username: 'user',
password: 'password',
database: 'odms',
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
synchronize: false, // trueにすると自動的にmigrationが行われるため注意
logger: new TestLogger('none'),
logging: true,
});
return await s.initialize();
})();
}
});
beforeEach(async () => {
if (source) {
await truncateAllTable(source);
}
});
afterAll(async () => {
await source?.destroy();
source = null;
});
it('[Admin] Taskが0件であっても実行できる', async () => {
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
if (!source) fail();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: externalId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'userId',
role: 'admin',
});
const service = module.get<TasksService>(TasksService);
const offset = 0;
const limit = 20;
const status = ['Uploaded,Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const { tasks, total } = await service.getTasks(
makeContext('trackingId', 'requestId'),
externalId,
[ADMIN_ROLES.ADMIN, USER_ROLES.NONE],
offset,
limit,
status,
paramName,
direction,
);
expect(tasks).toEqual([]);
expect(total).toEqual(0);
});
it('[Author] Authorは自分が作成者のTask一覧を取得できる', async () => {
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
if (!source) fail();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: userId, external_id } = await makeTestUser(source, {
account_id: accountId,
external_id: 'userId',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
//「バグ 3661: [FB対応]Option Itemにチェックを付けると真っ白な画面になる」の確認のため
// audio_file_idをTaskIdと異なる値にするために、AudioFileを作成
await createAudioFile(
source,
accountId,
userId,
'MY_AUTHOR_ID',
'',
'00',
);
// Taskを作成
await createTask(
source,
accountId,
userId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Uploaded',
);
await createTask(
source,
accountId,
userId,
'MY_AUTHOR_ID',
'',
'01',
'00000002',
'Uploaded',
);
const service = module.get<TasksService>(TasksService);
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const { tasks, total } = await service.getTasks(
makeContext('trackingId', 'requestId'),
external_id,
[USER_ROLES.AUTHOR],
offset,
limit,
status,
paramName,
direction,
);
expect(total).toEqual(2);
{
const task = tasks[0];
expect(task.jobNumber).toEqual('00000001');
// AudioOptionItem
const audioOptionItems = Array.from({ length: 10 }).map((_, i) => {
return {
optionItemLabel: `label${i}:audio_file_id${task.audioFileId}`,
optionItemValue: `value${i}:audio_file_id${task.audioFileId}`,
};
});
expect(task.optionItemList).toEqual(audioOptionItems);
}
{
const task = tasks[1];
expect(task.jobNumber).toEqual('00000002');
// AudioOptionItem
const audioOptionItems = Array.from({ length: 10 }).map((_, i) => {
return {
optionItemLabel: `label${i}:audio_file_id${task.audioFileId}`,
optionItemValue: `value${i}:audio_file_id${task.audioFileId}`,
};
});
expect(task.optionItemList).toEqual(audioOptionItems);
}
});
it('[Author] Authorは自分が作成者のTask一覧を取得できる(ソート条件がJob_number以外)', async () => {
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
if (!source) fail();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: userId, external_id } = await makeTestUser(source, {
account_id: accountId,
external_id: 'userId',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
//「バグ 3661: [FB対応]Option Itemにチェックを付けると真っ白な画面になる」の確認のため
// audio_file_idをTaskIdと異なる値にするために、AudioFileを作成
await createAudioFile(
source,
accountId,
userId,
'MY_AUTHOR_ID',
'',
'00',
);
// Taskを作成
await createTask(
source,
accountId,
userId,
'MY_AUTHOR_ID',
'WORKTYPE1',
'01',
'00000001',
'Uploaded',
);
await createTask(
source,
accountId,
userId,
'MY_AUTHOR_ID',
'WORKTYPE2',
'01',
'00000002',
'Uploaded',
);
const service = module.get<TasksService>(TasksService);
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
// バグ 3786: [FB対応]タスク一覧画面のOptionItemがソート条件によって表示順がおかしくなる の確認のため
// Job_number以外のソート条件を指定
const paramName = 'WORK_TYPE';
const direction = 'DESC';
const { tasks, total } = await service.getTasks(
makeContext('trackingId', 'requestId'),
external_id,
[USER_ROLES.AUTHOR],
offset,
limit,
status,
paramName,
direction,
);
expect(total).toEqual(2);
{
const task = tasks[0];
expect(task.jobNumber).toEqual('00000002');
// ソート条件がJob_number以外でもOptionItemがid順に取得されていることを確認
const audioOptionItems = Array.from({ length: 10 }).map((_, i) => {
return {
optionItemLabel: `label${i}:audio_file_id${task.audioFileId}`,
optionItemValue: `value${i}:audio_file_id${task.audioFileId}`,
};
});
expect(task.optionItemList).toEqual(audioOptionItems);
}
{
const task = tasks[1];
expect(task.jobNumber).toEqual('00000001');
// ソート条件がJob_number以外でもOptionItemがid順に取得されていることを確認
const audioOptionItems = Array.from({ length: 10 }).map((_, i) => {
return {
optionItemLabel: `label${i}:audio_file_id${task.audioFileId}`,
optionItemValue: `value${i}:audio_file_id${task.audioFileId}`,
};
});
expect(task.optionItemList).toEqual(audioOptionItems);
}
});
it('[Author] Authorは同一アカウントであっても自分以外のAuhtorのTaskは取得できない', async () => {
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
if (!source) fail();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: userId_1, external_id } = await makeTestUser(source, {
account_id: accountId,
external_id: 'userId_1',
role: 'author',
author_id: 'AUTHOR_ID_1',
});
const { id: userId_2 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'userId_2',
role: 'author',
author_id: 'AUTHOR_ID_2',
});
await createTask(
source,
accountId,
userId_1,
'AUTHOR_ID_1',
'',
'01',
'00000001',
'Uploaded',
);
await createTask(
source,
accountId,
userId_2,
'AUTHOR_ID_2',
'',
'01',
'00000002',
'Uploaded',
);
const service = module.get<TasksService>(TasksService);
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const { tasks, total } = await service.getTasks(
makeContext('trackingId', 'requestId'),
external_id,
[USER_ROLES.AUTHOR],
offset,
limit,
status,
paramName,
direction,
);
expect(total).toEqual(1);
{
const task = tasks[0];
expect(task.jobNumber).toEqual('00000001');
}
});
it('[Admin] Taskが100件であっても取得できる', async () => {
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
if (!source) fail();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id } = await makeTestUser(source, {
account_id: accountId,
external_id: 'userId',
role: 'none',
});
const { id: authorUserId, author_id } = await makeTestUser(source, {
account_id: accountId,
external_id: 'userId',
author_id: 'MY_AUTHOR_ID',
role: 'author',
});
const service = module.get<TasksService>(TasksService);
for (let i = 0; i < 100; i++) {
await createTask(
source,
accountId,
authorUserId,
author_id ?? '',
`WORKTYPE${i + 1}`,
'01',
// 00000001 ~ 00000100
`000000${String(i + 1).padStart(2, '0')}`,
'Uploaded',
);
}
const offset = 0;
const limit = 100;
const status = ['Uploaded', 'Backup'];
const paramName = 'WORK_TYPE';
const direction = 'DESC';
const { tasks, total } = await service.getTasks(
makeContext('trackingId', 'requestId'),
external_id,
[ADMIN_ROLES.ADMIN, USER_ROLES.NONE],
offset,
limit,
status,
paramName,
direction,
);
expect(tasks.length).toEqual(100);
expect(total).toEqual(100);
// ソート条件がWORK_TYPEのため、WORK_TYPEが降順になっていることを確認
expect(tasks[0].workType).toEqual('WORKTYPE99');
expect(tasks[99].workType).toEqual('WORKTYPE1');
expect(tasks[0].optionItemList).toEqual(
Array.from({ length: 10 }).map((_, i) => {
return {
optionItemLabel: `label${i}:audio_file_id${tasks[0].audioFileId}`,
optionItemValue: `value${i}:audio_file_id${tasks[0].audioFileId}`,
};
}),
);
});
describe('[admin] キーワード検索テスト', () => {
let service;
// ユーザーIDadmin
const admin_user_id = 'userId';
// AUTHOR ID 1
const author_id_1 = 'AUTHOR_1';
// AUTHOR ID 2
const author_id_2 = 'AUTHOR_2';
let notificationhubServiceMockValue;
beforeEach(async () => {
notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
if (!source) fail();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
// アカウント作成
const { id: accountId } = await makeTestSimpleAccount(source);
// ユーザー作成admin
const { external_id: adminUser } = await makeTestUser(source, {
account_id: accountId,
external_id: admin_user_id,
role: 'none',
});
// ユーザー作成AUTHOR1
const {
id: authorUser1,
external_id: author1,
author_id: authorId1,
} = await makeTestUser(source, {
account_id: accountId,
external_id: 'author_1',
author_id: author_id_1,
role: 'author',
});
// ユーザー作成AUTHOR2
const {
id: authorUser2,
external_id: author2,
author_id: authorId2,
} = await makeTestUser(source, {
account_id: accountId,
external_id: 'author_2',
author_id: author_id_2,
role: 'author',
});
service = module.get<TasksService>(TasksService);
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: adminUser,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
{
id: author1,
displayName: 'author1',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'author1@example.com',
},
],
},
{
id: author2,
displayName: 'author2',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'author2@example.com',
},
],
},
];
},
});
// タスクデータ作成
for (let i = 0; i < 10; i++) {
await createTask(
source,
accountId,
authorUser1,
authorId1 ?? '',
`WORKTYPE${i + 1}`,
'01',
// 00000001 ~ 00000010
`0000000${String(i + 1).padStart(2, '0')}`,
'Uploaded',
undefined,
true,
`file${String(i + 1).padStart(2, '0')}.zip`,
);
}
for (let i = 10; i < 15; i++) {
await createTask(
source,
accountId,
authorUser2,
authorId2 ?? '',
`WORKTYPE${i + 1}`,
'01',
// 00000011 ~ 00000015
`0000000${String(i + 1).padStart(2, '0')}`,
'Uploaded',
undefined,
true,
`file${String(i + 1).padStart(2, '0')}.zip`,
);
}
});
it('AuthorIDで絞り込みができる', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'AUTHOR_1';
const userInputFileName = undefined;
const { tasks, total } = await service.getTasks(
context,
admin_user_id,
[ADMIN_ROLES.ADMIN, USER_ROLES.NONE],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(10);
expect(total).toEqual(10);
});
it('部分一致でAuthorIDで絞り込みができる', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'UTH';
const userInputFileName = undefined;
const { tasks, total } = await service.getTasks(
context,
admin_user_id,
[ADMIN_ROLES.ADMIN, USER_ROLES.NONE],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(15);
expect(total).toEqual(15);
});
it('AuthorIDで絞り込みができない', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'TEST';
const userInputFileName = undefined;
const { tasks, total } = await service.getTasks(
context,
admin_user_id,
[ADMIN_ROLES.ADMIN, USER_ROLES.NONE],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(0);
expect(total).toEqual(0);
});
it('完全一致でファイル名で絞り込みができる', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = undefined;
const userInputFileName = 'file01.zip';
const { tasks, total } = await service.getTasks(
context,
admin_user_id,
[ADMIN_ROLES.ADMIN, USER_ROLES.NONE],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(1);
expect(total).toEqual(1);
});
it('部分一致でファイル名で絞り込みができる', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = undefined;
const userInputFileName = 'file0';
const { tasks, total } = await service.getTasks(
context,
admin_user_id,
[ADMIN_ROLES.ADMIN, USER_ROLES.NONE],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(9);
expect(total).toEqual(9);
});
it('ファイル名で絞り込みができない', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = undefined;
const userInputFileName = 'test.zip';
const { tasks, total } = await service.getTasks(
context,
admin_user_id,
[ADMIN_ROLES.ADMIN, USER_ROLES.NONE],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(0);
expect(total).toEqual(0);
});
it('完全一致でAuthorIDとファイル名で絞り込みができる', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'AUTHOR_1';
const userInputFileName = 'file01.zip';
const { tasks, total } = await service.getTasks(
context,
admin_user_id,
[ADMIN_ROLES.ADMIN, USER_ROLES.NONE],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(1);
expect(total).toEqual(1);
});
it('部分一致でAuthorIDとファイル名で絞り込みができる', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'UTH';
const userInputFileName = 'file03';
const { tasks, total } = await service.getTasks(
context,
admin_user_id,
[ADMIN_ROLES.ADMIN, USER_ROLES.NONE],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(1);
expect(total).toEqual(1);
});
it('AuthorIDとファイル名で絞り込みができないファイル名が違う', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'AUTHOR_1';
const userInputFileName = 'test.zip';
const { tasks, total } = await service.getTasks(
context,
admin_user_id,
[ADMIN_ROLES.ADMIN, USER_ROLES.NONE],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(0);
expect(total).toEqual(0);
});
it('AuthorIDとファイル名で絞り込みができないAuthorIDが違う', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'TEST';
const userInputFileName = 'file03.zip';
const { tasks, total } = await service.getTasks(
context,
admin_user_id,
[ADMIN_ROLES.ADMIN, USER_ROLES.NONE],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(0);
expect(total).toEqual(0);
});
});
describe('[typist] キーワード検索テスト', () => {
let service;
let notificationhubServiceMockValue;
// ユーザーIDadmin
const admin_user_id = 'userId';
// AUTHOR ID 1
const author_id_1 = 'AUTHOR_1';
// AUTHOR ID 2
const author_id_2 = 'AUTHOR_2';
// TYPIST
const typist_id = 'typistId';
beforeEach(async () => {
notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
if (!source) fail();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
// アカウント作成
const { id: accountId } = await makeTestSimpleAccount(source);
// ユーザー作成admin
const { external_id: adminUser } = await makeTestUser(source, {
account_id: accountId,
external_id: admin_user_id,
role: 'none',
});
// ユーザー作成AUTHOR1
const {
id: authorUser1,
external_id: author1,
author_id: authorId1,
} = await makeTestUser(source, {
account_id: accountId,
external_id: 'author_1',
author_id: author_id_1,
role: 'author',
});
// ユーザー作成AUTHOR2
const {
id: authorUser2,
external_id: author2,
author_id: authorId2,
} = await makeTestUser(source, {
account_id: accountId,
external_id: 'author_2',
author_id: author_id_2,
role: 'author',
});
// ユーザー作成TYPIST
const { id: typistUser, external_id: typist } = await makeTestUser(
source,
{
account_id: accountId,
external_id: typist_id,
role: 'typist',
},
);
// グループ作成
const { userGroupId } = await createUserGroup(
source,
accountId,
'USER_GROUP_A',
[typistUser],
);
service = module.get<TasksService>(TasksService);
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: adminUser,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
{
id: author1,
displayName: 'author1',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'author1@example.com',
},
],
},
{
id: author2,
displayName: 'author2',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'author2@example.com',
},
],
},
{
id: typist,
displayName: 'typist',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'typist@example.com',
},
],
},
];
},
});
// タスクデータ作成
for (let i = 0; i < 10; i++) {
const { taskId } = await createTask(
source,
accountId,
authorUser1,
authorId1 ?? '',
`WORKTYPE${i + 1}`,
'01',
// 00000001 ~ 00000010
`0000000${String(i + 1).padStart(2, '0')}`,
'Uploaded',
undefined,
true,
`file${String(i + 1).padStart(2, '0')}.zip`,
);
await createCheckoutPermissions(source, taskId, typistUser);
await createCheckoutPermissions(
source,
taskId,
undefined,
userGroupId,
);
}
for (let i = 10; i < 15; i++) {
const { taskId } = await createTask(
source,
accountId,
authorUser2,
authorId2 ?? '',
`WORKTYPE${i + 1}`,
'01',
// 00000011 ~ 00000015
`0000000${String(i + 1).padStart(2, '0')}`,
'Uploaded',
undefined,
true,
`file${String(i + 1).padStart(2, '0')}.zip`,
);
await createCheckoutPermissions(source, taskId, typistUser);
await createCheckoutPermissions(
source,
taskId,
undefined,
userGroupId,
);
}
});
it('AuthorIDで絞り込みができる', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'AUTHOR_1';
const userInputFileName = undefined;
const { tasks, total } = await service.getTasks(
context,
typist_id,
[USER_ROLES.TYPIST],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(10);
expect(total).toEqual(10);
});
it('部分一致でAuthorIDで絞り込みができる', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'UTH';
const userInputFileName = undefined;
const { tasks, total } = await service.getTasks(
context,
typist_id,
[USER_ROLES.TYPIST],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(15);
expect(total).toEqual(15);
});
it('AuthorIDで絞り込みができない', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'TEST';
const userInputFileName = undefined;
const { tasks, total } = await service.getTasks(
context,
typist_id,
[USER_ROLES.TYPIST],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(0);
expect(total).toEqual(0);
});
it('完全一致でファイル名で絞り込みができる', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = undefined;
const userInputFileName = 'file01.zip';
const { tasks, total } = await service.getTasks(
context,
typist_id,
[USER_ROLES.TYPIST],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(1);
expect(total).toEqual(1);
});
it('部分一致でファイル名で絞り込みができる', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = undefined;
const userInputFileName = 'file0';
const { tasks, total } = await service.getTasks(
context,
typist_id,
[USER_ROLES.TYPIST],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(9);
expect(total).toEqual(9);
});
it('ファイル名で絞り込みができない', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = undefined;
const userInputFileName = 'test.zip';
const { tasks, total } = await service.getTasks(
context,
typist_id,
[USER_ROLES.TYPIST],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(0);
expect(total).toEqual(0);
});
it('完全一致でAuthorIDとファイル名で絞り込みができる', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'AUTHOR_1';
const userInputFileName = 'file01.zip';
const { tasks, total } = await service.getTasks(
context,
typist_id,
[USER_ROLES.TYPIST],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(1);
expect(total).toEqual(1);
});
it('部分一致でAuthorIDとファイル名で絞り込みができる', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'UTH';
const userInputFileName = 'file03';
const { tasks, total } = await service.getTasks(
context,
typist_id,
[USER_ROLES.TYPIST],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(1);
expect(total).toEqual(1);
});
it('AuthorIDとファイル名で絞り込みができないファイル名が違う', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'AUTHOR_1';
const userInputFileName = 'test.zip';
const { tasks, total } = await service.getTasks(
context,
typist_id,
[USER_ROLES.TYPIST],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(0);
expect(total).toEqual(0);
});
it('AuthorIDとファイル名で絞り込みができないAuthorIDが違う', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'TEST';
const userInputFileName = 'file03.zip';
const { tasks, total } = await service.getTasks(
context,
typist_id,
[USER_ROLES.TYPIST],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(0);
expect(total).toEqual(0);
});
});
describe('[Author] キーワード検索テスト', () => {
let service;
// ユーザーIDadmin
const admin_user_id = 'userId';
// AUTHOR ID 1
const author_id_1 = 'AUTHOR_1';
// AUTHOR ID 2
const author_id_2 = 'AUTHOR_2';
let notificationhubServiceMockValue;
beforeEach(async () => {
notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
if (!source) fail();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
// アカウント作成
const { id: accountId } = await makeTestSimpleAccount(source);
// ユーザー作成admin
const { external_id: adminUser } = await makeTestUser(source, {
account_id: accountId,
external_id: admin_user_id,
role: 'none',
});
// ユーザー作成AUTHOR1
const {
id: authorUser1,
external_id: author1,
author_id: authorId1,
} = await makeTestUser(source, {
account_id: accountId,
external_id: 'author_1',
author_id: author_id_1,
role: 'author',
});
// ユーザー作成AUTHOR2
const {
id: authorUser2,
external_id: author2,
author_id: authorId2,
} = await makeTestUser(source, {
account_id: accountId,
external_id: 'author_2',
author_id: author_id_2,
role: 'author',
});
service = module.get<TasksService>(TasksService);
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: adminUser,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
{
id: author1,
displayName: 'author1',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'author1@example.com',
},
],
},
{
id: author2,
displayName: 'author2',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'author2@example.com',
},
],
},
];
},
});
// タスクデータ作成
for (let i = 0; i < 10; i++) {
await createTask(
source,
accountId,
authorUser1,
authorId1 ?? '',
`WORKTYPE${i + 1}`,
'01',
// 00000001 ~ 00000010
`0000000${String(i + 1).padStart(2, '0')}`,
'Uploaded',
undefined,
true,
`file${String(i + 1).padStart(2, '0')}.zip`,
);
}
for (let i = 10; i < 15; i++) {
await createTask(
source,
accountId,
authorUser2,
authorId2 ?? '',
`WORKTYPE${i + 1}`,
'01',
// 00000011 ~ 00000015
`0000000${String(i + 1).padStart(2, '0')}`,
'Uploaded',
undefined,
true,
`file${String(i + 1).padStart(2, '0')}.zip`,
);
}
});
it('AuthorIDで絞り込みができる', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'AUTHOR_1';
const userInputFileName = undefined;
const { tasks, total } = await service.getTasks(
context,
author_id_1,
[USER_ROLES.AUTHOR],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(10);
expect(total).toEqual(10);
});
it('部分一致でAuthorIDで絞り込みができる', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'UTH';
const userInputFileName = undefined;
const { tasks, total } = await service.getTasks(
context,
author_id_1,
[USER_ROLES.AUTHOR],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(10);
expect(total).toEqual(10);
});
it('AuthorIDで絞り込みができない', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'TEST';
const userInputFileName = undefined;
const { tasks, total } = await service.getTasks(
context,
author_id_1,
[USER_ROLES.AUTHOR],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(0);
expect(total).toEqual(0);
});
it('完全一致でファイル名で絞り込みができる', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = undefined;
const userInputFileName = 'file01.zip';
const { tasks, total } = await service.getTasks(
context,
author_id_1,
[USER_ROLES.AUTHOR],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(1);
expect(total).toEqual(1);
});
it('部分一致でファイル名で絞り込みができる', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = undefined;
const userInputFileName = 'file0';
const { tasks, total } = await service.getTasks(
context,
author_id_1,
[USER_ROLES.AUTHOR],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(9);
expect(total).toEqual(9);
});
it('ファイル名で絞り込みができない', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = undefined;
const userInputFileName = 'test.zip';
const { tasks, total } = await service.getTasks(
context,
author_id_1,
[USER_ROLES.AUTHOR],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(0);
expect(total).toEqual(0);
});
it('完全一致でAuthorIDとファイル名で絞り込みができる', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'AUTHOR_1';
const userInputFileName = 'file01.zip';
const { tasks, total } = await service.getTasks(
context,
author_id_1,
[USER_ROLES.AUTHOR],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(1);
expect(total).toEqual(1);
});
it('部分一致でAuthorIDとファイル名で絞り込みができる', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'UTH';
const userInputFileName = 'file03';
const { tasks, total } = await service.getTasks(
context,
author_id_1,
[USER_ROLES.AUTHOR],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(1);
expect(total).toEqual(1);
});
it('AuthorIDとファイル名で絞り込みができないファイル名が違う', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'AUTHOR_1';
const userInputFileName = 'test.zip';
const { tasks, total } = await service.getTasks(
context,
author_id_1,
[USER_ROLES.AUTHOR],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(0);
expect(total).toEqual(0);
});
it('AuthorIDとファイル名で絞り込みができないAuthorIDが違う', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'TEST';
const userInputFileName = 'file03.zip';
const { tasks, total } = await service.getTasks(
context,
author_id_1,
[USER_ROLES.AUTHOR],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(0);
expect(total).toEqual(0);
});
it('Authorが別のAuthorのタスクをAuthorIDで絞り込みができない', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'AUTHOR_2';
const userInputFileName = undefined;
const { tasks, total } = await service.getTasks(
context,
author_id_1,
[USER_ROLES.AUTHOR],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(0);
expect(total).toEqual(0);
});
it('Authorが別のAuthorのタスクをAuthorIDとファイル名で絞り込みができない', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = undefined;
const userInputFileName = 'file15.zip';
const { tasks, total } = await service.getTasks(
context,
author_id_1,
[USER_ROLES.AUTHOR],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(0);
expect(total).toEqual(0);
});
it('Authorが別のAuthorのタスクをAuthorIDとファイル名で絞り込みができない(ファイル名が違う)', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'AUTHOR_1';
const userInputFileName = 'file15.zip';
const { tasks, total } = await service.getTasks(
context,
author_id_1,
[USER_ROLES.AUTHOR],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(0);
expect(total).toEqual(0);
});
it('Authorが別のAuthorのタスクをAuthorIDとファイル名で絞り込みができない(AuthorIDが違う)', async () => {
const context = makeContext('trackingId', 'requestId');
const offset = 0;
const limit = 20;
const status = ['Uploaded', 'Backup'];
const paramName = 'JOB_NUMBER';
const direction = 'ASC';
const userInputAuthorId = 'AUTHOR_2';
const userInputFileName = 'file01.zip';
const { tasks, total } = await service.getTasks(
context,
author_id_1,
[USER_ROLES.AUTHOR],
offset,
limit,
status,
paramName,
direction,
userInputAuthorId,
userInputFileName,
);
expect(tasks.length).toEqual(0);
expect(total).toEqual(0);
});
});
});
});
describe('changeCheckoutPermission', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
port: 3306,
username: 'user',
password: 'password',
database: 'odms',
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
synchronize: false, // trueにすると自動的にmigrationが行われるため注意
logger: new TestLogger('none'),
logging: true,
});
return await s.initialize();
})();
}
});
beforeEach(async () => {
if (source) {
await truncateAllTable(source);
}
});
afterAll(async () => {
await source?.destroy();
source = null;
});
it('タスクのチェックアウト権限を変更できる。(個人指定)', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId_1 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: typistUserId_2 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-2-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Uploaded',
);
const { userGroupId } = await createUserGroup(
source,
accountId,
'USER_GROUP_A',
[typistUserId_1],
);
await createCheckoutPermissions(source, taskId, typistUserId_1);
await createCheckoutPermissions(source, taskId, undefined, userGroupId);
const service = module.get<TasksService>(TasksService);
const NotificationHubService = module.get<NotificationhubService>(
NotificationhubService,
);
await service.changeCheckoutPermission(
makeContext('trackingId', 'requestId'),
1,
[{ typistName: 'typist-user-2', typistUserId: typistUserId_2 }],
'author-user-external-id',
['admin'],
);
const permisions = await getCheckoutPermissions(source, taskId);
expect(permisions.length).toEqual(1);
expect(permisions[0]).toEqual({
id: 3,
task_id: taskId,
user_id: typistUserId_2,
user_group_id: null,
});
const resultTask = await getTask(source, taskId);
// 通知処理が想定通りの引数で呼ばれているか確認
expect(NotificationHubService.notify).toHaveBeenCalledWith(
makeContext('trackingId', 'requestId'),
`user_${typistUserId_2}`,
{
authorId: 'MY_AUTHOR_ID',
filename: 'x',
id: '2',
priority: 'High',
uploadedAt: resultTask?.file?.uploaded_at.toISOString(),
},
);
});
it('タスクのチェックアウト権限を変更できる。(グループ指定)', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId_1 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: typistUserId_2 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-2-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Uploaded',
);
const { userGroupId: userGroupId_1 } = await createUserGroup(
source,
accountId,
'USER_GROUP_A',
[typistUserId_1],
);
const { userGroupId: userGroupId_2 } = await createUserGroup(
source,
accountId,
'USER_GROUP_B',
[typistUserId_2],
);
await createCheckoutPermissions(source, taskId, typistUserId_1);
await createCheckoutPermissions(source, taskId, undefined, userGroupId_1);
const service = module.get<TasksService>(TasksService);
const NotificationHubService = module.get<NotificationhubService>(
NotificationhubService,
);
await service.changeCheckoutPermission(
makeContext('trackingId', 'requestId'),
1,
[{ typistName: 'USER_GROUP_B', typistGroupId: userGroupId_2 }],
'author-user-external-id',
['admin'],
);
const permisions = await getCheckoutPermissions(source, taskId);
expect(permisions.length).toEqual(1);
expect(permisions[0]).toEqual({
id: 3,
task_id: taskId,
user_id: null,
user_group_id: userGroupId_2,
});
const resultTask = await getTask(source, taskId);
// 通知処理が想定通りの引数で呼ばれているか確認
expect(NotificationHubService.notify).toHaveBeenCalledWith(
makeContext('trackingId', 'requestId'),
`user_${typistUserId_2}`,
{
authorId: 'MY_AUTHOR_ID',
filename: 'x',
id: '2',
priority: 'High',
uploadedAt: resultTask?.file?.uploaded_at.toISOString(),
},
);
});
it('タスクのチェックアウト権限を変更できる。(チェックアウト権限を外す)', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId_1 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Uploaded',
);
const { userGroupId } = await createUserGroup(
source,
accountId,
'USER_GROUP_A',
[typistUserId_1],
);
await createCheckoutPermissions(source, taskId, typistUserId_1);
await createCheckoutPermissions(source, taskId, undefined, userGroupId);
const service = module.get<TasksService>(TasksService);
await service.changeCheckoutPermission(
makeContext('trackingId', 'requestId'),
1,
[],
'author-user-external-id',
['admin'],
);
const permisions = await getCheckoutPermissions(source, taskId);
expect(permisions.length).toEqual(0);
});
it('ユーザーが存在しない場合、タスクのチェックアウト権限を変更できない', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId_1 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Uploaded',
);
const { userGroupId } = await createUserGroup(
source,
accountId,
'USER_GROUP_A',
[typistUserId_1],
);
await createCheckoutPermissions(source, taskId, typistUserId_1);
await createCheckoutPermissions(source, taskId, undefined, userGroupId);
const service = module.get<TasksService>(TasksService);
try {
await service.changeCheckoutPermission(
makeContext('trackingId', 'requestId'),
1,
[{ typistName: 'not-exist-user', typistUserId: 999 }],
'author-user-external-id',
['admin'],
);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010204'));
} else {
fail();
}
}
});
it('ユーザーがメール認証されていない場合、タスクのチェックアウト権限を変更できない', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId_1 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id_1',
role: 'typist',
});
const { id: typistUserId_2 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id_2',
role: 'typist',
email_verified: false,
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Uploaded',
);
const { userGroupId } = await createUserGroup(
source,
accountId,
'USER_GROUP_A',
[typistUserId_1],
);
await createCheckoutPermissions(source, taskId, typistUserId_1);
await createCheckoutPermissions(source, taskId, undefined, userGroupId);
const service = module.get<TasksService>(TasksService);
try {
await service.changeCheckoutPermission(
makeContext('trackingId', 'requestId'),
1,
[{ typistName: 'not-verified-user', typistUserId: typistUserId_2 }],
'author-user-external-id',
['admin'],
);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010204'));
} else {
fail();
}
}
});
it('ユーザーグループが存在しない場合、タスクのチェックアウト権限を変更できない', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId_1 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Uploaded',
);
const { userGroupId } = await createUserGroup(
source,
accountId,
'USER_GROUP_A',
[typistUserId_1],
);
await createCheckoutPermissions(source, taskId, typistUserId_1);
await createCheckoutPermissions(source, taskId, undefined, userGroupId);
const service = module.get<TasksService>(TasksService);
try {
await service.changeCheckoutPermission(
makeContext('trackingId', 'requestId'),
1,
[{ typistName: 'not-exist-user-group', typistGroupId: 999 }],
'author-user-external-id',
['admin'],
),
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010204'));
} else {
fail();
}
}
});
it('タスクが存在しない場合、タスクのチェックアウト権限を変更できない', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const service = module.get<TasksService>(TasksService);
try {
await service.changeCheckoutPermission(
makeContext('trackingId', 'requestId'),
1,
[{ typistName: 'typist-user', typistUserId: typistUserId }],
'author-user-external-id',
['admin'],
),
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010601'));
} else {
fail();
}
}
});
it('タスクのステータスがUploadedでない場合、タスクのチェックアウト権限を変更できない', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Inprogress',
);
const service = module.get<TasksService>(TasksService);
try {
await service.changeCheckoutPermission(
makeContext('trackingId', 'requestId'),
1,
[{ typistName: 'typist-user', typistUserId: typistUserId }],
'author-user-external-id',
['admin'],
),
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010601'));
} else {
fail();
}
}
});
it('ユーザーのRoleがAuthorでタスクのAuthorIDと自身のAuthorIDが一致しない場合、タスクのチェックアウト権限を変更できない', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
await createTask(
source,
accountId,
authorUserId,
'OTHER_AUTHOR_ID',
'',
'01',
'00000001',
'Uploaded',
);
const service = module.get<TasksService>(TasksService);
try {
await service.changeCheckoutPermission(
makeContext('trackingId', 'requestId'),
1,
[{ typistName: 'typist-user', typistUserId: typistUserId }],
'author-user-external-id',
['author'],
),
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010601'));
} else {
fail();
}
}
});
it('通知に失敗した場合、エラーとなる', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
notificationhubServiceMockValue.notify = new Error('Notify Error.');
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId_1 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: typistUserId_2 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-2-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Uploaded',
);
const { userGroupId } = await createUserGroup(
source,
accountId,
'USER_GROUP_A',
[typistUserId_1],
);
await createCheckoutPermissions(source, taskId, typistUserId_1);
await createCheckoutPermissions(source, taskId, undefined, userGroupId);
const service = module.get<TasksService>(TasksService);
try {
await service.changeCheckoutPermission(
makeContext('trackingId', 'requestId'),
1,
[{ typistName: 'typist-user-2', typistUserId: typistUserId_2 }],
'author-user-external-id',
['admin'],
),
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
} else {
fail();
}
}
});
});
describe('checkout', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
port: 3306,
username: 'user',
password: 'password',
database: 'odms',
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
synchronize: false, // trueにすると自動的にmigrationが行われるため注意
logger: new TestLogger('none'),
logging: true,
});
return await s.initialize();
})();
}
});
beforeEach(async () => {
if (source) {
await truncateAllTable(source);
}
});
afterAll(async () => {
await source?.destroy();
source = null;
});
it('ユーザーのRoleがTypistで、タスクのチェックアウト権限が個人指定である時、タスクをチェックアウトできる', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Uploaded',
);
const { userGroupId } = await createUserGroup(
source,
accountId,
'USER_GROUP_A',
[typistUserId],
);
await createCheckoutPermissions(source, taskId, typistUserId);
await createCheckoutPermissions(source, taskId, undefined, userGroupId);
const service = module.get<TasksService>(TasksService);
const initTask = await getTask(source, taskId);
await service.checkout(
makeContext('trackingId', 'requestId'),
1,
['typist'],
'typist-user-external-id',
);
const resultTask = await getTask(source, taskId);
const permisions = await getCheckoutPermissions(source, taskId);
expect(resultTask?.status).toEqual('InProgress');
expect(resultTask?.typist_user_id).toEqual(typistUserId);
expect(resultTask?.started_at).not.toEqual(initTask?.started_at);
expect(permisions.length).toEqual(1);
expect(permisions[0]).toEqual({
id: 3,
task_id: 1,
user_id: 1,
user_group_id: null,
});
});
it('ユーザーのRoleがTypistで、タスクのチェックアウト権限がグループ指定である時、タスクをチェックアウトできる', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Uploaded',
);
const { userGroupId } = await createUserGroup(
source,
accountId,
'USER_GROUP_A',
[typistUserId],
);
await createCheckoutPermissions(source, taskId, typistUserId);
await createCheckoutPermissions(source, taskId, undefined, userGroupId);
const service = module.get<TasksService>(TasksService);
const initTask = await getTask(source, taskId);
await service.checkout(
makeContext('trackingId', 'requestId'),
1,
['typist'],
'typist-user-external-id',
);
const resultTask = await getTask(source, taskId);
const permisions = await getCheckoutPermissions(source, taskId);
expect(resultTask?.status).toEqual('InProgress');
expect(resultTask?.typist_user_id).toEqual(typistUserId);
expect(resultTask?.started_at).not.toEqual(initTask?.started_at);
expect(permisions.length).toEqual(1);
expect(permisions[0]).toEqual({
id: 3,
task_id: 1,
user_id: 1,
user_group_id: null,
});
});
it('ユーザーのRoleがTypistで、タスクのステータスがPendingである時、タスクをチェックアウトできる', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Pending',
);
await createCheckoutPermissions(source, taskId, typistUserId);
const service = module.get<TasksService>(TasksService);
const initTask = await getTask(source, taskId);
await service.checkout(
makeContext('trackingId', 'requestId'),
1,
['typist'],
'typist-user-external-id',
);
const resultTask = await getTask(source, taskId);
const permisions = await getCheckoutPermissions(source, taskId);
expect(resultTask?.status).toEqual('InProgress');
expect(resultTask?.typist_user_id).toEqual(typistUserId);
//タスクの元々のステータスがPending,Inprogressの場合、文字起こし開始時刻は更新されない
expect(resultTask?.started_at).toEqual(initTask?.started_at);
expect(permisions.length).toEqual(1);
expect(permisions[0]).toEqual({
id: 2,
task_id: 1,
user_id: 1,
user_group_id: null,
});
});
it('第五階層のアカウントの場合、有効なライセンスが割当されている場合チェックアウトできる', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウントを作成
const { id: accountId } = await makeTestSimpleAccount(source, { tier: 5 });
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
// 本日の日付を作成
const today = new Date();
// 有効なライセンスを作成して紐づける
await createLicense(
source,
1,
today,
accountId,
LICENSE_TYPE.NORMAL,
LICENSE_ALLOCATED_STATUS.ALLOCATED,
typistUserId,
null,
null,
null,
);
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Pending',
);
await createCheckoutPermissions(source, taskId, typistUserId);
const service = module.get<TasksService>(TasksService);
const initTask = await getTask(source, taskId);
await service.checkout(
makeContext('trackingId', 'requestId'),
1,
['typist'],
'typist-user-external-id',
);
const resultTask = await getTask(source, taskId);
const permisions = await getCheckoutPermissions(source, taskId);
expect(resultTask?.status).toEqual('InProgress');
expect(resultTask?.typist_user_id).toEqual(typistUserId);
//タスクの元々のステータスがPending,Inprogressの場合、文字起こし開始時刻は更新されない
expect(resultTask?.started_at).toEqual(initTask?.started_at);
expect(permisions.length).toEqual(1);
expect(permisions[0]).toEqual({
id: 2,
task_id: 1,
user_id: 1,
user_group_id: null,
});
});
it('ユーザーのRoleがTypistで、対象のタスクのStatus[Uploaded,Inprogress,Pending]以外の時、タスクをチェックアウトできない', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Backup',
);
const service = module.get<TasksService>(TasksService);
try {
await service.checkout(
makeContext('trackingId', 'requestId'),
1,
['typist'],
'typist-user-external-id',
);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toBe(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010601'));
} else {
fail();
}
}
});
it('第五階層のアカウントの場合、ライセンスが未割当の場合チェックアウトできない', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウントを作成
const { id: accountId } = await makeTestSimpleAccount(source, { tier: 5 });
await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Backup',
);
const service = module.get<TasksService>(TasksService);
try {
await service.checkout(
makeContext('trackingId', 'requestId'),
1,
['typist'],
'typist-user-external-id',
);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toBe(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010812'));
} else {
fail();
}
}
});
it('第五階層のアカウントの場合、ライセンスが有効期限切れの場合チェックアウトできない', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウントを作成
const { id: accountId } = await makeTestSimpleAccount(source, { tier: 5 });
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
// 昨日の日付を作成
let yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
yesterday = new DateWithZeroTime(yesterday);
// 期限切れのライセンスを作成して紐づける
await createLicense(
source,
1,
yesterday,
accountId,
LICENSE_TYPE.NORMAL,
LICENSE_ALLOCATED_STATUS.ALLOCATED,
typistUserId,
null,
null,
null,
);
await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Backup',
);
const service = module.get<TasksService>(TasksService);
try {
await service.checkout(
makeContext('trackingId', 'requestId'),
1,
['typist'],
'typist-user-external-id',
);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toBe(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010805'));
} else {
fail();
}
}
});
it('ユーザーのRoleがTypistで、チェックアウト権限が存在しない時、タスクをチェックアウトできない', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Uploaded',
);
const service = module.get<TasksService>(TasksService);
try {
await service.checkout(
makeContext('trackingId', 'requestId'),
1,
['typist'],
'typist-user-external-id',
);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toBe(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010602'));
} else {
fail();
}
}
});
it('ユーザーのRoleがTypistで、既にチェックアウト中のタスクInProgressがある時、タスクをチェックアウトできない', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
TASK_STATUS.IN_PROGRESS,
typistUserId,
);
const { taskId, audioFileId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000002',
TASK_STATUS.UPLOADED,
);
await createCheckoutPermissions(source, taskId, typistUserId);
const service = module.get<TasksService>(TasksService);
try {
await service.checkout(
makeContext('trackingId', 'requestId'),
audioFileId,
['typist'],
'typist-user-external-id',
);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toBe(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010601'));
} else {
fail();
}
}
});
it('ユーザーのRoleがTypistで、別ユーザーによってチェックアウト中のタスクInProgressがある時、タスクをチェックアウトできる', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId1 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id1',
role: 'typist',
});
const { id: typistUserId2 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id2',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
TASK_STATUS.IN_PROGRESS,
typistUserId1,
);
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000002',
TASK_STATUS.UPLOADED,
);
await createCheckoutPermissions(source, taskId, typistUserId2);
const service = module.get<TasksService>(TasksService);
await service.checkout(
makeContext('trackingId', 'requestId'),
2,
['typist'],
'typist-user-external-id2',
);
const resultTask = await getTask(source, taskId);
const permisions = await getCheckoutPermissions(source, taskId);
expect(resultTask?.status).toEqual(TASK_STATUS.IN_PROGRESS);
expect(resultTask?.typist_user_id).toEqual(typistUserId2);
expect(permisions.length).toBe(1);
expect(permisions[0].task_id).toBe(taskId);
expect(permisions[0].user_id).toBe(typistUserId2);
});
it('ユーザーのRoleがAuthorで、アップロードした音声ファイルに紐づいたタスクをチェックアウトできる(Uploaded)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Uploaded',
);
const service = module.get<TasksService>(TasksService);
expect(
await service.checkout(
makeContext('trackingId', 'requestId'),
1,
['author'],
'author-user-external-id',
),
).toEqual(undefined);
});
it('ユーザーのRoleがAuthorで、アップロードした音声ファイルに紐づいたタスクをチェックアウトできる(Finished)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Uploaded',
);
const service = module.get<TasksService>(TasksService);
expect(
await service.checkout(
makeContext('trackingId', 'requestId'),
1,
['author'],
'author-user-external-id',
),
).toEqual(undefined);
});
it('ユーザーのRoleがAuthorで、アップロードした音声ファイルに紐づいたタスクが存在しない場合、タスクをチェックアウトできない', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const service = module.get<TasksService>(TasksService);
try {
await service.checkout(
makeContext('trackingId', 'requestId'),
1,
['author'],
'author-user-external-id',
),
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toBe(HttpStatus.NOT_FOUND);
expect(e.getResponse()).toEqual(makeErrorResponse('E010601'));
} else {
fail();
}
}
});
it('ユーザーのRoleがAuthorで、音声ファイルに紐づいたタスクでユーザーと一致するAuthorIDでない場合、タスクをチェックアウトできない', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
await createTask(
source,
accountId,
authorUserId,
'OTHOR_AUTHOR',
'',
'01',
'00000001',
'Uploaded',
);
const service = module.get<TasksService>(TasksService);
try {
await service.checkout(
makeContext('trackingId', 'requestId'),
1,
['author'],
'author-user-external-id',
);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toBe(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010602'));
} else {
fail();
}
}
});
it('ユーザーのRoleに[Typist,author]が設定されていない時、タスクをチェックアウトできない', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
await makeTestUser(source, {
account_id: accountId,
external_id: 'none-user-external-id',
role: 'none',
author_id: 'MY_AUTHOR_ID',
});
const service = module.get<TasksService>(TasksService);
try {
await service.checkout(
makeContext('trackingId', 'requestId'),
1,
['none'],
'none-user-external-id',
);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toBe(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010602'));
} else {
fail();
}
}
});
});
describe('checkin', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
port: 3306,
username: 'user',
password: 'password',
database: 'odms',
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
synchronize: false, // trueにすると自動的にmigrationが行われるため注意
logger: new TestLogger('none'),
logging: true,
});
return await s.initialize();
})();
}
});
beforeEach(async () => {
if (source) {
await truncateAllTable(source);
}
});
afterAll(async () => {
await source?.destroy();
source = null;
});
it('API実行者が文字起こし実行中のタスクである場合、タスクをチェックインできる', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'InProgress',
typistUserId,
);
await createCheckoutPermissions(source, taskId, typistUserId);
const service = module.get<TasksService>(TasksService);
const initTask = await getTask(source, taskId);
await service.checkin(
makeContext('trackingId', 'requestId'),
1,
'typist-user-external-id',
);
const resultTask = await getTask(source, taskId);
expect(resultTask?.status).toEqual('Finished');
expect(resultTask?.finished_at).not.toEqual(initTask?.finished_at);
}, 600000);
it('タスクのステータスがInprogressでない時、タスクをチェックインできない', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Uploaded',
typistUserId,
);
await createCheckoutPermissions(source, taskId, typistUserId);
const service = module.get<TasksService>(TasksService);
await expect(
service.checkin(
makeContext('trackingId', 'requestId'),
1,
'typist-user-external-id',
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010601'), HttpStatus.BAD_REQUEST),
);
});
it('API実行者が文字起こし実行中のタスクでない場合、タスクをチェックインできない', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: anotherTypistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'another-typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'InProgress',
// API実行者のタスクではないため、typist_user_idは設定しない
);
await createCheckoutPermissions(source, taskId, anotherTypistUserId);
const service = module.get<TasksService>(TasksService);
await expect(
service.checkin(
makeContext('trackingId', 'requestId'),
1,
'typist-user-external-id',
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010601'), HttpStatus.BAD_REQUEST),
);
});
it('タスクがない時、タスクをチェックインできない', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const service = module.get<TasksService>(TasksService);
await expect(
service.checkin(
makeContext('trackingId', 'requestId'),
1,
'typist-user-external-id',
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010603'), HttpStatus.NOT_FOUND),
);
});
it('API実行者が文字起こし実行中のタスクである場合、タスクをチェックインできる。(文字起こし完了メールの送信先がいない場合送信処理はスキップされる)', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { account, admin } = await makeTestAccount(source);
const { id: typistUserId, external_id: typistExternalId } =
await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId, external_id: authorExternalId } =
await makeTestUser(source, {
account_id: account.id,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
notification: false,
});
const { taskId } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'InProgress',
typistUserId,
);
await createCheckoutPermissions(source, taskId, typistUserId);
const service = module.get<TasksService>(TasksService);
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
{
id: typistExternalId,
displayName: 'typist',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'typist@example.com',
},
],
},
{
id: authorExternalId,
displayName: 'author',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'author@example.com',
},
],
},
];
},
});
const spy = jest
.spyOn(service['sendgridService'], 'sendMail')
.mockImplementation();
const initTask = await getTask(source, taskId);
await service.checkin(
makeContext('trackingId', 'requestId'),
1,
'typist-user-external-id',
);
const resultTask = await getTask(source, taskId);
expect(resultTask?.status).toEqual('Finished');
expect(resultTask?.finished_at).not.toEqual(initTask?.finished_at);
//メール送信処理が呼ばれていない
expect(spy).not.toHaveBeenCalled();
});
it('API実行者が文字起こし実行中のタスクである場合、タスクをチェックインできる。(文字起こし完了メールはAuthorだけに送信する)', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { account, admin } = await makeTestAccount(source);
const { id: typistUserId, external_id: typistExternalId } =
await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId, external_id: authorExternalId } =
await makeTestUser(source, {
account_id: account.id,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'InProgress',
typistUserId,
);
await createCheckoutPermissions(source, taskId, typistUserId);
const service = module.get<TasksService>(TasksService);
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
{
id: typistExternalId,
displayName: 'typist',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'typist@example.com',
},
],
},
{
id: authorExternalId,
displayName: 'author',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'author@example.com',
},
],
},
];
},
});
let _to = Array(10);
overrideSendgridService(service, {
sendMail: async (
context: Context,
to: string[],
cc: string[],
from: string,
subject: string,
text: string,
html: string,
) => {
_to = to;
},
});
const initTask = await getTask(source, taskId);
await service.checkin(
makeContext('trackingId', 'requestId'),
1,
'typist-user-external-id',
);
const resultTask = await getTask(source, taskId);
expect(resultTask?.status).toEqual('Finished');
expect(resultTask?.finished_at).not.toEqual(initTask?.finished_at);
//メール送信処理が呼ばれていない
expect(_to.length).toBe(1);
expect(_to).toEqual(['author@example.com']);
});
});
describe('suspend', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
port: 3306,
username: 'user',
password: 'password',
database: 'odms',
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
synchronize: false, // trueにすると自動的にmigrationが行われるため注意
logger: new TestLogger('none'),
logging: true,
});
return await s.initialize();
})();
}
});
beforeEach(async () => {
if (source) {
await truncateAllTable(source);
}
});
afterAll(async () => {
await source?.destroy();
source = null;
});
it('API実行者が文字起こし実行中のタスクである場合、タスクを中断できる', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'InProgress',
typistUserId,
);
const service = module.get<TasksService>(TasksService);
await service.suspend(
makeContext('trackingId', 'requestId'),
1,
'typist-user-external-id',
);
const resultTask = await getTask(source, taskId);
expect(resultTask?.status).toEqual('Pending');
});
it('タスクのステータスがInprogressでない時、タスクを中断できない', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Uploaded',
typistUserId,
);
await createCheckoutPermissions(source, taskId, typistUserId);
const service = module.get<TasksService>(TasksService);
await expect(
service.suspend(
makeContext('trackingId', 'requestId'),
1,
'typist-user-external-id',
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010601'), HttpStatus.BAD_REQUEST),
);
});
it('API実行者が文字起こし実行中のタスクでない場合、タスクを中断できない', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: anotherTypistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'another-typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'InProgress',
anotherTypistUserId,
);
await createCheckoutPermissions(source, taskId, anotherTypistUserId);
const service = module.get<TasksService>(TasksService);
await expect(
service.checkin(
makeContext('trackingId', 'requestId'),
1,
'typist-user-external-id',
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010601'), HttpStatus.BAD_REQUEST),
);
});
it('タスクがない時、タスクを中断できない', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const service = module.get<TasksService>(TasksService);
await expect(
service.checkin(
makeContext('trackingId', 'requestId'),
1,
'typist-user-external-id',
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010603'), HttpStatus.NOT_FOUND),
);
});
});
describe('cancel', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
port: 3306,
username: 'user',
password: 'password',
database: 'odms',
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
synchronize: false, // trueにすると自動的にmigrationが行われるため注意
logger: new TestLogger('none'),
logging: true,
});
return await s.initialize();
})();
}
});
beforeEach(async () => {
if (source) {
await truncateAllTable(source);
}
});
afterAll(async () => {
await source?.destroy();
source = null;
});
it('API実行者のRoleがTypistの場合、自身が文字起こし実行中のタスクをキャンセルできる', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'InProgress',
typistUserId,
);
await createCheckoutPermissions(source, taskId, typistUserId);
const service = module.get<TasksService>(TasksService);
await service.cancel(
makeContext('trackingId', 'requestId'),
1,
'typist-user-external-id',
['typist', 'standard'],
);
const resultTask = await getTask(source, taskId);
const permisions = await getCheckoutPermissions(source, taskId);
expect(resultTask?.status).toEqual('Uploaded');
expect(resultTask?.typist_user_id).toEqual(null);
expect(permisions.length).toEqual(0);
});
it('API実行者のRoleがTypistの場合、自身が文字起こし中断しているタスクをキャンセルできる', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Pending',
typistUserId,
);
await createCheckoutPermissions(source, taskId, typistUserId);
const service = module.get<TasksService>(TasksService);
await service.cancel(
makeContext('trackingId', 'requestId'),
1,
'typist-user-external-id',
['typist', 'standard'],
);
const resultTask = await getTask(source, taskId);
const permisions = await getCheckoutPermissions(source, taskId);
expect(resultTask?.status).toEqual('Uploaded');
expect(resultTask?.typist_user_id).toEqual(null);
expect(permisions.length).toEqual(0);
});
it('API実行者のRoleがAdminの場合、文字起こし実行中のタスクをキャンセルできる', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'InProgress',
typistUserId,
);
await createCheckoutPermissions(source, taskId, typistUserId);
const service = module.get<TasksService>(TasksService);
await service.cancel(
makeContext('trackingId', 'requestId'),
1,
'typist-user-external-id',
['admin', 'author'],
);
const resultTask = await getTask(source, taskId);
const permisions = await getCheckoutPermissions(source, taskId);
expect(resultTask?.status).toEqual('Uploaded');
expect(resultTask?.typist_user_id).toEqual(null);
expect(permisions.length).toEqual(0);
});
it('API実行者のRoleがAdminの場合、文字起こし中断しているタスクをキャンセルできる', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Pending',
typistUserId,
);
await createCheckoutPermissions(source, taskId, typistUserId);
const service = module.get<TasksService>(TasksService);
await service.cancel(
makeContext('trackingId', 'requestId'),
1,
'typist-user-external-id',
['admin', 'author'],
);
const resultTask = await getTask(source, taskId);
const permisions = await getCheckoutPermissions(source, taskId);
expect(resultTask?.status).toEqual('Uploaded');
expect(resultTask?.typist_user_id).toEqual(null);
expect(permisions.length).toEqual(0);
});
it('タスクのステータスが[Inprogress,Pending]でない時、タスクをキャンセルできない', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Uploaded',
typistUserId,
);
await createCheckoutPermissions(source, taskId, typistUserId);
const service = module.get<TasksService>(TasksService);
await expect(
service.cancel(
makeContext('trackingId', 'requestId'),
1,
'typist-user-external-id',
['admin', 'author'],
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010601'), HttpStatus.BAD_REQUEST),
);
});
it('API実行者のRoleがTypistの場合、他人が文字起こし実行中のタスクをキャンセルできない', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: anotherTypistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'another-typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'InProgress',
anotherTypistUserId,
);
await createCheckoutPermissions(source, taskId, anotherTypistUserId);
const service = module.get<TasksService>(TasksService);
await expect(
service.cancel(
makeContext('trackingId', 'requestId'),
1,
'typist-user-external-id',
['typist', 'standard'],
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010601'), HttpStatus.BAD_REQUEST),
);
});
it('タスクがない時、タスクをキャンセルできない', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const service = module.get<TasksService>(TasksService);
await expect(
service.cancel(
makeContext('trackingId', 'requestId'),
1,
'typist-user-external-id',
['typist', 'standard'],
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010603'), HttpStatus.NOT_FOUND),
);
});
it('API実行者のRoleがTypistの場合、自身が文字起こし実行中のタスクをキャンセルし、そのタスクの自動ルーティングを行う', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId, author_id } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'AUTHOR_ID',
});
//ワークタイプIDを作成
await createWorktype(source, accountId, '01');
// テンプレートファイルを作成
const { id: templateFileId } = await createTemplateFile(
source,
accountId,
'template-file-name',
'https://example.com',
);
// ワークフローを作成
const { id: workflowId } = await createWorkflow(
source,
accountId,
authorUserId,
undefined,
templateFileId,
);
// ワークフロータイピストを作成
await createWorkflowTypist(source, workflowId, typistUserId);
const { taskId, audioFileId } = await createTask(
source,
accountId,
authorUserId,
author_id ?? '',
'',
'01',
'00000001',
'InProgress',
typistUserId,
);
await createCheckoutPermissions(source, taskId, typistUserId);
const service = module.get<TasksService>(TasksService);
const NotificationHubService = module.get<NotificationhubService>(
NotificationhubService,
);
await service.cancel(
makeContext('trackingId', 'requestId'),
audioFileId,
'typist-user-external-id',
['typist', 'standard'],
);
const resultTask = await getTask(source, taskId);
const permisions = await getCheckoutPermissions(source, taskId);
expect(resultTask?.status).toEqual('Uploaded');
expect(resultTask?.typist_user_id).toEqual(null);
// タスクのテンプレートファイルIDを確認
expect(resultTask?.template_file_id).toEqual(templateFileId);
// タスクのチェックアウト権限が想定通りワークフローで設定されているのユーザーIDで作成されているか確認
expect(permisions.length).toEqual(1);
expect(permisions[0].user_id).toEqual(typistUserId);
// 通知処理が想定通りの引数で呼ばれているか確認
expect(NotificationHubService.notify).toHaveBeenCalledWith(
makeContext('trackingId', 'requestId'),
`user_${typistUserId}`,
{
authorId: 'AUTHOR_ID',
filename: 'x',
id: '1',
priority: 'High',
uploadedAt: resultTask?.file?.uploaded_at.toISOString(),
},
);
});
it('API実行者のRoleがAuthor,Adminの場合、文字起こし実行中のタスクをキャンセルし、そのタスクの自動ルーティングを行う', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
// タスクの文字起こし担当者
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
// 自動ルーティングされるタイピストユーザーを作成
const { id: autoRoutingTypistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'auto-routing-typist-user-external-id',
role: 'typist',
});
// API実行者
const {
id: myAuthorUserId,
external_id,
role,
} = await makeTestUser(source, {
account_id: accountId,
external_id: 'my-author-user-external-id',
role: 'author admin',
author_id: 'MY_AUTHOR_ID',
});
// 音声ファイルのアップロード者
const { id: authorUserId, author_id } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'AUTHOR_ID',
});
//ワークタイプIDを作成
const { id: workTypeId, custom_worktype_id } = await createWorktype(
source,
accountId,
'01',
);
// テンプレートファイルを作成
const { id: templateFileId } = await createTemplateFile(
source,
accountId,
'template-file-name',
'https://example.com',
);
// ワークフローを作成
const { id: workflowId } = await createWorkflow(
source,
accountId,
authorUserId,
workTypeId,
templateFileId,
);
// ワークフロータイピストを作成
await createWorkflowTypist(source, workflowId, autoRoutingTypistUserId);
const { taskId } = await createTask(
source,
accountId,
authorUserId,
author_id ?? '',
custom_worktype_id,
'01',
'00000001',
'InProgress',
typistUserId,
);
await createCheckoutPermissions(source, taskId, typistUserId);
const service = module.get<TasksService>(TasksService);
const NotificationHubService = module.get<NotificationhubService>(
NotificationhubService,
);
await service.cancel(
makeContext('trackingId', 'requestId'),
1,
external_id,
role.split(' ') as Roles[],
);
const resultTask = await getTask(source, taskId);
const permisions = await getCheckoutPermissions(source, taskId);
expect(resultTask?.status).toEqual('Uploaded');
expect(resultTask?.typist_user_id).toEqual(null);
// タスクのテンプレートファイルIDを確認
expect(resultTask?.template_file_id).toEqual(templateFileId);
// タスクのチェックアウト権限が想定通りワークフローで設定されているのユーザーIDで作成されているか確認
expect(permisions.length).toEqual(1);
expect(permisions[0].user_id).toEqual(autoRoutingTypistUserId);
// 通知処理が想定通りの引数で呼ばれているか確認
expect(NotificationHubService.notify).toHaveBeenCalledWith(
makeContext('trackingId', 'requestId'),
`user_${autoRoutingTypistUserId}`,
{
authorId: 'AUTHOR_ID',
filename: 'x',
id: '2',
priority: 'High',
uploadedAt: resultTask?.file?.uploaded_at.toISOString(),
},
);
});
it('API実行者のRoleがAuthor,Adminの場合、文字起こし実行中のタスクをキャンセルするが、一致するワークフローがない場合は自動ルーティングを行うことができない', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
// タスクの文字起こし担当者
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
// 自動ルーティングされるタイピストユーザーを作成
const { id: autoRoutingTypistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'auto-routing-typist-user-external-id',
role: 'typist',
});
// API実行者
const {
id: myAuthorUserId,
external_id,
role,
author_id: myAuthorId,
} = await makeTestUser(source, {
account_id: accountId,
external_id: 'my-author-user-external-id',
role: 'author admin',
author_id: 'MY_AUTHOR_ID',
});
// 音声ファイルのアップロード者
const { id: authorUserId, author_id } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'AUTHOR_ID',
});
//ワークタイプIDを作成
const { id: workTypeId, custom_worktype_id } = await createWorktype(
source,
accountId,
'01',
);
// テンプレートファイルを作成
const { id: templateFileId } = await createTemplateFile(
source,
accountId,
'template-file-name',
'https://example.com',
);
// ワークフローを作成
const { id: workflowId } = await createWorkflow(
source,
accountId,
authorUserId,
workTypeId,
templateFileId,
);
// ワークフロータイピストを作成
await createWorkflowTypist(source, workflowId, autoRoutingTypistUserId);
const { taskId, audioFileId } = await createTask(
source,
accountId,
myAuthorUserId,
myAuthorId ?? '',
custom_worktype_id,
'01',
'00000001',
'InProgress',
typistUserId,
);
await createCheckoutPermissions(source, taskId, typistUserId);
const service = module.get<TasksService>(TasksService);
const NotificationHubService = module.get<NotificationhubService>(
NotificationhubService,
);
await service.cancel(
makeContext('trackingId', 'requestId'),
audioFileId,
external_id,
role.split(' ') as Roles[],
);
const resultTask = await getTask(source, taskId);
const permisions = await getCheckoutPermissions(source, taskId);
expect(resultTask?.status).toEqual('Uploaded');
expect(resultTask?.typist_user_id).toEqual(null);
// タスクのテンプレートファイルIDを確認
expect(resultTask?.template_file_id).toEqual(null);
// タスクのチェックアウト権限が付与されていないことを確認
expect(permisions.length).toEqual(0);
// 通知処理が想定通りの引数で呼ばれているか確認
expect(NotificationHubService.notify).not.toBeCalled();
});
it('API実行者のRoleがTypistの場合、自身が文字起こし実行中のタスクをキャンセルするが、一致するワークフローがない場合は自動ルーティングを行うことができない', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
// タスクの文字起こし担当者
const {
id: typistUserId,
external_id,
role,
} = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
// 音声ファイルのアップロード者
const { id: authorUserId, author_id } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
author_id ?? '',
'custom_worktype_id',
'01',
'00000001',
'InProgress',
typistUserId,
);
await createCheckoutPermissions(source, taskId, typistUserId);
const service = module.get<TasksService>(TasksService);
const NotificationHubService = module.get<NotificationhubService>(
NotificationhubService,
);
await service.cancel(
makeContext('trackingId', 'requestId'),
1,
external_id,
role.split(' ') as Roles[],
);
const resultTask = await getTask(source, taskId);
const permisions = await getCheckoutPermissions(source, taskId);
expect(resultTask?.status).toEqual('Uploaded');
expect(resultTask?.typist_user_id).toEqual(null);
// タスクのチェックアウト権限が削除されていることを確認
expect(permisions.length).toEqual(0);
// 通知処理が想定通りの引数で呼ばれていないか確認
expect(NotificationHubService.notify).not.toHaveBeenCalled();
});
});
describe('backup', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
port: 3306,
username: 'user',
password: 'password',
database: 'odms',
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
synchronize: false, // trueにすると自動的にmigrationが行われるため注意
logger: new TestLogger('none'),
logging: true,
});
return await s.initialize();
})();
}
});
beforeEach(async () => {
if (source) {
await truncateAllTable(source);
}
});
afterAll(async () => {
await source?.destroy();
source = null;
});
it('文字起こし完了のタスクをバックアップできる', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source);
const { id: authorUserId } = await makeTestUser(source, {
account_id: account.id,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { id: typistUserId } = await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { taskId, audioFileId } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
TASK_STATUS.FINISHED,
typistUserId,
);
// 作成したデータを確認
{
const task = await getTask(source, taskId);
expect(task?.status).toBe(TASK_STATUS.FINISHED);
expect(task?.is_job_number_enabled).toBe(true);
}
const service = module.get<TasksService>(TasksService);
await service.backup(
makeContext(admin.external_id, 'requestId'),
audioFileId,
admin.external_id,
);
// バックアップしたデータを確認
{
const task = await getTask(source, taskId);
expect(task?.status).toBe(TASK_STATUS.BACKUP);
expect(task?.is_job_number_enabled).toBe(false);
}
});
it('文字起こしバックアップ済みのタスクをバックアップできる', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source);
const { id: authorUserId } = await makeTestUser(source, {
account_id: account.id,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { id: typistUserId } = await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { taskId, audioFileId } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
TASK_STATUS.BACKUP,
typistUserId,
false,
);
// 作成したデータを確認
{
const task = await getTask(source, taskId);
expect(task?.status).toBe(TASK_STATUS.BACKUP);
expect(task?.is_job_number_enabled).toBe(false);
}
const service = module.get<TasksService>(TasksService);
await service.backup(
makeContext(admin.external_id, 'requestId'),
audioFileId,
admin.external_id,
);
// バックアップしたデータを確認
{
const task = await getTask(source, taskId);
expect(task?.status).toBe(TASK_STATUS.BACKUP);
expect(task?.is_job_number_enabled).toBe(false);
}
});
it('タスクのステータスが[Finished,Backup]でない時、エラーを返却する', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source);
const { id: authorUserId } = await makeTestUser(source, {
account_id: account.id,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { id: typistUserId } = await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { taskId, audioFileId } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
TASK_STATUS.IN_PROGRESS,
typistUserId,
);
// 作成したデータを確認
{
const task = await getTask(source, taskId);
expect(task?.status).toBe(TASK_STATUS.IN_PROGRESS);
expect(task?.is_job_number_enabled).toBe(true);
}
const service = module.get<TasksService>(TasksService);
try {
await service.backup(
makeContext(admin.external_id, 'requestId'),
audioFileId,
admin.external_id,
);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010601'));
} else {
fail();
}
}
});
it('指定タスクが存在しない時、エラーを返却する', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source);
const { id: authorUserId } = await makeTestUser(source, {
account_id: account.id,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { id: typistUserId } = await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { taskId } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
TASK_STATUS.FINISHED,
typistUserId,
);
// 作成したデータを確認
{
const task = await getTask(source, taskId);
expect(task?.status).toBe(TASK_STATUS.FINISHED);
expect(task?.is_job_number_enabled).toBe(true);
}
const service = module.get<TasksService>(TasksService);
try {
await service.backup(
makeContext(admin.external_id, 'requestId'),
9999, // 存在しないタスクID
admin.external_id,
);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.NOT_FOUND);
expect(e.getResponse()).toEqual(makeErrorResponse('E010603'));
} else {
fail();
}
}
});
it('DBアクセスに失敗した場合、エラーを返却する', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source);
const { id: authorUserId } = await makeTestUser(source, {
account_id: account.id,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { id: typistUserId } = await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { taskId, audioFileId } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
TASK_STATUS.FINISHED,
typistUserId,
);
// 作成したデータを確認
{
const task = await getTask(source, taskId);
expect(task?.status).toBe(TASK_STATUS.FINISHED);
expect(task?.is_job_number_enabled).toBe(true);
}
const service = module.get<TasksService>(TasksService);
//DBアクセスに失敗するようにする
const tasksService = module.get<TasksRepositoryService>(
TasksRepositoryService,
);
tasksService.backup = jest.fn().mockRejectedValue('DB failed');
try {
await service.backup(
makeContext(admin.external_id, 'requestId'),
audioFileId,
admin.external_id,
);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
} else {
fail();
}
}
});
});
describe('getNextTask', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
port: 3306,
username: 'user',
password: 'password',
database: 'odms',
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
synchronize: false, // trueにすると自動的にmigrationが行われるため注意
logger: new TestLogger('none'),
logging: true,
});
return await s.initialize();
})();
}
});
beforeEach(async () => {
if (source) {
await truncateAllTable(source);
}
});
afterAll(async () => {
await source?.destroy();
source = null;
});
it('次タスクを取得できるJobNumber順', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { account, admin } = await makeTestAccount(source, { tier: 5 });
const { id: authorUserId } = await makeTestUser(source, {
account_id: account.id,
author_id: 'AUTHOR_ID',
external_id: 'author-user-external-id',
role: USER_ROLES.AUTHOR,
});
const { id: typistUserId, external_id: typistExternalId } =
await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: USER_ROLES.TYPIST,
});
await updateSortCriteria(source, typistUserId, 'JOB_NUMBER', 'ASC');
const { taskId: taskId1 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
TASK_STATUS.UPLOADED,
);
await createCheckoutPermissions(source, taskId1, typistUserId);
const { taskId: taskId3, audioFileId: audioFileId3 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000003',
TASK_STATUS.UPLOADED,
);
await createCheckoutPermissions(source, taskId3, typistUserId);
const { taskId: taskId2, audioFileId: audioFileId2 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000002',
TASK_STATUS.UPLOADED,
);
await createCheckoutPermissions(source, taskId2, typistUserId);
const service = module.get<TasksService>(TasksService);
const context = makeContext(admin.external_id, 'requestId');
const nextAudioFileId = await service.getNextTask(
context,
typistExternalId,
audioFileId2,
);
// 実行結果が正しいか確認
{
expect(nextAudioFileId).toEqual(audioFileId3);
}
});
it('次タスクを取得できるJobNumber順優先度', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { account, admin } = await makeTestAccount(source, { tier: 5 });
const { id: authorUserId } = await makeTestUser(source, {
account_id: account.id,
author_id: 'AUTHOR_ID',
external_id: 'author-user-external-id',
role: USER_ROLES.AUTHOR,
});
const { id: typistUserId, external_id: typistExternalId } =
await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: USER_ROLES.TYPIST,
});
await createSortCriteria(source, typistUserId, 'JOB_NUMBER', 'ASC');
const { taskId: taskId1, audioFileId: audioFileId1 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'00',
'00000001',
TASK_STATUS.UPLOADED,
);
await createCheckoutPermissions(source, taskId1, typistUserId);
const { taskId: taskId3, audioFileId: audioFileId3 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'00',
'00000003',
TASK_STATUS.UPLOADED,
);
await createCheckoutPermissions(source, taskId3, typistUserId);
const { taskId: taskId2 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000002',
TASK_STATUS.UPLOADED,
);
await createCheckoutPermissions(source, taskId2, typistUserId);
const service = module.get<TasksService>(TasksService);
const context = makeContext(admin.external_id, 'requestId');
const nextAudioFileId = await service.getNextTask(
context,
typistExternalId,
audioFileId1,
);
// 実行結果が正しいか確認
{
expect(nextAudioFileId).toEqual(audioFileId3);
}
});
it('次タスクを取得できるJobNumber順、先頭', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { account, admin } = await makeTestAccount(source, { tier: 5 });
const { id: authorUserId } = await makeTestUser(source, {
account_id: account.id,
author_id: 'AUTHOR_ID',
external_id: 'author-user-external-id',
role: USER_ROLES.AUTHOR,
});
const { id: typistUserId, external_id: typistExternalId } =
await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: USER_ROLES.TYPIST,
});
await updateSortCriteria(source, typistUserId, 'JOB_NUMBER', 'ASC');
const { taskId: taskId1, audioFileId: audioFileId1 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
TASK_STATUS.UPLOADED,
);
await createCheckoutPermissions(source, taskId1, typistUserId);
const { taskId: taskId3, audioFileId: audioFileId3 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000003',
TASK_STATUS.UPLOADED,
);
await createCheckoutPermissions(source, taskId3, typistUserId);
const { taskId: taskId2 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000002',
TASK_STATUS.UPLOADED,
);
await createCheckoutPermissions(source, taskId2, typistUserId);
const service = module.get<TasksService>(TasksService);
const context = makeContext(admin.external_id, 'requestId');
const nextAudioFileId = await service.getNextTask(
context,
typistExternalId,
audioFileId3,
);
// 実行結果が正しいか確認
{
expect(nextAudioFileId).toEqual(audioFileId1);
}
});
it('次タスクを取得できるWorktype順', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { account, admin } = await makeTestAccount(source, { tier: 5 });
const { id: authorUserId } = await makeTestUser(source, {
account_id: account.id,
author_id: 'AUTHOR_ID',
external_id: 'author-user-external-id',
role: USER_ROLES.AUTHOR,
});
const { id: typistUserId, external_id: typistExternalId } =
await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: USER_ROLES.TYPIST,
});
await createSortCriteria(source, typistUserId, 'WORK_TYPE', 'ASC');
const { taskId: taskId1 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'worktype1',
'01',
'00000001',
TASK_STATUS.UPLOADED,
);
await createCheckoutPermissions(source, taskId1, typistUserId);
const { taskId: taskId3, audioFileId: audioFileId3 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'worktype2',
'01',
'00000003',
TASK_STATUS.UPLOADED,
);
await createCheckoutPermissions(source, taskId3, typistUserId);
const { taskId: taskId2, audioFileId: audioFileId2 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'worktype3',
'01',
'00000002',
TASK_STATUS.UPLOADED,
);
await createCheckoutPermissions(source, taskId2, typistUserId);
const service = module.get<TasksService>(TasksService);
const context = makeContext(admin.external_id, 'requestId');
const nextAudioFileId = await service.getNextTask(
context,
typistExternalId,
audioFileId3,
);
// 実行結果が正しいか確認
{
expect(nextAudioFileId).toEqual(audioFileId2);
}
});
it('次タスクを取得できるStatus順', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { account, admin } = await makeTestAccount(source, { tier: 5 });
const { id: authorUserId } = await makeTestUser(source, {
account_id: account.id,
author_id: 'AUTHOR_ID',
external_id: 'author-user-external-id',
role: USER_ROLES.AUTHOR,
});
const { id: typistUserId, external_id: typistExternalId } =
await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: USER_ROLES.TYPIST,
});
await createSortCriteria(source, typistUserId, 'STATUS', 'ASC');
const { taskId: taskId1, audioFileId: audioFileId1 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'worktype1',
'01',
'00000001',
TASK_STATUS.UPLOADED,
);
await createCheckoutPermissions(source, taskId1, typistUserId);
const { taskId: taskId3 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'worktype2',
'01',
'00000003',
TASK_STATUS.UPLOADED,
);
await createCheckoutPermissions(source, taskId3, typistUserId);
const { taskId: taskId2, audioFileId: audioFileId2 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'worktype3',
'01',
'00000002',
TASK_STATUS.PENDING,
);
await createCheckoutPermissions(source, taskId2, typistUserId);
const service = module.get<TasksService>(TasksService);
const context = makeContext(admin.external_id, 'requestId');
const nextAudioFileId = await service.getNextTask(
context,
typistExternalId,
audioFileId2,
);
// 実行結果が正しいか確認
{
expect(nextAudioFileId).toEqual(audioFileId1);
}
});
it('次タスクが存在しない場合undefinedを返すJobNumber順', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { account, admin } = await makeTestAccount(source, { tier: 5 });
const { id: authorUserId } = await makeTestUser(source, {
account_id: account.id,
author_id: 'AUTHOR_ID',
external_id: 'author-user-external-id',
role: USER_ROLES.AUTHOR,
});
const { id: typistUserId, external_id: typistExternalId } =
await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: USER_ROLES.TYPIST,
});
await createSortCriteria(source, typistUserId, 'JOB_NUMBER', 'ASC');
const { taskId: taskId1, audioFileId: audioFileId1 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'worktype1',
'01',
'00000001',
TASK_STATUS.UPLOADED,
);
await createCheckoutPermissions(source, taskId1, typistUserId);
const service = module.get<TasksService>(TasksService);
const context = makeContext(admin.external_id, 'requestId');
const nextAudioFileId = await service.getNextTask(
context,
typistExternalId,
audioFileId1,
);
// 実行結果が正しいか確認
{
expect(nextAudioFileId).toEqual(undefined);
}
});
it('ユーザーの検索条件のAuthorIdの部分一致で次タスクを取得できるJobNumber順', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { account, admin } = await makeTestAccount(source, { tier: 5 });
const { id: authorUserId } = await makeTestUser(source, {
account_id: account.id,
author_id: 'AUTHOR_ID',
external_id: 'author-user-external-id',
role: USER_ROLES.AUTHOR,
});
const { id: typistUserId, external_id: typistExternalId } =
await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: USER_ROLES.TYPIST,
});
await updateSortCriteria(source, typistUserId, 'JOB_NUMBER', 'ASC');
await updateTaskFilter(source, typistUserId, 'MY_AUTHOR', null);
const { taskId: taskId1 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId1, typistUserId);
const { taskId: taskId4, audioFileId: audioFileId4 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000004',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId4, typistUserId);
const { taskId: taskId3, audioFileId: audioFileId3 } = await createTask(
source,
account.id,
authorUserId,
'MY_TEST_ID',
'',
'01',
'00000003',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId3, typistUserId);
const { taskId: taskId2, audioFileId: audioFileId2 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000002',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId2, typistUserId);
const service = module.get<TasksService>(TasksService);
const context = makeContext(admin.external_id, 'requestId');
const nextAudioFileId = await service.getNextTask(
context,
typistExternalId,
audioFileId2,
);
// 実行結果が正しいか確認
{
expect(nextAudioFileId).toEqual(audioFileId4);
}
});
it('ユーザーの検索条件のAuthorIDの完全一致で次タスクを取得できるJobNumber順', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { account, admin } = await makeTestAccount(source, { tier: 5 });
const { id: authorUserId } = await makeTestUser(source, {
account_id: account.id,
author_id: 'AUTHOR_ID',
external_id: 'author-user-external-id',
role: USER_ROLES.AUTHOR,
});
const { id: typistUserId, external_id: typistExternalId } =
await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: USER_ROLES.TYPIST,
});
await updateSortCriteria(source, typistUserId, 'JOB_NUMBER', 'ASC');
await updateTaskFilter(source, typistUserId, 'MY_AUTHOR_ID', null);
const { taskId: taskId1 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId1, typistUserId);
const { taskId: taskId4, audioFileId: audioFileId4 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000004',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId4, typistUserId);
const { taskId: taskId3, audioFileId: audioFileId3 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR',
'',
'01',
'00000003',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId3, typistUserId);
const { taskId: taskId2, audioFileId: audioFileId2 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000002',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId2, typistUserId);
const service = module.get<TasksService>(TasksService);
const context = makeContext(admin.external_id, 'requestId');
const nextAudioFileId = await service.getNextTask(
context,
typistExternalId,
audioFileId2,
);
// 実行結果が正しいか確認
{
expect(nextAudioFileId).toEqual(audioFileId4);
}
});
it('ユーザーの検索条件のファイル名の部分一致で次タスクを取得できるJobNumber順', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { account, admin } = await makeTestAccount(source, { tier: 5 });
const { id: authorUserId } = await makeTestUser(source, {
account_id: account.id,
author_id: 'AUTHOR_ID',
external_id: 'author-user-external-id',
role: USER_ROLES.AUTHOR,
});
const { id: typistUserId, external_id: typistExternalId } =
await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: USER_ROLES.TYPIST,
});
await updateSortCriteria(source, typistUserId, 'JOB_NUMBER', 'ASC');
await updateTaskFilter(source, typistUserId, null, 'FILE');
const { taskId: taskId1, audioFileId: audioFileId1 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId1, typistUserId);
const { taskId: taskId4, audioFileId: audioFileId4 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000004',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId4, typistUserId);
const { taskId: taskId3, audioFileId: audioFileId3 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000003',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId3, typistUserId);
const { taskId: taskId2, audioFileId: audioFileId2 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000002',
TASK_STATUS.UPLOADED,
undefined,
true,
'TEST.txt',
);
await createCheckoutPermissions(source, taskId2, typistUserId);
const service = module.get<TasksService>(TasksService);
const context = makeContext(admin.external_id, 'requestId');
const nextAudioFileId = await service.getNextTask(
context,
typistExternalId,
audioFileId1,
);
// 実行結果が正しいか確認
{
expect(nextAudioFileId).toEqual(audioFileId3);
}
});
it('ユーザーの検索条件のファイル名の完全一致で次タスクを取得できるJobNumber順', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { account, admin } = await makeTestAccount(source, { tier: 5 });
const { id: authorUserId } = await makeTestUser(source, {
account_id: account.id,
author_id: 'AUTHOR_ID',
external_id: 'author-user-external-id',
role: USER_ROLES.AUTHOR,
});
const { id: typistUserId, external_id: typistExternalId } =
await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: USER_ROLES.TYPIST,
});
await updateSortCriteria(source, typistUserId, 'JOB_NUMBER', 'ASC');
await updateTaskFilter(source, typistUserId, null, 'FILE.txt');
const { taskId: taskId1, audioFileId: audioFileId1 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId1, typistUserId);
const { taskId: taskId4, audioFileId: audioFileId4 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000004',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId4, typistUserId);
const { taskId: taskId3, audioFileId: audioFileId3 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000003',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId3, typistUserId);
const { taskId: taskId2, audioFileId: audioFileId2 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000002',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE',
);
await createCheckoutPermissions(source, taskId2, typistUserId);
const service = module.get<TasksService>(TasksService);
const context = makeContext(admin.external_id, 'requestId');
const nextAudioFileId = await service.getNextTask(
context,
typistExternalId,
audioFileId1,
);
// 実行結果が正しいか確認
{
expect(nextAudioFileId).toEqual(audioFileId3);
}
});
it('ユーザーの検索条件のAuthorIDとファイル名の部分一致で次タスクを取得できるJobNumber順', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { account, admin } = await makeTestAccount(source, { tier: 5 });
const { id: authorUserId } = await makeTestUser(source, {
account_id: account.id,
author_id: 'AUTHOR_ID',
external_id: 'author-user-external-id',
role: USER_ROLES.AUTHOR,
});
const { id: typistUserId, external_id: typistExternalId } =
await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: USER_ROLES.TYPIST,
});
await updateSortCriteria(source, typistUserId, 'JOB_NUMBER', 'ASC');
await updateTaskFilter(source, typistUserId, 'Author', 'FILE');
const { taskId: taskId1, audioFileId: audioFileId1 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId1, typistUserId);
const { taskId: taskId4, audioFileId: audioFileId4 } = await createTask(
source,
account.id,
authorUserId,
'MY_TEST_ID',
'',
'01',
'00000004',
TASK_STATUS.UPLOADED,
undefined,
true,
'TEST.txt',
);
await createCheckoutPermissions(source, taskId4, typistUserId);
const { taskId: taskId3, audioFileId: audioFileId3 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000003',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId3, typistUserId);
const { taskId: taskId2, audioFileId: audioFileId2 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000002',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId2, typistUserId);
const service = module.get<TasksService>(TasksService);
const context = makeContext(admin.external_id, 'requestId');
const nextAudioFileId = await service.getNextTask(
context,
typistExternalId,
audioFileId3,
);
// 実行結果が正しいか確認
{
expect(nextAudioFileId).toEqual(audioFileId1);
}
});
it('ユーザーの検索条件のAuthorIDとファイル名の完全一致で次タスクを取得できるJobNumber順', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { account, admin } = await makeTestAccount(source, { tier: 5 });
const { id: authorUserId } = await makeTestUser(source, {
account_id: account.id,
author_id: 'AUTHOR_ID',
external_id: 'author-user-external-id',
role: USER_ROLES.AUTHOR,
});
const { id: typistUserId, external_id: typistExternalId } =
await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: USER_ROLES.TYPIST,
});
await updateSortCriteria(source, typistUserId, 'JOB_NUMBER', 'ASC');
await updateTaskFilter(source, typistUserId, 'MY_AUTHOR_ID', 'FILE.txt');
const { taskId: taskId1, audioFileId: audioFileId1 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId1, typistUserId);
const { taskId: taskId4, audioFileId: audioFileId4 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR',
'',
'01',
'00000004',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE',
);
await createCheckoutPermissions(source, taskId4, typistUserId);
const { taskId: taskId3, audioFileId: audioFileId3 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000003',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId3, typistUserId);
const { taskId: taskId2, audioFileId: audioFileId2 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000002',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId2, typistUserId);
const service = module.get<TasksService>(TasksService);
const context = makeContext(admin.external_id, 'requestId');
const nextAudioFileId = await service.getNextTask(
context,
typistExternalId,
audioFileId3,
);
// 実行結果が正しいか確認
{
expect(nextAudioFileId).toEqual(audioFileId1);
}
});
it('ユーザーの検索条件のAuthorIDとファイル名に一致するタスクが存在しない', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { account, admin } = await makeTestAccount(source, { tier: 5 });
const { id: authorUserId } = await makeTestUser(source, {
account_id: account.id,
author_id: 'AUTHOR_ID',
external_id: 'author-user-external-id',
role: USER_ROLES.AUTHOR,
});
const { id: typistUserId, external_id: typistExternalId } =
await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: USER_ROLES.TYPIST,
});
await updateSortCriteria(source, typistUserId, 'JOB_NUMBER', 'ASC');
await updateTaskFilter(source, typistUserId, 'TEST_ID', 'TEST.txt');
const { taskId: taskId1, audioFileId: audioFileId1 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId1, typistUserId);
const { taskId: taskId4, audioFileId: audioFileId4 } = await createTask(
source,
account.id,
authorUserId,
'MY_Author_ID',
'',
'01',
'00000004',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId4, typistUserId);
const { taskId: taskId3, audioFileId: audioFileId3 } = await createTask(
source,
account.id,
authorUserId,
'TEST_ID',
'',
'01',
'00000003',
TASK_STATUS.FINISHED,
undefined,
true,
'TEST.txt',
);
await createCheckoutPermissions(source, taskId3, typistUserId);
const { taskId: taskId2, audioFileId: audioFileId2 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000002',
TASK_STATUS.UPLOADED,
undefined,
true,
'FILE.txt',
);
await createCheckoutPermissions(source, taskId2, typistUserId);
const service = module.get<TasksService>(TasksService);
const context = makeContext(admin.external_id, 'requestId');
const nextAudioFileId = await service.getNextTask(
context,
typistExternalId,
audioFileId3,
);
// 実行結果が正しいか確認
// 検索条件で一致するタスクが存在しないため、nextAudioFileIdをundefinedで取得する
// 。
{
expect(nextAudioFileId).toEqual(undefined);
}
});
it('指定タスクが存在しない場合エラーを返すJobNumber順', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { account, admin } = await makeTestAccount(source, { tier: 5 });
const { id: authorUserId } = await makeTestUser(source, {
account_id: account.id,
author_id: 'AUTHOR_ID',
external_id: 'author-user-external-id',
role: USER_ROLES.AUTHOR,
});
const { id: typistUserId, external_id: typistExternalId } =
await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: USER_ROLES.TYPIST,
});
await createSortCriteria(source, typistUserId, 'WORK_TYPE', 'ASC');
const { taskId: taskId1, audioFileId: audioFileId1 } = await createTask(
source,
account.id,
authorUserId,
'MY_AUTHOR_ID',
'worktype1',
'01',
'00000001',
TASK_STATUS.UPLOADED,
);
await createCheckoutPermissions(source, taskId1, typistUserId);
const service = module.get<TasksService>(TasksService);
const context = makeContext(admin.external_id, 'requestId');
// 実行結果が正しいか確認
try {
await service.getNextTask(context, typistExternalId, audioFileId1 + 1);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010603'));
} else {
fail();
}
}
});
});
describe('deleteTask', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
port: 3306,
username: 'user',
password: 'password',
database: 'odms',
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
synchronize: false, // trueにすると自動的にmigrationが行われるため注意
logger: new TestLogger('none'),
logging: true,
});
return await s.initialize();
})();
}
});
beforeEach(async () => {
if (source) {
await truncateAllTable(source);
}
});
afterAll(async () => {
await source?.destroy();
source = null;
});
it('管理者として、アカウント内のタスクを削除できる(タスクのStatusがUploaded)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { account, admin } = await makeTestAccount(source, { tier: 5 });
const authorId = 'AUTHOR_ID';
const { id: authorUserId } = await makeTestUser(source, {
account_id: account.id,
author_id: 'AUTHOR_ID',
external_id: 'author-user-external-id',
role: USER_ROLES.AUTHOR,
});
const { id: typistUserId } = await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: USER_ROLES.TYPIST,
});
const { taskId, audioFileId } = await createTask(
source,
account.id,
authorUserId,
authorId,
'',
'01',
'00000001',
TASK_STATUS.UPLOADED,
);
await createCheckoutPermissions(source, taskId, typistUserId);
// 作成したデータを確認
{
const task = await getTask(source, taskId);
const audioFile = await getAudioFile(source, audioFileId);
const checkoutPermissions = await getCheckoutPermissions(source, taskId);
const optionItems = await getAudioOptionItems(source, taskId);
expect(task?.id).toBe(taskId);
expect(task?.status).toBe(TASK_STATUS.UPLOADED);
expect(task?.audio_file_id).toBe(audioFileId);
expect(audioFile?.id).toBe(audioFileId);
expect(audioFile?.file_name).toBe('x.zip');
expect(audioFile?.author_id).toBe(authorId);
expect(checkoutPermissions.length).toBe(1);
expect(checkoutPermissions[0].user_id).toBe(typistUserId);
expect(optionItems.length).toBe(10);
}
const service = module.get<TasksService>(TasksService);
const blobStorageService =
module.get<BlobstorageService>(BlobstorageService);
const context = makeContext(admin.external_id, 'requestId');
overrideBlobstorageService(service, {
deleteFile: jest.fn(),
});
await service.deleteTask(context, admin.external_id, audioFileId);
// 実行結果が正しいか確認
{
const task = await getTask(source, taskId);
const audioFile = await getAudioFile(source, audioFileId);
const checkoutPermissions = await getCheckoutPermissions(source, taskId);
const optionItems = await getAudioOptionItems(source, taskId);
expect(task).toBe(null);
expect(audioFile).toBe(null);
expect(checkoutPermissions.length).toBe(0);
expect(optionItems.length).toBe(0);
// Blob削除メソッドが呼ばれているか確認
expect(blobStorageService.deleteFile).toBeCalledWith(
context,
account.id,
account.country,
'y.zip',
);
}
});
it('Authorとして、自身が追加したタスクを削除できる(タスクのStatusがFinished)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { account } = await makeTestAccount(source, { tier: 5 });
const authorId = 'AUTHOR_ID';
const { id: authorUserId, external_id: authorExternalId } =
await makeTestUser(source, {
account_id: account.id,
author_id: 'AUTHOR_ID',
external_id: 'author-user-external-id',
role: USER_ROLES.AUTHOR,
});
const { id: typistUserId } = await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: USER_ROLES.TYPIST,
});
const { taskId, audioFileId } = await createTask(
source,
account.id,
authorUserId,
authorId,
'',
'01',
'00000001',
TASK_STATUS.FINISHED,
);
await createCheckoutPermissions(source, taskId, typistUserId);
// 作成したデータを確認
{
const task = await getTask(source, taskId);
const audioFile = await getAudioFile(source, audioFileId);
const checkoutPermissions = await getCheckoutPermissions(source, taskId);
const optionItems = await getAudioOptionItems(source, taskId);
expect(task?.id).toBe(taskId);
expect(task?.status).toBe(TASK_STATUS.FINISHED);
expect(task?.audio_file_id).toBe(audioFileId);
expect(audioFile?.id).toBe(audioFileId);
expect(audioFile?.file_name).toBe('x.zip');
expect(audioFile?.author_id).toBe(authorId);
expect(checkoutPermissions.length).toBe(1);
expect(checkoutPermissions[0].user_id).toBe(typistUserId);
expect(optionItems.length).toBe(10);
}
const service = module.get<TasksService>(TasksService);
const blobStorageService =
module.get<BlobstorageService>(BlobstorageService);
const context = makeContext(authorExternalId, 'requestId');
overrideBlobstorageService(service, {
deleteFile: jest.fn(),
});
await service.deleteTask(context, authorExternalId, audioFileId);
// 実行結果が正しいか確認
{
const task = await getTask(source, taskId);
const audioFile = await getAudioFile(source, audioFileId);
const checkoutPermissions = await getCheckoutPermissions(source, taskId);
const optionItems = await getAudioOptionItems(source, taskId);
expect(task).toBe(null);
expect(audioFile).toBe(null);
expect(checkoutPermissions.length).toBe(0);
expect(optionItems.length).toBe(0);
// Blob削除メソッドが呼ばれているか確認
expect(blobStorageService.deleteFile).toBeCalledWith(
context,
account.id,
account.country,
'y.zip',
);
}
});
it('Authorとして、自身が追加したタスクを削除できる(タスクのStatusがBackup)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { account } = await makeTestAccount(source, { tier: 5 });
const authorId = 'AUTHOR_ID';
const { id: authorUserId, external_id: authorExternalId } =
await makeTestUser(source, {
account_id: account.id,
author_id: 'AUTHOR_ID',
external_id: 'author-user-external-id',
role: USER_ROLES.AUTHOR,
});
const { id: typistUserId } = await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: USER_ROLES.TYPIST,
});
const { taskId, audioFileId } = await createTask(
source,
account.id,
authorUserId,
authorId,
'',
'01',
'00000001',
TASK_STATUS.BACKUP,
);
await createCheckoutPermissions(source, taskId, typistUserId);
// 作成したデータを確認
{
const task = await getTask(source, taskId);
const audioFile = await getAudioFile(source, audioFileId);
const checkoutPermissions = await getCheckoutPermissions(source, taskId);
const optionItems = await getAudioOptionItems(source, taskId);
expect(task?.id).toBe(taskId);
expect(task?.status).toBe(TASK_STATUS.BACKUP);
expect(task?.audio_file_id).toBe(audioFileId);
expect(audioFile?.id).toBe(audioFileId);
expect(audioFile?.file_name).toBe('x.zip');
expect(audioFile?.author_id).toBe(authorId);
expect(checkoutPermissions.length).toBe(1);
expect(checkoutPermissions[0].user_id).toBe(typistUserId);
expect(optionItems.length).toBe(10);
}
const service = module.get<TasksService>(TasksService);
const blobStorageService =
module.get<BlobstorageService>(BlobstorageService);
const context = makeContext(authorExternalId, 'requestId');
overrideBlobstorageService(service, {
deleteFile: jest.fn(),
});
await service.deleteTask(context, authorExternalId, audioFileId);
// 実行結果が正しいか確認
{
const task = await getTask(source, taskId);
const audioFile = await getAudioFile(source, audioFileId);
const checkoutPermissions = await getCheckoutPermissions(source, taskId);
const optionItems = await getAudioOptionItems(source, taskId);
expect(task).toBe(null);
expect(audioFile).toBe(null);
expect(checkoutPermissions.length).toBe(0);
expect(optionItems.length).toBe(0);
// Blob削除メソッドが呼ばれているか確認
expect(blobStorageService.deleteFile).toBeCalledWith(
context,
account.id,
account.country,
'y.zip',
);
}
});
it('ステータスがInProgressのタスクを削除しようとした場合、エラーとなること', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { account } = await makeTestAccount(source, { tier: 5 });
const authorId = 'AUTHOR_ID';
const { id: authorUserId, external_id: authorExternalId } =
await makeTestUser(source, {
account_id: account.id,
author_id: 'AUTHOR_ID',
external_id: 'author-user-external-id',
role: USER_ROLES.AUTHOR,
});
const { id: typistUserId } = await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: USER_ROLES.TYPIST,
});
const { taskId, audioFileId } = await createTask(
source,
account.id,
authorUserId,
authorId,
'',
'01',
'00000001',
TASK_STATUS.IN_PROGRESS,
);
await createCheckoutPermissions(source, taskId, typistUserId);
// 作成したデータを確認
{
const task = await getTask(source, taskId);
const audioFile = await getAudioFile(source, audioFileId);
const checkoutPermissions = await getCheckoutPermissions(source, taskId);
const optionItems = await getAudioOptionItems(source, taskId);
expect(task?.id).toBe(taskId);
expect(task?.status).toBe(TASK_STATUS.IN_PROGRESS);
expect(task?.audio_file_id).toBe(audioFileId);
expect(audioFile?.id).toBe(audioFileId);
expect(audioFile?.file_name).toBe('x.zip');
expect(audioFile?.author_id).toBe(authorId);
expect(checkoutPermissions.length).toBe(1);
expect(checkoutPermissions[0].user_id).toBe(typistUserId);
expect(optionItems.length).toBe(10);
}
const service = module.get<TasksService>(TasksService);
const context = makeContext(authorExternalId, 'requestId');
overrideBlobstorageService(service, {
// eslint-disable-next-line @typescript-eslint/no-empty-function
deleteFile: async () => {},
});
try {
await service.deleteTask(context, authorExternalId, audioFileId);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010601'));
} else {
fail();
}
}
});
it('ステータスがPendingのタスクを削除しようとした場合、エラーとなること', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { account } = await makeTestAccount(source, { tier: 5 });
const authorId = 'AUTHOR_ID';
const { id: authorUserId, external_id: authorExternalId } =
await makeTestUser(source, {
account_id: account.id,
author_id: 'AUTHOR_ID',
external_id: 'author-user-external-id',
role: USER_ROLES.AUTHOR,
});
const { id: typistUserId } = await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: USER_ROLES.TYPIST,
});
const { taskId, audioFileId } = await createTask(
source,
account.id,
authorUserId,
authorId,
'',
'01',
'00000001',
TASK_STATUS.PENDING,
);
await createCheckoutPermissions(source, taskId, typistUserId);
// 作成したデータを確認
{
const task = await getTask(source, taskId);
const audioFile = await getAudioFile(source, audioFileId);
const checkoutPermissions = await getCheckoutPermissions(source, taskId);
const optionItems = await getAudioOptionItems(source, taskId);
expect(task?.id).toBe(taskId);
expect(task?.status).toBe(TASK_STATUS.PENDING);
expect(task?.audio_file_id).toBe(audioFileId);
expect(audioFile?.id).toBe(audioFileId);
expect(audioFile?.file_name).toBe('x.zip');
expect(audioFile?.author_id).toBe(authorId);
expect(checkoutPermissions.length).toBe(1);
expect(checkoutPermissions[0].user_id).toBe(typistUserId);
expect(optionItems.length).toBe(10);
}
const service = module.get<TasksService>(TasksService);
const context = makeContext(authorExternalId, 'requestId');
overrideBlobstorageService(service, {
// eslint-disable-next-line @typescript-eslint/no-empty-function
deleteFile: async () => {},
});
try {
await service.deleteTask(context, authorExternalId, audioFileId);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010601'));
} else {
fail();
}
}
});
it('Authorが自身が作成したタスク以外を削除しようとした場合、エラーとなること', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { account } = await makeTestAccount(source, { tier: 5 });
const authorId1 = 'AUTHOR_ID1';
const authorId2 = 'AUTHOR_ID2';
const { id: authorUserId1 } = await makeTestUser(source, {
account_id: account.id,
author_id: authorId1,
external_id: 'author-user-external-id1',
role: USER_ROLES.AUTHOR,
});
const { external_id: authorExternalId2 } = await makeTestUser(source, {
account_id: account.id,
author_id: authorId2,
external_id: 'author-user-external-id2',
role: USER_ROLES.AUTHOR,
});
const { id: typistUserId } = await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: USER_ROLES.TYPIST,
});
const { taskId, audioFileId } = await createTask(
source,
account.id,
authorUserId1,
authorId1,
'',
'01',
'00000001',
TASK_STATUS.UPLOADED,
);
await createCheckoutPermissions(source, taskId, typistUserId);
// 作成したデータを確認
{
const task = await getTask(source, taskId);
const audioFile = await getAudioFile(source, audioFileId);
const checkoutPermissions = await getCheckoutPermissions(source, taskId);
const optionItems = await getAudioOptionItems(source, taskId);
expect(task?.id).toBe(taskId);
expect(task?.status).toBe(TASK_STATUS.UPLOADED);
expect(task?.audio_file_id).toBe(audioFileId);
expect(audioFile?.id).toBe(audioFileId);
expect(audioFile?.file_name).toBe('x.zip');
expect(audioFile?.author_id).toBe(authorId1);
expect(checkoutPermissions.length).toBe(1);
expect(checkoutPermissions[0].user_id).toBe(typistUserId);
expect(optionItems.length).toBe(10);
}
const service = module.get<TasksService>(TasksService);
const context = makeContext(authorExternalId2, 'requestId');
overrideBlobstorageService(service, {
// eslint-disable-next-line @typescript-eslint/no-empty-function
deleteFile: async () => {},
});
try {
await service.deleteTask(context, authorExternalId2, audioFileId);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010602'));
} else {
fail();
}
}
});
it('削除対象タスクが存在しない場合、エラーとなること', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { admin } = await makeTestAccount(source, { tier: 5 });
const service = module.get<TasksService>(TasksService);
const context = makeContext(admin.external_id, 'requestId');
overrideBlobstorageService(service, {
// eslint-disable-next-line @typescript-eslint/no-empty-function
deleteFile: async () => {},
});
try {
await service.deleteTask(context, admin.external_id, 1);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010603'));
} else {
fail();
}
}
});
it('タスクのDB削除に失敗した場合、エラーとなること', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { account } = await makeTestAccount(source, { tier: 5 });
const authorId = 'AUTHOR_ID';
const { id: authorUserId, external_id: authorExternalId } =
await makeTestUser(source, {
account_id: account.id,
author_id: 'AUTHOR_ID',
external_id: 'author-user-external-id',
role: USER_ROLES.AUTHOR,
});
const { id: typistUserId } = await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: USER_ROLES.TYPIST,
});
const { taskId, audioFileId } = await createTask(
source,
account.id,
authorUserId,
authorId,
'',
'01',
'00000001',
TASK_STATUS.UPLOADED,
);
await createCheckoutPermissions(source, taskId, typistUserId);
// 作成したデータを確認
{
const task = await getTask(source, taskId);
const audioFile = await getAudioFile(source, audioFileId);
const checkoutPermissions = await getCheckoutPermissions(source, taskId);
const optionItems = await getAudioOptionItems(source, taskId);
expect(task?.id).toBe(taskId);
expect(task?.status).toBe(TASK_STATUS.UPLOADED);
expect(task?.audio_file_id).toBe(audioFileId);
expect(audioFile?.id).toBe(audioFileId);
expect(audioFile?.file_name).toBe('x.zip');
expect(audioFile?.author_id).toBe(authorId);
expect(checkoutPermissions.length).toBe(1);
expect(checkoutPermissions[0].user_id).toBe(typistUserId);
expect(optionItems.length).toBe(10);
}
const service = module.get<TasksService>(TasksService);
const context = makeContext(authorExternalId, 'requestId');
// DBアクセスに失敗するようにする
const tasksRepositoryService = module.get<TasksRepositoryService>(
TasksRepositoryService,
);
tasksRepositoryService.deleteTask = jest
.fn()
.mockRejectedValue('DB failed');
overrideBlobstorageService(service, {
// eslint-disable-next-line @typescript-eslint/no-empty-function
deleteFile: async () => {},
});
try {
await service.deleteTask(context, authorExternalId, audioFileId);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
} else {
fail();
}
}
});
it('blobストレージからの音声ファイル削除に失敗した場合でも、エラーとならないこと', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
const { account, admin } = await makeTestAccount(source, { tier: 5 });
const authorId = 'AUTHOR_ID';
const { id: authorUserId } = await makeTestUser(source, {
account_id: account.id,
author_id: 'AUTHOR_ID',
external_id: 'author-user-external-id',
role: USER_ROLES.AUTHOR,
});
const { id: typistUserId } = await makeTestUser(source, {
account_id: account.id,
external_id: 'typist-user-external-id',
role: USER_ROLES.TYPIST,
});
const { taskId, audioFileId } = await createTask(
source,
account.id,
authorUserId,
authorId,
'',
'01',
'00000001',
TASK_STATUS.UPLOADED,
);
await createCheckoutPermissions(source, taskId, typistUserId);
// 作成したデータを確認
{
const task = await getTask(source, taskId);
const audioFile = await getAudioFile(source, audioFileId);
const checkoutPermissions = await getCheckoutPermissions(source, taskId);
const optionItems = await getAudioOptionItems(source, taskId);
expect(task?.id).toBe(taskId);
expect(task?.status).toBe(TASK_STATUS.UPLOADED);
expect(task?.audio_file_id).toBe(audioFileId);
expect(audioFile?.id).toBe(audioFileId);
expect(audioFile?.file_name).toBe('x.zip');
expect(audioFile?.author_id).toBe(authorId);
expect(checkoutPermissions.length).toBe(1);
expect(checkoutPermissions[0].user_id).toBe(typistUserId);
expect(optionItems.length).toBe(10);
}
const service = module.get<TasksService>(TasksService);
const context = makeContext(admin.external_id, 'requestId');
overrideBlobstorageService(service, {
deleteFile: async () => {
throw new Error('blob failed');
},
});
await service.deleteTask(context, admin.external_id, audioFileId);
// 実行結果が正しいか確認
{
const task = await getTask(source, taskId);
const audioFile = await getAudioFile(source, audioFileId);
const checkoutPermissions = await getCheckoutPermissions(source, taskId);
const optionItems = await getAudioOptionItems(source, taskId);
expect(task).toBe(null);
expect(audioFile).toBe(null);
expect(checkoutPermissions.length).toBe(0);
expect(optionItems.length).toBe(0);
}
});
});
describe('reopen', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
port: 3306,
username: 'user',
password: 'password',
database: 'odms',
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
synchronize: false, // trueにすると自動的にmigrationが行われるため注意
logger: new TestLogger('none'),
logging: true,
});
return await s.initialize();
})();
}
});
beforeEach(async () => {
if (source) {
await truncateAllTable(source);
}
});
afterAll(async () => {
await source?.destroy();
source = null;
});
it('API実行者のRoleがTypistの場合、自身が担当する完了済みの文字起こしタスクを再開できる', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Finished',
typistUserId,
);
await createCheckoutPermissions(source, taskId, typistUserId);
const service = module.get<TasksService>(TasksService);
await service.reopen(
makeContext('trackingId', 'requestId'),
1,
'typist-user-external-id',
['typist', 'standard'],
);
const resultTask = await getTask(source, taskId);
expect(resultTask?.status).toEqual('Pending');
expect(resultTask?.finished_at).toEqual(null);
});
it('API実行者のRoleがAdminの場合、完了済みの文字起こしタスクを再開できる', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Finished',
typistUserId,
);
await createCheckoutPermissions(source, taskId, typistUserId);
const service = module.get<TasksService>(TasksService);
await service.reopen(
makeContext('trackingId', 'requestId'),
1,
'typist-user-external-id',
['admin', 'standard'],
);
const resultTask = await getTask(source, taskId);
expect(resultTask?.status).toEqual('Pending');
expect(resultTask?.finished_at).toEqual(null);
});
it('タスクのステータスが[Finished]でない時、タスクを再開できない', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Uploaded',
typistUserId,
);
await createCheckoutPermissions(source, taskId, typistUserId);
const service = module.get<TasksService>(TasksService);
await expect(
service.reopen(
makeContext('trackingId', 'requestId'),
1,
'typist-user-external-id',
['admin', 'author'],
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010601'), HttpStatus.BAD_REQUEST),
);
});
it('API実行者のRoleがTypistの場合、他人の終了済み文字起こしタスクを再開できない', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: anotherTypistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'another-typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Finished',
anotherTypistUserId,
);
await createCheckoutPermissions(source, taskId, anotherTypistUserId);
const service = module.get<TasksService>(TasksService);
await expect(
service.reopen(
makeContext('trackingId', 'requestId'),
1,
'typist-user-external-id',
['typist', 'standard'],
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010601'), HttpStatus.BAD_REQUEST),
);
});
it('API実行者のRoleがAuthorの場合、他人が終了済み文字起こしタスクを再開できない', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
const { id: anotherTypistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'another-typist-user-external-id',
role: 'typist',
});
const { id: authorUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const { taskId } = await createTask(
source,
accountId,
authorUserId,
'MY_AUTHOR_ID',
'',
'01',
'00000001',
'Finished',
anotherTypistUserId,
);
await createCheckoutPermissions(source, taskId, anotherTypistUserId);
const service = module.get<TasksService>(TasksService);
await expect(
service.reopen(
makeContext('trackingId', 'requestId'),
1,
'author-user-external-id',
['author', 'standard'],
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010601'), HttpStatus.BAD_REQUEST),
);
});
it('タスクがない時、タスクを再開できない', async () => {
if (!source) fail();
const notificationhubServiceMockValue =
makeDefaultNotificationhubServiceMockValue();
const module = await makeTaskTestingModuleWithNotificaiton(
source,
notificationhubServiceMockValue,
);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
});
await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'MY_AUTHOR_ID',
});
const service = module.get<TasksService>(TasksService);
await expect(
service.reopen(
makeContext('trackingId', 'requestId'),
1,
'typist-user-external-id',
['typist', 'standard'],
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010603'), HttpStatus.NOT_FOUND),
);
});
});