## 概要 [Task3121: バックアップAPI実装](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3121) - タスクのバックアップAPIとテストを実装しました。 - 実装に当たり、タスクエンティティ定義の型を修正しています。 ## レビューポイント - テストケースに過不足はないでしょうか? - エンティティの値を取得した際に`is_job_number_enabled`が数値となってしまうのでtypeをBooleanに変更しましたが問題ないでしょうか? ## UIの変更 - なし ## 動作確認状況 - ローカルで確認
3746 lines
113 KiB
TypeScript
3746 lines
113 KiB
TypeScript
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 {
|
||
createCheckoutPermissions,
|
||
createTask,
|
||
createUserGroup,
|
||
getCheckoutPermissions,
|
||
getTask,
|
||
makeTaskTestingModuleWithNotificaiton,
|
||
} from './test/utility';
|
||
import { Adb2cTooManyRequestsError } from '../../gateways/adb2c/adb2c.service';
|
||
import { makeContext } from '../../common/log';
|
||
import {
|
||
makeTestAccount,
|
||
makeTestSimpleAccount,
|
||
makeTestUser,
|
||
} from '../../common/test/utility';
|
||
import { ADMIN_ROLES, TASK_STATUS, USER_ROLES } from '../../constants';
|
||
import { makeTestingModule } from '../../common/test/modules';
|
||
import { createSortCriteria } from '../users/test/utility';
|
||
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';
|
||
|
||
describe('TasksService', () => {
|
||
it('タスク一覧を取得できる(admin)', async () => {
|
||
const tasksRepositoryMockValue = makeDefaultTasksRepositoryMockValue();
|
||
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
|
||
const userGroupsRepositoryMockValue =
|
||
makeDefaultUserGroupsRepositoryMockValue();
|
||
const adb2cServiceMockValue = makeDefaultAdb2cServiceMockValue();
|
||
const notificationhubServiceMockValue =
|
||
makeDefaultNotificationhubServiceMockValue();
|
||
const service = await makeTasksServiceMock(
|
||
tasksRepositoryMockValue,
|
||
usersRepositoryMockValue,
|
||
userGroupsRepositoryMockValue,
|
||
adb2cServiceMockValue,
|
||
notificationhubServiceMockValue,
|
||
);
|
||
|
||
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'),
|
||
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',
|
||
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();
|
||
usersRepositoryMockValue.findUserByExternalId = new Error('DB failed');
|
||
const service = await makeTasksServiceMock(
|
||
tasksRepositoryMockValue,
|
||
usersRepositoryMockValue,
|
||
userGroupsRepositoryMockValue,
|
||
adb2cServiceMockValue,
|
||
notificationhubServiceMockValue,
|
||
);
|
||
|
||
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'),
|
||
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();
|
||
tasksRepositoryMockValue.getTasksFromAccountId = new Error('DB failed');
|
||
const service = await makeTasksServiceMock(
|
||
tasksRepositoryMockValue,
|
||
usersRepositoryMockValue,
|
||
userGroupsRepositoryMockValue,
|
||
adb2cServiceMockValue,
|
||
notificationhubServiceMockValue,
|
||
);
|
||
|
||
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'),
|
||
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',
|
||
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 service = await makeTasksServiceMock(
|
||
tasksRepositoryMockValue,
|
||
usersRepositoryMockValue,
|
||
userGroupsRepositoryMockValue,
|
||
adb2cServiceMockValue,
|
||
notificationhubServiceMockValue,
|
||
);
|
||
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'),
|
||
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();
|
||
if (usersRepositoryMockValue.findUserByExternalId instanceof Error) {
|
||
return;
|
||
}
|
||
usersRepositoryMockValue.findUserByExternalId.role = 'author';
|
||
const service = await makeTasksServiceMock(
|
||
tasksRepositoryMockValue,
|
||
usersRepositoryMockValue,
|
||
userGroupsRepositoryMockValue,
|
||
adb2cServiceMockValue,
|
||
notificationhubServiceMockValue,
|
||
);
|
||
|
||
const userId = 'userId';
|
||
const offset = 0;
|
||
const limit = 20;
|
||
const status = ['Uploaded', 'Backup'];
|
||
const paramName = 'JOB_NUMBER';
|
||
const direction = 'ASC';
|
||
const result = await service.tasksService.getTasks(
|
||
makeContext('trackingId'),
|
||
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',
|
||
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('abcdef', 1, 0, 20, 'JOB_NUMBER', 'ASC', [
|
||
'Uploaded',
|
||
'Backup',
|
||
]);
|
||
});
|
||
|
||
it('タスク一覧の取得に失敗した場合、エラーを返却する(author)', async () => {
|
||
const tasksRepositoryMockValue = makeDefaultTasksRepositoryMockValue();
|
||
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
|
||
const userGroupsRepositoryMockValue =
|
||
makeDefaultUserGroupsRepositoryMockValue();
|
||
const adb2cServiceMockValue = makeDefaultAdb2cServiceMockValue();
|
||
const notificationhubServiceMockValue =
|
||
makeDefaultNotificationhubServiceMockValue();
|
||
tasksRepositoryMockValue.getTasksFromAuthorIdAndAccountId = new Error(
|
||
'DB failed',
|
||
);
|
||
const service = await makeTasksServiceMock(
|
||
tasksRepositoryMockValue,
|
||
usersRepositoryMockValue,
|
||
userGroupsRepositoryMockValue,
|
||
adb2cServiceMockValue,
|
||
notificationhubServiceMockValue,
|
||
);
|
||
|
||
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'),
|
||
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();
|
||
if (usersRepositoryMockValue.findUserByExternalId instanceof Error) {
|
||
return;
|
||
}
|
||
usersRepositoryMockValue.findUserByExternalId.role = 'typist';
|
||
|
||
const service = await makeTasksServiceMock(
|
||
tasksRepositoryMockValue,
|
||
usersRepositoryMockValue,
|
||
userGroupsRepositoryMockValue,
|
||
adb2cServiceMockValue,
|
||
notificationhubServiceMockValue,
|
||
);
|
||
|
||
const userId = 'userId';
|
||
const offset = 0;
|
||
const limit = 20;
|
||
const status = ['Uploaded', 'Backup'];
|
||
const paramName = 'JOB_NUMBER';
|
||
const direction = 'ASC';
|
||
const result = await service.tasksService.getTasks(
|
||
makeContext('trackingId'),
|
||
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',
|
||
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('userId', 0, 20, 'JOB_NUMBER', 'ASC', [
|
||
'Uploaded',
|
||
'Backup',
|
||
]);
|
||
});
|
||
|
||
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 service = await makeTasksServiceMock(
|
||
tasksRepositoryMockValue,
|
||
usersRepositoryMockValue,
|
||
userGroupsRepositoryMockValue,
|
||
adb2cServiceMockValue,
|
||
notificationhubServiceMockValue,
|
||
);
|
||
|
||
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'),
|
||
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();
|
||
adb2cServiceMockValue.getUsers = new Adb2cTooManyRequestsError();
|
||
const service = await makeTasksServiceMock(
|
||
tasksRepositoryMockValue,
|
||
usersRepositoryMockValue,
|
||
userGroupsRepositoryMockValue,
|
||
adb2cServiceMockValue,
|
||
notificationhubServiceMockValue,
|
||
);
|
||
|
||
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'),
|
||
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;
|
||
beforeEach(async () => {
|
||
source = new DataSource({
|
||
type: 'sqlite',
|
||
database: ':memory:',
|
||
logging: false,
|
||
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
|
||
synchronize: true, // trueにすると自動的にmigrationが行われるため注意
|
||
});
|
||
return source.initialize();
|
||
});
|
||
|
||
afterEach(async () => {
|
||
if (!source) return;
|
||
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'),
|
||
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',
|
||
});
|
||
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'),
|
||
external_id,
|
||
[USER_ROLES.AUTHOR],
|
||
offset,
|
||
limit,
|
||
status,
|
||
paramName,
|
||
direction,
|
||
);
|
||
|
||
expect(total).toEqual(2);
|
||
{
|
||
const task = tasks[0];
|
||
expect(task.jobNumber).toEqual('00000001');
|
||
}
|
||
{
|
||
const task = tasks[1];
|
||
expect(task.jobNumber).toEqual('00000002');
|
||
}
|
||
});
|
||
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'),
|
||
external_id,
|
||
[USER_ROLES.AUTHOR],
|
||
offset,
|
||
limit,
|
||
status,
|
||
paramName,
|
||
direction,
|
||
);
|
||
expect(total).toEqual(1);
|
||
{
|
||
const task = tasks[0];
|
||
expect(task.jobNumber).toEqual('00000001');
|
||
}
|
||
});
|
||
});
|
||
});
|
||
|
||
describe('changeCheckoutPermission', () => {
|
||
let source: DataSource | null = null;
|
||
beforeEach(async () => {
|
||
source = new DataSource({
|
||
type: 'sqlite',
|
||
database: ':memory:',
|
||
logging: false,
|
||
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
|
||
synchronize: true, // trueにすると自動的にmigrationが行われるため注意
|
||
});
|
||
return source.initialize();
|
||
});
|
||
|
||
afterEach(async () => {
|
||
if (!source) return;
|
||
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'),
|
||
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'),
|
||
[`user_${typistUserId_2}`],
|
||
{
|
||
authorId: 'MY_AUTHOR_ID',
|
||
filename: 'x',
|
||
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'),
|
||
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'),
|
||
[`user_${typistUserId_2}`],
|
||
{
|
||
authorId: 'MY_AUTHOR_ID',
|
||
filename: 'x',
|
||
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'),
|
||
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'),
|
||
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'),
|
||
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'),
|
||
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'),
|
||
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'),
|
||
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'),
|
||
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'),
|
||
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;
|
||
beforeEach(async () => {
|
||
source = new DataSource({
|
||
type: 'sqlite',
|
||
database: ':memory:',
|
||
logging: false,
|
||
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
|
||
synchronize: true, // trueにすると自動的にmigrationが行われるため注意
|
||
});
|
||
return source.initialize();
|
||
});
|
||
|
||
afterEach(async () => {
|
||
if (!source) return;
|
||
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'),
|
||
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'),
|
||
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'),
|
||
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',
|
||
author_id: 'MY_AUTHOR_ID',
|
||
});
|
||
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'),
|
||
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('ユーザーの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',
|
||
author_id: 'MY_AUTHOR_ID',
|
||
});
|
||
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'),
|
||
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'),
|
||
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'),
|
||
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'),
|
||
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'),
|
||
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'),
|
||
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'),
|
||
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'),
|
||
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;
|
||
beforeEach(async () => {
|
||
source = new DataSource({
|
||
type: 'sqlite',
|
||
database: ':memory:',
|
||
logging: false,
|
||
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
|
||
synchronize: true, // trueにすると自動的にmigrationが行われるため注意
|
||
});
|
||
return source.initialize();
|
||
});
|
||
|
||
afterEach(async () => {
|
||
if (!source) return;
|
||
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'),
|
||
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);
|
||
});
|
||
|
||
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'), 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'), 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'), 1, 'typist-user-external-id'),
|
||
).rejects.toEqual(
|
||
new HttpException(makeErrorResponse('E010603'), HttpStatus.NOT_FOUND),
|
||
);
|
||
});
|
||
});
|
||
|
||
describe('suspend', () => {
|
||
let source: DataSource | null = null;
|
||
beforeEach(async () => {
|
||
source = new DataSource({
|
||
type: 'sqlite',
|
||
database: ':memory:',
|
||
logging: false,
|
||
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
|
||
synchronize: true, // trueにすると自動的にmigrationが行われるため注意
|
||
});
|
||
return source.initialize();
|
||
});
|
||
|
||
afterEach(async () => {
|
||
if (!source) return;
|
||
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'),
|
||
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'), 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'), 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'), 1, 'typist-user-external-id'),
|
||
).rejects.toEqual(
|
||
new HttpException(makeErrorResponse('E010603'), HttpStatus.NOT_FOUND),
|
||
);
|
||
});
|
||
});
|
||
|
||
describe('cancel', () => {
|
||
let source: DataSource | null = null;
|
||
beforeEach(async () => {
|
||
source = new DataSource({
|
||
type: 'sqlite',
|
||
database: ':memory:',
|
||
logging: false,
|
||
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
|
||
synchronize: true, // trueにすると自動的にmigrationが行われるため注意
|
||
});
|
||
return source.initialize();
|
||
});
|
||
|
||
afterEach(async () => {
|
||
if (!source) return;
|
||
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'),
|
||
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'),
|
||
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'),
|
||
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'),
|
||
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'), 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'), 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'), 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 } = 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'),
|
||
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);
|
||
// タスクのテンプレートファイル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'),
|
||
[`user_${typistUserId}`],
|
||
{
|
||
authorId: 'AUTHOR_ID',
|
||
filename: 'x',
|
||
priority: 'High',
|
||
uploadedAt: resultTask?.file?.uploaded_at.toISOString(),
|
||
},
|
||
);
|
||
});
|
||
|
||
it('API実行者のRoleがAdminの場合、自身が文字起こし実行中のタスクをキャンセルし、そのタスクの自動ルーティングを行う(API実行者のAuthorIDと音声ファイルに紐づくWorkType)', 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,
|
||
myAuthorUserId,
|
||
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'),
|
||
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'),
|
||
[`user_${autoRoutingTypistUserId}`],
|
||
{
|
||
authorId: 'AUTHOR_ID',
|
||
filename: 'x',
|
||
priority: 'High',
|
||
uploadedAt: resultTask?.file?.uploaded_at.toISOString(),
|
||
},
|
||
);
|
||
});
|
||
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'),
|
||
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;
|
||
beforeEach(async () => {
|
||
source = new DataSource({
|
||
type: 'sqlite',
|
||
database: ':memory:',
|
||
logging: false,
|
||
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
|
||
synchronize: true, // trueにすると自動的にmigrationが行われるため注意
|
||
});
|
||
return source.initialize();
|
||
});
|
||
|
||
afterEach(async () => {
|
||
if (!source) return;
|
||
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),
|
||
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),
|
||
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),
|
||
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),
|
||
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),
|
||
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;
|
||
beforeEach(async () => {
|
||
source = new DataSource({
|
||
type: 'sqlite',
|
||
database: ':memory:',
|
||
logging: false,
|
||
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
|
||
synchronize: true, // trueにすると自動的にmigrationが行われるため注意
|
||
});
|
||
return source.initialize();
|
||
});
|
||
|
||
afterEach(async () => {
|
||
if (!source) return;
|
||
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 createSortCriteria(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);
|
||
|
||
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);
|
||
|
||
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 createSortCriteria(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);
|
||
|
||
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);
|
||
|
||
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);
|
||
|
||
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);
|
||
|
||
const nextAudioFileId = await service.getNextTask(
|
||
context,
|
||
typistExternalId,
|
||
audioFileId1,
|
||
);
|
||
|
||
// 実行結果が正しいか確認
|
||
{
|
||
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);
|
||
|
||
// 実行結果が正しいか確認
|
||
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();
|
||
}
|
||
}
|
||
});
|
||
});
|