Merged PR 205: API実装(タスクチェックアウトAPI (Author))
## 概要 [Task2009: API実装(タスクチェックアウトAPI (Author))](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2009) - タスクチェックアウトAPIのAuthorユーザーの動作を実装しました。 - 対応するタスクがあるかを確認だけして特に変更はしていません。 - 対応タスクを追加しました。 ## レビューポイント - 実装内容は認識通りか - テスト内容に不足はないか ## UIの変更 なし ## 動作確認状況 - ローカルで確認
This commit is contained in:
parent
8c5f5b61c1
commit
dadbc550c6
@ -1086,6 +1086,7 @@ describe('checkout', () => {
|
||||
await source.destroy();
|
||||
source = null;
|
||||
});
|
||||
|
||||
it('ユーザーのRoleがTypistで、タスクのチェックアウト権限が個人指定である時、タスクをチェックアウトできる', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
const { accountId } = await createAccount(source);
|
||||
@ -1326,6 +1327,108 @@ describe('checkout', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('ユーザーのRoleがAuthorで、アップロードした音声ファイルに紐づいたタスクをチェックアウトできる(Uploaded)', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
const { accountId } = await createAccount(source);
|
||||
const { userId: authorUserId } = await createUser(
|
||||
source,
|
||||
accountId,
|
||||
'author-user-external-id',
|
||||
'author',
|
||||
'MY_AUTHOR_ID',
|
||||
);
|
||||
await createTask(
|
||||
source,
|
||||
accountId,
|
||||
authorUserId,
|
||||
'MY_AUTHOR_ID',
|
||||
'',
|
||||
'01',
|
||||
'00000001',
|
||||
'Uploaded',
|
||||
);
|
||||
|
||||
const service = module.get<TasksService>(TasksService);
|
||||
expect(
|
||||
await service.checkout(1, ['author'], 'author-user-external-id'),
|
||||
).toEqual(undefined);
|
||||
});
|
||||
|
||||
it('ユーザーのRoleがAuthorで、アップロードした音声ファイルに紐づいたタスクをチェックアウトできる(Finished)', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
const { accountId } = await createAccount(source);
|
||||
const { userId: authorUserId } = await createUser(
|
||||
source,
|
||||
accountId,
|
||||
'author-user-external-id',
|
||||
'author',
|
||||
'MY_AUTHOR_ID',
|
||||
);
|
||||
await createTask(
|
||||
source,
|
||||
accountId,
|
||||
authorUserId,
|
||||
'MY_AUTHOR_ID',
|
||||
'',
|
||||
'01',
|
||||
'00000001',
|
||||
'Uploaded',
|
||||
);
|
||||
|
||||
const service = module.get<TasksService>(TasksService);
|
||||
expect(
|
||||
await service.checkout(1, ['author'], 'author-user-external-id'),
|
||||
).toEqual(undefined);
|
||||
});
|
||||
|
||||
it('ユーザーのRoleがAuthorで、アップロードした音声ファイルに紐づいたタスクが存在しない場合、タスクをチェックアウトできない', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
const { accountId } = await createAccount(source);
|
||||
await createUser(
|
||||
source,
|
||||
accountId,
|
||||
'author-user-external-id',
|
||||
'author',
|
||||
'MY_AUTHOR_ID',
|
||||
);
|
||||
|
||||
const service = module.get<TasksService>(TasksService);
|
||||
await expect(
|
||||
service.checkout(1, ['author'], 'author-user-external-id'),
|
||||
).rejects.toEqual(
|
||||
new HttpException(makeErrorResponse('E010601'), HttpStatus.BAD_REQUEST),
|
||||
);
|
||||
});
|
||||
|
||||
it('ユーザーのRoleがAuthorで、音声ファイルに紐づいたタスクでユーザーと一致するAuthorIDでない場合、タスクをチェックアウトできない', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
const { accountId } = await createAccount(source);
|
||||
const { userId: authorUserId } = await createUser(
|
||||
source,
|
||||
accountId,
|
||||
'author-user-external-id',
|
||||
'author',
|
||||
'MY_AUTHOR_ID',
|
||||
);
|
||||
await createTask(
|
||||
source,
|
||||
accountId,
|
||||
authorUserId,
|
||||
'OTHOR_AUTHOR',
|
||||
'',
|
||||
'01',
|
||||
'00000001',
|
||||
'Uploaded',
|
||||
);
|
||||
|
||||
const service = module.get<TasksService>(TasksService);
|
||||
await expect(
|
||||
service.checkout(1, ['author'], 'author-user-external-id'),
|
||||
).rejects.toEqual(
|
||||
new HttpException(makeErrorResponse('E010602'), HttpStatus.BAD_REQUEST),
|
||||
);
|
||||
});
|
||||
|
||||
it('ユーザーのRoleに[Typist,author]が設定されていない時、タスクをチェックアウトできない', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
const { accountId } = await createAccount(source);
|
||||
|
||||
@ -19,6 +19,7 @@ import { AdB2cUser } from '../../gateways/adb2c/types/types';
|
||||
import { CheckoutPermission } from '../../repositories/checkout_permissions/entity/checkout_permission.entity';
|
||||
import {
|
||||
CheckoutPermissionNotFoundError,
|
||||
TaskAuthorIdNotMatchError,
|
||||
TasksNotFoundError,
|
||||
TypistUserGroupNotFoundError,
|
||||
TypistUserNotFoundError,
|
||||
@ -147,10 +148,16 @@ export class TasksService {
|
||||
externalId: string,
|
||||
): Promise<void> {
|
||||
try {
|
||||
const { id, account_id } =
|
||||
const { id, account_id, author_id } =
|
||||
await this.usersRepository.findUserByExternalId(externalId);
|
||||
// TODO authorの処理は別タスクで対応
|
||||
|
||||
if (roles.includes(USER_ROLES.AUTHOR)) {
|
||||
await this.taskRepository.getTaskFromAudioFileId(
|
||||
audioFileId,
|
||||
account_id,
|
||||
author_id,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (roles.includes(USER_ROLES.TYPIST)) {
|
||||
@ -163,6 +170,7 @@ export class TasksService {
|
||||
if (e instanceof Error) {
|
||||
switch (e.constructor) {
|
||||
case CheckoutPermissionNotFoundError:
|
||||
case TaskAuthorIdNotMatchError:
|
||||
case InvalidRoleError:
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E010602'),
|
||||
|
||||
@ -4,5 +4,7 @@ export class TypistUserGroupNotFoundError extends Error {}
|
||||
export class TypistUserNotFoundError extends Error {}
|
||||
// タスク未発見エラー
|
||||
export class TasksNotFoundError extends Error {}
|
||||
// タスクAuthorID不一致エラー
|
||||
export class TaskAuthorIdNotMatchError extends Error {}
|
||||
// チェックアウト権限未発見エラー
|
||||
export class CheckoutPermissionNotFoundError extends Error {}
|
||||
|
||||
@ -22,6 +22,7 @@ import { UserGroup } from '../user_groups/entity/user_group.entity';
|
||||
import { User } from '../users/entity/user.entity';
|
||||
import {
|
||||
CheckoutPermissionNotFoundError,
|
||||
TaskAuthorIdNotMatchError,
|
||||
TasksNotFoundError,
|
||||
TypistUserGroupNotFoundError,
|
||||
TypistUserNotFoundError,
|
||||
@ -32,6 +33,45 @@ import { Roles } from '../../common/types/role';
|
||||
export class TasksRepositoryService {
|
||||
constructor(private dataSource: DataSource) {}
|
||||
|
||||
/**
|
||||
* 音声ファイルIDに紐づいたTaskを取得する
|
||||
* @param audioFileId
|
||||
* @param account_id
|
||||
* @param author_id
|
||||
* @returns task from author id
|
||||
*/
|
||||
async getTaskFromAudioFileId(
|
||||
audioFileId: number,
|
||||
account_id: number,
|
||||
author_id: string,
|
||||
): Promise<Task> {
|
||||
return await this.dataSource.transaction(async (entityManager) => {
|
||||
const taskRepo = entityManager.getRepository(Task);
|
||||
// 指定した音声ファイルIDに紐づくTaskの中でAuthorIDが一致するものを取得
|
||||
const task = await taskRepo.findOne({
|
||||
relations: {
|
||||
file: true,
|
||||
},
|
||||
where: {
|
||||
audio_file_id: audioFileId,
|
||||
account_id: account_id,
|
||||
},
|
||||
});
|
||||
if (!task) {
|
||||
throw new TasksNotFoundError(
|
||||
`task not found. audio_file_id:${audioFileId}`,
|
||||
);
|
||||
}
|
||||
if (task.file?.author_id !== author_id) {
|
||||
throw new TaskAuthorIdNotMatchError(
|
||||
`task authorId not match. audio_file_id:${audioFileId}, author_id:${author_id}, author_id(Task):${task.file?.author_id}`,
|
||||
);
|
||||
}
|
||||
|
||||
return task;
|
||||
});
|
||||
}
|
||||
|
||||
async checkout(
|
||||
audioFileId: number,
|
||||
account_id: number,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user