Merged PR 465: API実装(ワークフロー更新API)
## 概要 [Task2776: API実装(ワークフロー更新API)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2776) - ワークフロー編集APIとテストを実装しました。 ## レビューポイント - リポジトリでのチェック処理は適切か - テストケースは適切か ## UIの変更 - なし ## 動作確認状況 - ローカルで確認
This commit is contained in:
parent
983726eaf3
commit
f70e266e85
@ -58,4 +58,5 @@ export const ErrorCodes = [
|
||||
'E011003', // ワークタイプ不在エラー
|
||||
'E012001', // テンプレートファイル不在エラー
|
||||
'E013001', // ワークフローのAuthorIDとWorktypeIDのペア重複エラー
|
||||
'E013002', // ワークフロー不在エラー
|
||||
] as const;
|
||||
|
||||
@ -47,4 +47,5 @@ export const errors: Errors = {
|
||||
E011003: 'WorkTypeID not found Error',
|
||||
E012001: 'Template file not found Error',
|
||||
E013001: 'AuthorId and WorktypeId pair already exists Error',
|
||||
E013002: 'Workflow not found Error',
|
||||
};
|
||||
|
||||
@ -156,16 +156,21 @@ export class WorkflowsController {
|
||||
@Param() param: UpdateWorkflowRequestParam,
|
||||
@Body() body: UpdateWorkflowRequest,
|
||||
): Promise<UpdateWorkflowResponse> {
|
||||
const { authorId } = body;
|
||||
const { authorId, worktypeId, templateId, typists } = body;
|
||||
const { workflowId } = param;
|
||||
const token = retrieveAuthorizationToken(req);
|
||||
const { userId } = jwt.decode(token, { json: true }) as AccessToken;
|
||||
console.log('updateWorkflow');
|
||||
|
||||
const context = makeContext(userId);
|
||||
console.log(context.trackingId);
|
||||
console.log(authorId);
|
||||
console.log(workflowId);
|
||||
await this.workflowsService.updateWorkflow(
|
||||
context,
|
||||
userId,
|
||||
workflowId,
|
||||
authorId,
|
||||
worktypeId,
|
||||
templateId,
|
||||
typists,
|
||||
);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -925,3 +925,900 @@ describe('createWorkflows', () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateWorkflow', () => {
|
||||
let source: DataSource = 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 () => {
|
||||
await source.destroy();
|
||||
source = null;
|
||||
});
|
||||
|
||||
it('アカウント内のWorkflowを更新できる(WorktypeIDあり、テンプレートファイルあり)', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
// 第五階層のアカウント作成
|
||||
const { account, admin } = await makeTestAccount(source, { tier: 5 });
|
||||
const { id: authorId1 } = await makeTestUser(source, {
|
||||
external_id: 'author1',
|
||||
author_id: 'AUTHOR1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.AUTHOR,
|
||||
});
|
||||
const { id: authorId2 } = await makeTestUser(source, {
|
||||
external_id: 'author2',
|
||||
author_id: 'AUTHOR2',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.AUTHOR,
|
||||
});
|
||||
const { id: typistId1 } = await makeTestUser(source, {
|
||||
external_id: 'typist1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.TYPIST,
|
||||
});
|
||||
const { id: typistId2 } = await makeTestUser(source, {
|
||||
external_id: 'typist12',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.TYPIST,
|
||||
});
|
||||
|
||||
const { id: worktypeId } = await createWorktype(
|
||||
source,
|
||||
account.id,
|
||||
'worktype1',
|
||||
);
|
||||
|
||||
const { id: templateId } = await createTemplateFile(
|
||||
source,
|
||||
account.id,
|
||||
'fileName1',
|
||||
'url1',
|
||||
);
|
||||
|
||||
const preWorkflow = await createWorkflow(
|
||||
source,
|
||||
account.id,
|
||||
authorId1,
|
||||
undefined,
|
||||
undefined,
|
||||
);
|
||||
await createWorkflowTypist(source, preWorkflow.id, typistId1);
|
||||
|
||||
//作成したデータを確認
|
||||
{
|
||||
const workflows = await getWorkflows(source, account.id);
|
||||
const workflowTypists = await getAllWorkflowTypists(source);
|
||||
expect(workflows.length).toBe(1);
|
||||
expect(workflows[0].id).toBe(preWorkflow.id);
|
||||
expect(workflows[0].account_id).toBe(account.id);
|
||||
expect(workflows[0].author_id).toBe(authorId1);
|
||||
expect(workflows[0].worktype_id).toBe(null);
|
||||
expect(workflows[0].template_id).toBe(null);
|
||||
expect(workflowTypists.length).toBe(1);
|
||||
}
|
||||
|
||||
const service = module.get<WorkflowsService>(WorkflowsService);
|
||||
const context = makeContext(admin.external_id);
|
||||
|
||||
await service.updateWorkflow(
|
||||
context,
|
||||
admin.external_id,
|
||||
preWorkflow.id,
|
||||
authorId2,
|
||||
worktypeId,
|
||||
templateId,
|
||||
[
|
||||
{
|
||||
typistId: typistId2,
|
||||
},
|
||||
],
|
||||
);
|
||||
|
||||
//実行結果を確認
|
||||
{
|
||||
const workflows = await getWorkflows(source, account.id);
|
||||
expect(workflows.length).toBe(1);
|
||||
expect(workflows[0].account_id).toBe(account.id);
|
||||
expect(workflows[0].author_id).toBe(authorId2);
|
||||
expect(workflows[0].worktype_id).toBe(worktypeId);
|
||||
expect(workflows[0].template_id).toBe(templateId);
|
||||
|
||||
const workflowTypists = await getWorkflowTypists(source, workflows[0].id);
|
||||
expect(workflowTypists.length).toBe(1);
|
||||
expect(workflowTypists[0].typist_id).toBe(typistId2);
|
||||
}
|
||||
});
|
||||
|
||||
it('アカウント内にWorkflowを作成できる(WorktypeIDなし、テンプレートファイルあり)', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
// 第五階層のアカウント作成
|
||||
const { account, admin } = await makeTestAccount(source, { tier: 5 });
|
||||
const { id: authorId1 } = await makeTestUser(source, {
|
||||
external_id: 'author1',
|
||||
author_id: 'AUTHOR1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.AUTHOR,
|
||||
});
|
||||
const { id: authorId2 } = await makeTestUser(source, {
|
||||
external_id: 'author2',
|
||||
author_id: 'AUTHOR2',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.AUTHOR,
|
||||
});
|
||||
const { id: typistId1 } = await makeTestUser(source, {
|
||||
external_id: 'typist1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.TYPIST,
|
||||
});
|
||||
const { id: typistId2 } = await makeTestUser(source, {
|
||||
external_id: 'typist12',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.TYPIST,
|
||||
});
|
||||
|
||||
const { id: templateId } = await createTemplateFile(
|
||||
source,
|
||||
account.id,
|
||||
'fileName1',
|
||||
'url1',
|
||||
);
|
||||
|
||||
const preWorkflow = await createWorkflow(
|
||||
source,
|
||||
account.id,
|
||||
authorId1,
|
||||
undefined,
|
||||
undefined,
|
||||
);
|
||||
await createWorkflowTypist(source, preWorkflow.id, typistId1);
|
||||
|
||||
//作成したデータを確認
|
||||
{
|
||||
const workflows = await getWorkflows(source, account.id);
|
||||
const workflowTypists = await getAllWorkflowTypists(source);
|
||||
expect(workflows.length).toBe(1);
|
||||
expect(workflows[0].id).toBe(preWorkflow.id);
|
||||
expect(workflows[0].account_id).toBe(account.id);
|
||||
expect(workflows[0].author_id).toBe(authorId1);
|
||||
expect(workflows[0].worktype_id).toBe(null);
|
||||
expect(workflows[0].template_id).toBe(null);
|
||||
expect(workflowTypists.length).toBe(1);
|
||||
}
|
||||
|
||||
const service = module.get<WorkflowsService>(WorkflowsService);
|
||||
const context = makeContext(admin.external_id);
|
||||
|
||||
await service.updateWorkflow(
|
||||
context,
|
||||
admin.external_id,
|
||||
preWorkflow.id,
|
||||
authorId2,
|
||||
undefined,
|
||||
templateId,
|
||||
[
|
||||
{
|
||||
typistId: typistId2,
|
||||
},
|
||||
],
|
||||
);
|
||||
|
||||
//実行結果を確認
|
||||
{
|
||||
const workflows = await getWorkflows(source, account.id);
|
||||
expect(workflows.length).toBe(1);
|
||||
expect(workflows[0].account_id).toBe(account.id);
|
||||
expect(workflows[0].author_id).toBe(authorId2);
|
||||
expect(workflows[0].worktype_id).toBe(null);
|
||||
expect(workflows[0].template_id).toBe(templateId);
|
||||
|
||||
const workflowTypists = await getWorkflowTypists(source, workflows[0].id);
|
||||
expect(workflowTypists.length).toBe(1);
|
||||
expect(workflowTypists[0].typist_id).toBe(typistId2);
|
||||
}
|
||||
});
|
||||
|
||||
it('アカウント内にWorkflowを作成できる(WorktypeIDあり、テンプレートファイルなし)', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
// 第五階層のアカウント作成
|
||||
const { account, admin } = await makeTestAccount(source, { tier: 5 });
|
||||
const { id: authorId1 } = await makeTestUser(source, {
|
||||
external_id: 'author1',
|
||||
author_id: 'AUTHOR1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.AUTHOR,
|
||||
});
|
||||
const { id: authorId2 } = await makeTestUser(source, {
|
||||
external_id: 'author2',
|
||||
author_id: 'AUTHOR2',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.AUTHOR,
|
||||
});
|
||||
const { id: typistId1 } = await makeTestUser(source, {
|
||||
external_id: 'typist1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.TYPIST,
|
||||
});
|
||||
const { id: typistId2 } = await makeTestUser(source, {
|
||||
external_id: 'typist12',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.TYPIST,
|
||||
});
|
||||
|
||||
const { id: worktypeId } = await createWorktype(
|
||||
source,
|
||||
account.id,
|
||||
'worktype1',
|
||||
);
|
||||
|
||||
const preWorkflow = await createWorkflow(
|
||||
source,
|
||||
account.id,
|
||||
authorId1,
|
||||
undefined,
|
||||
undefined,
|
||||
);
|
||||
await createWorkflowTypist(source, preWorkflow.id, typistId1);
|
||||
|
||||
//作成したデータを確認
|
||||
{
|
||||
const workflows = await getWorkflows(source, account.id);
|
||||
const workflowTypists = await getAllWorkflowTypists(source);
|
||||
expect(workflows.length).toBe(1);
|
||||
expect(workflows[0].id).toBe(preWorkflow.id);
|
||||
expect(workflows[0].account_id).toBe(account.id);
|
||||
expect(workflows[0].author_id).toBe(authorId1);
|
||||
expect(workflows[0].worktype_id).toBe(null);
|
||||
expect(workflows[0].template_id).toBe(null);
|
||||
expect(workflowTypists.length).toBe(1);
|
||||
}
|
||||
|
||||
const service = module.get<WorkflowsService>(WorkflowsService);
|
||||
const context = makeContext(admin.external_id);
|
||||
|
||||
await service.updateWorkflow(
|
||||
context,
|
||||
admin.external_id,
|
||||
preWorkflow.id,
|
||||
authorId2,
|
||||
worktypeId,
|
||||
undefined,
|
||||
[
|
||||
{
|
||||
typistId: typistId2,
|
||||
},
|
||||
],
|
||||
);
|
||||
|
||||
//実行結果を確認
|
||||
{
|
||||
const workflows = await getWorkflows(source, account.id);
|
||||
expect(workflows.length).toBe(1);
|
||||
expect(workflows[0].account_id).toBe(account.id);
|
||||
expect(workflows[0].author_id).toBe(authorId2);
|
||||
expect(workflows[0].worktype_id).toBe(worktypeId);
|
||||
expect(workflows[0].template_id).toBe(null);
|
||||
|
||||
const workflowTypists = await getWorkflowTypists(source, workflows[0].id);
|
||||
expect(workflowTypists.length).toBe(1);
|
||||
expect(workflowTypists[0].typist_id).toBe(typistId2);
|
||||
}
|
||||
});
|
||||
|
||||
it('アカウント内にWorkflowを作成できる(WorktypeIDなし、テンプレートファイルなし)', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
// 第五階層のアカウント作成
|
||||
const { account, admin } = await makeTestAccount(source, { tier: 5 });
|
||||
const { id: authorId1 } = await makeTestUser(source, {
|
||||
external_id: 'author1',
|
||||
author_id: 'AUTHOR1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.AUTHOR,
|
||||
});
|
||||
const { id: authorId2 } = await makeTestUser(source, {
|
||||
external_id: 'author2',
|
||||
author_id: 'AUTHOR2',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.AUTHOR,
|
||||
});
|
||||
const { id: typistId1 } = await makeTestUser(source, {
|
||||
external_id: 'typist1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.TYPIST,
|
||||
});
|
||||
const { id: typistId2 } = await makeTestUser(source, {
|
||||
external_id: 'typist12',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.TYPIST,
|
||||
});
|
||||
|
||||
const preWorkflow = await createWorkflow(
|
||||
source,
|
||||
account.id,
|
||||
authorId1,
|
||||
undefined,
|
||||
undefined,
|
||||
);
|
||||
await createWorkflowTypist(source, preWorkflow.id, typistId1);
|
||||
|
||||
//作成したデータを確認
|
||||
{
|
||||
const workflows = await getWorkflows(source, account.id);
|
||||
const workflowTypists = await getAllWorkflowTypists(source);
|
||||
expect(workflows.length).toBe(1);
|
||||
expect(workflows[0].id).toBe(preWorkflow.id);
|
||||
expect(workflows[0].account_id).toBe(account.id);
|
||||
expect(workflows[0].author_id).toBe(authorId1);
|
||||
expect(workflows[0].worktype_id).toBe(null);
|
||||
expect(workflows[0].template_id).toBe(null);
|
||||
expect(workflowTypists.length).toBe(1);
|
||||
}
|
||||
|
||||
const service = module.get<WorkflowsService>(WorkflowsService);
|
||||
const context = makeContext(admin.external_id);
|
||||
|
||||
await service.updateWorkflow(
|
||||
context,
|
||||
admin.external_id,
|
||||
preWorkflow.id,
|
||||
authorId2,
|
||||
undefined,
|
||||
undefined,
|
||||
[
|
||||
{
|
||||
typistId: typistId2,
|
||||
},
|
||||
],
|
||||
);
|
||||
|
||||
//実行結果を確認
|
||||
{
|
||||
const workflows = await getWorkflows(source, account.id);
|
||||
expect(workflows.length).toBe(1);
|
||||
expect(workflows[0].account_id).toBe(account.id);
|
||||
expect(workflows[0].author_id).toBe(authorId2);
|
||||
expect(workflows[0].worktype_id).toBe(null);
|
||||
expect(workflows[0].template_id).toBe(null);
|
||||
|
||||
const workflowTypists = await getWorkflowTypists(source, workflows[0].id);
|
||||
expect(workflowTypists.length).toBe(1);
|
||||
expect(workflowTypists[0].typist_id).toBe(typistId2);
|
||||
}
|
||||
});
|
||||
it('DBにWorkflowが存在しない場合、400エラーとなること', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
// 第五階層のアカウント作成
|
||||
const { account, admin } = await makeTestAccount(source, { tier: 5 });
|
||||
const { id: authorId1 } = await makeTestUser(source, {
|
||||
external_id: 'author1',
|
||||
author_id: 'AUTHOR1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.AUTHOR,
|
||||
});
|
||||
const { id: typistId1 } = await makeTestUser(source, {
|
||||
external_id: 'typist1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.TYPIST,
|
||||
});
|
||||
|
||||
const service = module.get<WorkflowsService>(WorkflowsService);
|
||||
const context = makeContext(admin.external_id);
|
||||
|
||||
//実行結果を確認
|
||||
try {
|
||||
await service.updateWorkflow(
|
||||
context,
|
||||
admin.external_id,
|
||||
9999,
|
||||
authorId1,
|
||||
undefined,
|
||||
undefined,
|
||||
[
|
||||
{
|
||||
typistId: typistId1,
|
||||
},
|
||||
],
|
||||
);
|
||||
} catch (e) {
|
||||
if (e instanceof HttpException) {
|
||||
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
|
||||
expect(e.getResponse()).toEqual(makeErrorResponse('E013002'));
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
});
|
||||
it('DBにAuthorが存在しない場合、400エラーとなること', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
// 第五階層のアカウント作成
|
||||
const { account, admin } = await makeTestAccount(source, { tier: 5 });
|
||||
const { id: authorId1 } = await makeTestUser(source, {
|
||||
external_id: 'author1',
|
||||
author_id: 'AUTHOR1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.AUTHOR,
|
||||
});
|
||||
const { id: typistId1 } = await makeTestUser(source, {
|
||||
external_id: 'typist1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.TYPIST,
|
||||
});
|
||||
|
||||
const { id: worktypeId } = await createWorktype(
|
||||
source,
|
||||
account.id,
|
||||
'worktype1',
|
||||
);
|
||||
|
||||
const { id: templateId } = await createTemplateFile(
|
||||
source,
|
||||
account.id,
|
||||
'fileName1',
|
||||
'url1',
|
||||
);
|
||||
|
||||
const preWorkflow = await createWorkflow(
|
||||
source,
|
||||
account.id,
|
||||
authorId1,
|
||||
undefined,
|
||||
undefined,
|
||||
);
|
||||
await createWorkflowTypist(source, preWorkflow.id, typistId1);
|
||||
|
||||
//作成したデータを確認
|
||||
{
|
||||
const workflows = await getWorkflows(source, account.id);
|
||||
expect(workflows.length).toBe(1);
|
||||
}
|
||||
|
||||
const service = module.get<WorkflowsService>(WorkflowsService);
|
||||
const context = makeContext(admin.external_id);
|
||||
|
||||
//実行結果を確認
|
||||
try {
|
||||
await service.updateWorkflow(
|
||||
context,
|
||||
admin.external_id,
|
||||
preWorkflow.id,
|
||||
9999,
|
||||
worktypeId,
|
||||
templateId,
|
||||
[
|
||||
{
|
||||
typistId: typistId1,
|
||||
},
|
||||
],
|
||||
);
|
||||
} catch (e) {
|
||||
if (e instanceof HttpException) {
|
||||
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
|
||||
expect(e.getResponse()).toEqual(makeErrorResponse('E010204'));
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('DBにWorktypeIDが存在しない場合、400エラーとなること', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
// 第五階層のアカウント作成
|
||||
const { account, admin } = await makeTestAccount(source, { tier: 5 });
|
||||
const { id: authorId1 } = await makeTestUser(source, {
|
||||
external_id: 'author1',
|
||||
author_id: 'AUTHOR1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.AUTHOR,
|
||||
});
|
||||
const { id: typistId1 } = await makeTestUser(source, {
|
||||
external_id: 'typist1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.TYPIST,
|
||||
});
|
||||
|
||||
const { id: templateId } = await createTemplateFile(
|
||||
source,
|
||||
account.id,
|
||||
'fileName1',
|
||||
'url1',
|
||||
);
|
||||
|
||||
const preWorkflow = await createWorkflow(
|
||||
source,
|
||||
account.id,
|
||||
authorId1,
|
||||
undefined,
|
||||
undefined,
|
||||
);
|
||||
await createWorkflowTypist(source, preWorkflow.id, typistId1);
|
||||
|
||||
//作成したデータを確認
|
||||
{
|
||||
const workflows = await getWorkflows(source, account.id);
|
||||
expect(workflows.length).toBe(1);
|
||||
}
|
||||
|
||||
const service = module.get<WorkflowsService>(WorkflowsService);
|
||||
const context = makeContext(admin.external_id);
|
||||
|
||||
//実行結果を確認
|
||||
try {
|
||||
await service.updateWorkflow(
|
||||
context,
|
||||
admin.external_id,
|
||||
preWorkflow.id,
|
||||
authorId1,
|
||||
9999,
|
||||
templateId,
|
||||
[
|
||||
{
|
||||
typistId: typistId1,
|
||||
},
|
||||
],
|
||||
);
|
||||
} catch (e) {
|
||||
if (e instanceof HttpException) {
|
||||
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
|
||||
expect(e.getResponse()).toEqual(makeErrorResponse('E011003'));
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('DBにテンプレートファイルが存在しない場合、400エラーとなること', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
// 第五階層のアカウント作成
|
||||
const { account, admin } = await makeTestAccount(source, { tier: 5 });
|
||||
const { id: authorId1 } = await makeTestUser(source, {
|
||||
external_id: 'author1',
|
||||
author_id: 'AUTHOR1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.AUTHOR,
|
||||
});
|
||||
const { id: typistId1 } = await makeTestUser(source, {
|
||||
external_id: 'typist1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.TYPIST,
|
||||
});
|
||||
|
||||
const { id: worktypeId } = await createWorktype(
|
||||
source,
|
||||
account.id,
|
||||
'worktype1',
|
||||
);
|
||||
|
||||
const preWorkflow = await createWorkflow(
|
||||
source,
|
||||
account.id,
|
||||
authorId1,
|
||||
undefined,
|
||||
undefined,
|
||||
);
|
||||
await createWorkflowTypist(source, preWorkflow.id, typistId1);
|
||||
|
||||
//作成したデータを確認
|
||||
{
|
||||
const workflows = await getWorkflows(source, account.id);
|
||||
expect(workflows.length).toBe(1);
|
||||
}
|
||||
|
||||
const service = module.get<WorkflowsService>(WorkflowsService);
|
||||
const context = makeContext(admin.external_id);
|
||||
|
||||
//実行結果を確認
|
||||
try {
|
||||
await service.updateWorkflow(
|
||||
context,
|
||||
admin.external_id,
|
||||
preWorkflow.id,
|
||||
authorId1,
|
||||
worktypeId,
|
||||
9999,
|
||||
[
|
||||
{
|
||||
typistId: typistId1,
|
||||
},
|
||||
],
|
||||
);
|
||||
} catch (e) {
|
||||
if (e instanceof HttpException) {
|
||||
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
|
||||
expect(e.getResponse()).toEqual(makeErrorResponse('E012001'));
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('DBにルーティング候補ユーザーが存在しない場合、400エラーとなること', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
// 第五階層のアカウント作成
|
||||
const { account, admin } = await makeTestAccount(source, { tier: 5 });
|
||||
const { id: authorId1 } = await makeTestUser(source, {
|
||||
external_id: 'author1',
|
||||
author_id: 'AUTHOR1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.AUTHOR,
|
||||
});
|
||||
const { id: typistId1 } = await makeTestUser(source, {
|
||||
external_id: 'typist1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.TYPIST,
|
||||
});
|
||||
|
||||
const { id: worktypeId } = await createWorktype(
|
||||
source,
|
||||
account.id,
|
||||
'worktype1',
|
||||
);
|
||||
|
||||
const { id: templateId } = await createTemplateFile(
|
||||
source,
|
||||
account.id,
|
||||
'fileName1',
|
||||
'url1',
|
||||
);
|
||||
|
||||
const preWorkflow = await createWorkflow(
|
||||
source,
|
||||
account.id,
|
||||
authorId1,
|
||||
undefined,
|
||||
undefined,
|
||||
);
|
||||
await createWorkflowTypist(source, preWorkflow.id, typistId1);
|
||||
|
||||
//作成したデータを確認
|
||||
{
|
||||
const workflows = await getWorkflows(source, account.id);
|
||||
expect(workflows.length).toBe(1);
|
||||
}
|
||||
|
||||
const service = module.get<WorkflowsService>(WorkflowsService);
|
||||
const context = makeContext(admin.external_id);
|
||||
|
||||
//実行結果を確認
|
||||
try {
|
||||
await service.updateWorkflow(
|
||||
context,
|
||||
admin.external_id,
|
||||
preWorkflow.id,
|
||||
authorId1,
|
||||
worktypeId,
|
||||
templateId,
|
||||
[
|
||||
{
|
||||
typistId: 9999,
|
||||
},
|
||||
],
|
||||
);
|
||||
} catch (e) {
|
||||
if (e instanceof HttpException) {
|
||||
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
|
||||
expect(e.getResponse()).toEqual(makeErrorResponse('E010204'));
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('DBにルーティング候補グループが存在しない場合、400エラーとなること', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
// 第五階層のアカウント作成
|
||||
const { account, admin } = await makeTestAccount(source, { tier: 5 });
|
||||
const { id: authorId1 } = await makeTestUser(source, {
|
||||
external_id: 'author1',
|
||||
author_id: 'AUTHOR1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.AUTHOR,
|
||||
});
|
||||
const { id: typistId1 } = await makeTestUser(source, {
|
||||
external_id: 'typist1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.TYPIST,
|
||||
});
|
||||
|
||||
const { id: worktypeId } = await createWorktype(
|
||||
source,
|
||||
account.id,
|
||||
'worktype1',
|
||||
);
|
||||
|
||||
const { id: templateId } = await createTemplateFile(
|
||||
source,
|
||||
account.id,
|
||||
'fileName1',
|
||||
'url1',
|
||||
);
|
||||
|
||||
const preWorkflow = await createWorkflow(
|
||||
source,
|
||||
account.id,
|
||||
authorId1,
|
||||
undefined,
|
||||
undefined,
|
||||
);
|
||||
await createWorkflowTypist(source, preWorkflow.id, typistId1);
|
||||
|
||||
//作成したデータを確認
|
||||
{
|
||||
const workflows = await getWorkflows(source, account.id);
|
||||
expect(workflows.length).toBe(1);
|
||||
}
|
||||
|
||||
const service = module.get<WorkflowsService>(WorkflowsService);
|
||||
const context = makeContext(admin.external_id);
|
||||
|
||||
//実行結果を確認
|
||||
try {
|
||||
await service.updateWorkflow(
|
||||
context,
|
||||
admin.external_id,
|
||||
preWorkflow.id,
|
||||
authorId1,
|
||||
worktypeId,
|
||||
templateId,
|
||||
[
|
||||
{
|
||||
typistGroupId: 9999,
|
||||
},
|
||||
],
|
||||
);
|
||||
} catch (e) {
|
||||
if (e instanceof HttpException) {
|
||||
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
|
||||
expect(e.getResponse()).toEqual(makeErrorResponse('E010908'));
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('DBにAuthorIDとWorktypeIDのペアがすでに存在する場合、400エラーとなること', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
// 第五階層のアカウント作成
|
||||
const { account, admin } = await makeTestAccount(source, { tier: 5 });
|
||||
const { id: authorId1 } = await makeTestUser(source, {
|
||||
external_id: 'author1',
|
||||
author_id: 'AUTHOR1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.AUTHOR,
|
||||
});
|
||||
const { id: typistId1 } = await makeTestUser(source, {
|
||||
external_id: 'typist1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.TYPIST,
|
||||
});
|
||||
const { id: worktypeId1 } = await createWorktype(
|
||||
source,
|
||||
account.id,
|
||||
'worktype1',
|
||||
);
|
||||
|
||||
await createWorkflow(source, account.id, authorId1, worktypeId1, undefined);
|
||||
|
||||
const preWorkflow = await createWorkflow(
|
||||
source,
|
||||
account.id,
|
||||
authorId1,
|
||||
undefined,
|
||||
undefined,
|
||||
);
|
||||
await createWorkflowTypist(source, preWorkflow.id, typistId1);
|
||||
|
||||
//作成したデータを確認
|
||||
{
|
||||
const workflows = await getWorkflows(source, account.id);
|
||||
expect(workflows.length).toBe(2);
|
||||
}
|
||||
|
||||
const service = module.get<WorkflowsService>(WorkflowsService);
|
||||
const context = makeContext(admin.external_id);
|
||||
|
||||
//実行結果を確認
|
||||
try {
|
||||
await service.updateWorkflow(
|
||||
context,
|
||||
admin.external_id,
|
||||
preWorkflow.id,
|
||||
authorId1,
|
||||
worktypeId1,
|
||||
undefined,
|
||||
[
|
||||
{
|
||||
typistId: typistId1,
|
||||
},
|
||||
],
|
||||
);
|
||||
} catch (e) {
|
||||
if (e instanceof HttpException) {
|
||||
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
|
||||
expect(e.getResponse()).toEqual(makeErrorResponse('E013001'));
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('DBアクセスに失敗した場合、500エラーを返却する', async () => {
|
||||
const module = await makeTestingModule(source);
|
||||
// 第五階層のアカウント作成
|
||||
const { account, admin } = await makeTestAccount(source, { tier: 5 });
|
||||
const { id: authorId1 } = await makeTestUser(source, {
|
||||
external_id: 'author1',
|
||||
author_id: 'AUTHOR1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.AUTHOR,
|
||||
});
|
||||
const { id: typistId1 } = await makeTestUser(source, {
|
||||
external_id: 'typist1',
|
||||
account_id: account.id,
|
||||
role: USER_ROLES.TYPIST,
|
||||
});
|
||||
|
||||
const preWorkflow = await createWorkflow(
|
||||
source,
|
||||
account.id,
|
||||
authorId1,
|
||||
undefined,
|
||||
undefined,
|
||||
);
|
||||
await createWorkflowTypist(source, preWorkflow.id, typistId1);
|
||||
|
||||
//作成したデータを確認
|
||||
{
|
||||
const workflows = await getWorkflows(source, account.id);
|
||||
const workflowTypists = await getAllWorkflowTypists(source);
|
||||
expect(workflows.length).toBe(1);
|
||||
expect(workflows[0].id).toBe(preWorkflow.id);
|
||||
expect(workflows[0].account_id).toBe(account.id);
|
||||
expect(workflows[0].author_id).toBe(authorId1);
|
||||
expect(workflows[0].worktype_id).toBe(null);
|
||||
expect(workflows[0].template_id).toBe(null);
|
||||
expect(workflowTypists.length).toBe(1);
|
||||
}
|
||||
|
||||
const service = module.get<WorkflowsService>(WorkflowsService);
|
||||
const context = makeContext(admin.external_id);
|
||||
|
||||
//DBアクセスに失敗するようにする
|
||||
const workflowsRepositoryService = module.get<WorkflowsRepositoryService>(
|
||||
WorkflowsRepositoryService,
|
||||
);
|
||||
workflowsRepositoryService.updatetWorkflow = jest
|
||||
.fn()
|
||||
.mockRejectedValue('DB failed');
|
||||
|
||||
//実行結果を確認
|
||||
try {
|
||||
await service.updateWorkflow(
|
||||
context,
|
||||
admin.external_id,
|
||||
preWorkflow.id,
|
||||
authorId1,
|
||||
undefined,
|
||||
undefined,
|
||||
[
|
||||
{
|
||||
typistId: typistId1,
|
||||
},
|
||||
],
|
||||
);
|
||||
} catch (e) {
|
||||
if (e instanceof HttpException) {
|
||||
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,16 +1,18 @@
|
||||
import { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common';
|
||||
import { WorkflowsRepositoryService } from '../../repositories/workflows/workflows.repository.service';
|
||||
import { UsersRepositoryService } from '../../repositories/users/users.repository.service';
|
||||
import { WorkflowTypist } from './types/types';
|
||||
import { Context } from '../../common/log';
|
||||
import { makeErrorResponse } from '../../common/error/makeErrorResponse';
|
||||
import { Workflow, WorkflowTypist } from './types/types';
|
||||
import { AdB2cService } from '../../gateways/adb2c/adb2c.service';
|
||||
import { UserNotFoundError } from '../../repositories/users/errors/types';
|
||||
import { TypistGroupNotExistError } from '../../repositories/user_groups/errors/types';
|
||||
import { WorktypeIdNotFoundError } from '../../repositories/worktypes/errors/types';
|
||||
import { TemplateFileNotExistError } from '../../repositories/template_files/errors/types';
|
||||
import { AuthorIdAndWorktypeIdPairAlreadyExistsError } from '../../repositories/workflows/errors/types';
|
||||
import { Workflow } from './types/types';
|
||||
import { AdB2cService } from '../../gateways/adb2c/adb2c.service';
|
||||
import {
|
||||
AuthorIdAndWorktypeIdPairAlreadyExistsError,
|
||||
WorkflowIdNotFoundError,
|
||||
} from '../../repositories/workflows/errors/types';
|
||||
|
||||
@Injectable()
|
||||
export class WorkflowsService {
|
||||
@ -196,4 +198,96 @@ export class WorkflowsService {
|
||||
);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* アカウント内のワークフローを更新する
|
||||
* @param context
|
||||
* @param externalId
|
||||
* @param workflowId
|
||||
* @param authorId
|
||||
* @param [worktypeId]
|
||||
* @param [templateId]
|
||||
* @param [typists]
|
||||
* @returns workflow
|
||||
*/
|
||||
async updateWorkflow(
|
||||
context: Context,
|
||||
externalId: string,
|
||||
workflowId: number,
|
||||
authorId: number,
|
||||
worktypeId?: number | undefined,
|
||||
templateId?: number | undefined,
|
||||
typists?: WorkflowTypist[],
|
||||
): Promise<void> {
|
||||
this.logger.log(
|
||||
`[IN] [${context.trackingId}] ${this.updateWorkflow.name} | params: { ` +
|
||||
`externalId: ${externalId}, ` +
|
||||
`workflowId: ${workflowId}, ` +
|
||||
`authorId: ${authorId}, ` +
|
||||
`worktypeId: ${worktypeId}, ` +
|
||||
`templateId: ${templateId}, ` +
|
||||
`typists: ${JSON.stringify(typists)} };`,
|
||||
);
|
||||
try {
|
||||
const { account_id: accountId } =
|
||||
await this.usersRepository.findUserByExternalId(externalId);
|
||||
|
||||
await this.workflowsRepository.updatetWorkflow(
|
||||
accountId,
|
||||
workflowId,
|
||||
authorId,
|
||||
worktypeId,
|
||||
templateId,
|
||||
typists,
|
||||
);
|
||||
} catch (e) {
|
||||
this.logger.error(`[${context.trackingId}] error=${e}`);
|
||||
if (e instanceof Error) {
|
||||
switch (e.constructor) {
|
||||
case WorkflowIdNotFoundError:
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E013002'),
|
||||
HttpStatus.BAD_REQUEST,
|
||||
);
|
||||
case UserNotFoundError:
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E010204'),
|
||||
HttpStatus.BAD_REQUEST,
|
||||
);
|
||||
case TypistGroupNotExistError:
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E010908'),
|
||||
HttpStatus.BAD_REQUEST,
|
||||
);
|
||||
case WorktypeIdNotFoundError:
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E011003'),
|
||||
HttpStatus.BAD_REQUEST,
|
||||
);
|
||||
case TemplateFileNotExistError:
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E012001'),
|
||||
HttpStatus.BAD_REQUEST,
|
||||
);
|
||||
case AuthorIdAndWorktypeIdPairAlreadyExistsError:
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E013001'),
|
||||
HttpStatus.BAD_REQUEST,
|
||||
);
|
||||
default:
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E009999'),
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E009999'),
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
} finally {
|
||||
this.logger.log(
|
||||
`[OUT] [${context.trackingId}] ${this.updateWorkflow.name}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,2 +1,4 @@
|
||||
// AuthorIDとWorktypeIDのペア重複エラー
|
||||
export class AuthorIdAndWorktypeIdPairAlreadyExistsError extends Error {}
|
||||
// WorkflowID存在エラー
|
||||
export class WorkflowIdNotFoundError extends Error {}
|
||||
|
||||
@ -11,7 +11,10 @@ import { TypistGroupNotExistError } from '../user_groups/errors/types';
|
||||
import { UserNotFoundError } from '../users/errors/types';
|
||||
import { WorktypeIdNotFoundError } from '../worktypes/errors/types';
|
||||
import { TemplateFileNotExistError } from '../template_files/errors/types';
|
||||
import { AuthorIdAndWorktypeIdPairAlreadyExistsError } from './errors/types';
|
||||
import {
|
||||
AuthorIdAndWorktypeIdPairAlreadyExistsError,
|
||||
WorkflowIdNotFoundError,
|
||||
} from './errors/types';
|
||||
|
||||
@Injectable()
|
||||
export class WorkflowsRepositoryService {
|
||||
@ -37,6 +40,9 @@ export class WorkflowsRepositoryService {
|
||||
typistGroup: true,
|
||||
},
|
||||
},
|
||||
order: {
|
||||
id: 'ASC',
|
||||
},
|
||||
});
|
||||
|
||||
return workflows;
|
||||
@ -158,6 +164,142 @@ export class WorkflowsRepositoryService {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* ワークフローを更新する
|
||||
* @param accountId
|
||||
* @param workflowId
|
||||
* @param authorId
|
||||
* @param [worktypeId]
|
||||
* @param [templateId]
|
||||
* @param [typists]
|
||||
* @returns workflow
|
||||
*/
|
||||
async updatetWorkflow(
|
||||
accountId: number,
|
||||
workflowId: number,
|
||||
authorId: number,
|
||||
worktypeId?: number | undefined,
|
||||
templateId?: number | undefined,
|
||||
typists?: WorkflowTypist[],
|
||||
): Promise<void> {
|
||||
return await this.dataSource.transaction(async (entityManager) => {
|
||||
const workflowRepo = entityManager.getRepository(Workflow);
|
||||
|
||||
// ワークフローの存在確認
|
||||
const targetWorkflow = await workflowRepo.findOne({
|
||||
where: { account_id: accountId, id: workflowId },
|
||||
});
|
||||
if (!targetWorkflow) {
|
||||
throw new WorkflowIdNotFoundError(
|
||||
`workflow not found. id: ${workflowId}`,
|
||||
);
|
||||
}
|
||||
|
||||
// authorの存在確認
|
||||
const userRepo = entityManager.getRepository(User);
|
||||
const author = await userRepo.findOne({
|
||||
where: { account_id: accountId, id: authorId },
|
||||
});
|
||||
if (!author) {
|
||||
throw new UserNotFoundError(`author not found. id: ${authorId}`);
|
||||
}
|
||||
|
||||
// worktypeの存在確認
|
||||
if (worktypeId !== undefined) {
|
||||
const worktypeRepo = entityManager.getRepository(Worktype);
|
||||
const worktypes = await worktypeRepo.find({
|
||||
where: { account_id: accountId, id: worktypeId },
|
||||
});
|
||||
if (worktypes.length === 0) {
|
||||
throw new WorktypeIdNotFoundError(
|
||||
`worktype not found. id: ${worktypeId}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// templateの存在確認
|
||||
if (templateId !== undefined) {
|
||||
const templateRepo = entityManager.getRepository(TemplateFile);
|
||||
const template = await templateRepo.findOne({
|
||||
where: { account_id: accountId, id: templateId },
|
||||
});
|
||||
if (!template) {
|
||||
throw new TemplateFileNotExistError(
|
||||
`template not found. id: ${templateId}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ルーティング候補ユーザーの存在確認
|
||||
const typistIds = typists.flatMap((typist) =>
|
||||
typist.typistId ? [typist.typistId] : [],
|
||||
);
|
||||
const typistUsers = await userRepo.find({
|
||||
where: { account_id: accountId, id: In(typistIds) },
|
||||
});
|
||||
if (typistUsers.length !== typistIds.length) {
|
||||
throw new UserNotFoundError(`typist not found. ids: ${typistIds}`);
|
||||
}
|
||||
|
||||
// ルーティング候補ユーザーグループの存在確認
|
||||
const groupIds = typists.flatMap((typist) => {
|
||||
return typist.typistGroupId ? [typist.typistGroupId] : [];
|
||||
});
|
||||
const userGroupRepo = entityManager.getRepository(UserGroup);
|
||||
const typistGroups = await userGroupRepo.find({
|
||||
where: { account_id: accountId, id: In(groupIds) },
|
||||
});
|
||||
if (typistGroups.length !== groupIds.length) {
|
||||
throw new TypistGroupNotExistError(
|
||||
`typist group not found. ids: ${groupIds}`,
|
||||
);
|
||||
}
|
||||
|
||||
const workflowTypistsRepo = entityManager.getRepository(DbWorkflowTypist);
|
||||
|
||||
// 既存データの削除
|
||||
await workflowTypistsRepo.delete({ workflow_id: workflowId });
|
||||
await workflowRepo.delete(workflowId);
|
||||
|
||||
{
|
||||
// ワークフローの重複確認
|
||||
const duplicateWorkflow = await workflowRepo.find({
|
||||
where: {
|
||||
account_id: accountId,
|
||||
author_id: authorId,
|
||||
worktype_id: worktypeId,
|
||||
},
|
||||
});
|
||||
if (duplicateWorkflow.length !== 0) {
|
||||
throw new AuthorIdAndWorktypeIdPairAlreadyExistsError(
|
||||
'workflow already exists',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ワークフローのデータ作成
|
||||
const newWorkflow = this.makeWorkflow(
|
||||
accountId,
|
||||
authorId,
|
||||
worktypeId,
|
||||
templateId,
|
||||
);
|
||||
|
||||
await workflowRepo.save(newWorkflow);
|
||||
|
||||
// ルーティング候補のデータ作成
|
||||
const workflowTypists = typists.map((typist) =>
|
||||
this.makeWorkflowTypist(
|
||||
newWorkflow.id,
|
||||
typist.typistId,
|
||||
typist.typistGroupId,
|
||||
),
|
||||
);
|
||||
|
||||
await workflowTypistsRepo.save(workflowTypists);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* DBに保存するワークフローデータを作成する
|
||||
* @param accountId
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user