From 6690302ac320447ffd2be22e9f96bb993a11fae8 Mon Sep 17 00:00:00 2001 From: "saito.k" Date: Fri, 9 Aug 2024 07:47:33 +0000 Subject: [PATCH] =?UTF-8?q?Merged=20PR=20920:=20API=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task4336: API修正](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/4336) - 文字起こし完了時のメールを文字起こし担当のTypistに送信しないようにする ## レビューポイント - 特になし ## UIの変更 - Before/Afterのスクショなど - スクショ置き場 ## 動作確認状況 - ローカルで確認 - ほかのテストケースがすべて通ることを確認 - メール送信処理を確認するテストケースを追加 ## 補足 - 相談、参考資料などがあれば --- .../src/features/tasks/tasks.service.spec.ts | 210 +++++++++++++++++- .../src/features/tasks/tasks.service.ts | 7 +- .../src/features/users/users.service.spec.ts | 4 +- .../src/gateways/sendgrid/sendgrid.service.ts | 17 +- 4 files changed, 217 insertions(+), 21 deletions(-) diff --git a/dictation_server/src/features/tasks/tasks.service.spec.ts b/dictation_server/src/features/tasks/tasks.service.spec.ts index cb59c38..9671a4a 100644 --- a/dictation_server/src/features/tasks/tasks.service.spec.ts +++ b/dictation_server/src/features/tasks/tasks.service.spec.ts @@ -22,7 +22,7 @@ import { makeTaskTestingModuleWithNotificaiton, } from './test/utility'; import { Adb2cTooManyRequestsError } from '../../gateways/adb2c/adb2c.service'; -import { makeContext } from '../../common/log'; +import { Context, makeContext } from '../../common/log'; import { createSortCriteria, makeTestAccount, @@ -31,6 +31,7 @@ import { updateSortCriteria, } from '../../common/test/utility'; import { + ADB2C_SIGN_IN_TYPE, ADMIN_ROLES, LICENSE_ALLOCATED_STATUS, LICENSE_TYPE, @@ -47,7 +48,11 @@ import { createTemplateFile } from '../templates/test/utility'; import { NotificationhubService } from '../../gateways/notificationhub/notificationhub.service'; import { Roles } from '../../common/types/role'; import { TasksRepositoryService } from '../../repositories/tasks/tasks.repository.service'; -import { overrideBlobstorageService } from '../../common/test/overrides'; +import { + overrideAdB2cService, + overrideBlobstorageService, + overrideSendgridService, +} from '../../common/test/overrides'; import { BlobstorageService } from '../../gateways/blobstorage/blobstorage.service'; import { truncateAllTable } from '../../common/test/init'; import { makeDefaultLicensesRepositoryMockValue } from '../accounts/test/accounts.service.mock'; @@ -2524,7 +2529,7 @@ describe('checkin', () => { expect(resultTask?.status).toEqual('Finished'); expect(resultTask?.finished_at).not.toEqual(initTask?.finished_at); - }); + }, 600000); it('タスクのステータスがInprogressでない時、タスクをチェックインできない', async () => { if (!source) fail(); @@ -2659,6 +2664,205 @@ describe('checkin', () => { new HttpException(makeErrorResponse('E010603'), HttpStatus.NOT_FOUND), ); }); + it('API実行者が文字起こし実行中のタスクである場合、タスクをチェックインできる。(文字起こし完了メールの送信先がいない場合送信処理はスキップされる)', async () => { + if (!source) fail(); + const notificationhubServiceMockValue = + makeDefaultNotificationhubServiceMockValue(); + const module = await makeTaskTestingModuleWithNotificaiton( + source, + notificationhubServiceMockValue, + ); + if (!module) fail(); + const { account, admin } = await makeTestAccount(source); + const { id: typistUserId, external_id: typistExternalId } = + await makeTestUser(source, { + account_id: account.id, + external_id: 'typist-user-external-id', + role: 'typist', + }); + const { id: authorUserId, external_id: authorExternalId } = + await makeTestUser(source, { + account_id: account.id, + external_id: 'author-user-external-id', + role: 'author', + author_id: 'MY_AUTHOR_ID', + notification: false, + }); + const { taskId } = await createTask( + source, + account.id, + authorUserId, + 'MY_AUTHOR_ID', + '', + '01', + '00000001', + 'InProgress', + typistUserId, + ); + await createCheckoutPermissions(source, taskId, typistUserId); + + const service = module.get(TasksService); + overrideAdB2cService(service, { + getUsers: async () => { + return [ + { + id: admin.external_id, + displayName: 'admin', + identities: [ + { + signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS, + issuer: 'issuer', + issuerAssignedId: 'admin@example.com', + }, + ], + }, + { + id: typistExternalId, + displayName: 'typist', + identities: [ + { + signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS, + issuer: 'issuer', + issuerAssignedId: 'typist@example.com', + }, + ], + }, + { + id: authorExternalId, + displayName: 'author', + identities: [ + { + signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS, + issuer: 'issuer', + issuerAssignedId: 'author@example.com', + }, + ], + }, + ]; + }, + }); + const spy = jest.spyOn(service["sendgridService"], "sendMail").mockImplementation(); + + const initTask = await getTask(source, taskId); + + await service.checkin( + makeContext('trackingId', 'requestId'), + 1, + 'typist-user-external-id', + ); + const resultTask = await getTask(source, taskId); + + expect(resultTask?.status).toEqual('Finished'); + expect(resultTask?.finished_at).not.toEqual(initTask?.finished_at); + //メール送信処理が呼ばれていない + expect(spy).not.toHaveBeenCalled(); + }); + it('API実行者が文字起こし実行中のタスクである場合、タスクをチェックインできる。(文字起こし完了メールはAuthorだけに送信する)', async () => { + if (!source) fail(); + const notificationhubServiceMockValue = + makeDefaultNotificationhubServiceMockValue(); + const module = await makeTaskTestingModuleWithNotificaiton( + source, + notificationhubServiceMockValue, + ); + if (!module) fail(); + const { account, admin } = await makeTestAccount(source); + const { id: typistUserId, external_id: typistExternalId } = + await makeTestUser(source, { + account_id: account.id, + external_id: 'typist-user-external-id', + role: 'typist', + }); + const { id: authorUserId, external_id: authorExternalId } = + await makeTestUser(source, { + account_id: account.id, + external_id: 'author-user-external-id', + role: 'author', + author_id: 'MY_AUTHOR_ID', + }); + const { taskId } = await createTask( + source, + account.id, + authorUserId, + 'MY_AUTHOR_ID', + '', + '01', + '00000001', + 'InProgress', + typistUserId, + ); + await createCheckoutPermissions(source, taskId, typistUserId); + + const service = module.get(TasksService); + overrideAdB2cService(service, { + getUsers: async () => { + return [ + { + id: admin.external_id, + displayName: 'admin', + identities: [ + { + signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS, + issuer: 'issuer', + issuerAssignedId: 'admin@example.com', + }, + ], + }, + { + id: typistExternalId, + displayName: 'typist', + identities: [ + { + signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS, + issuer: 'issuer', + issuerAssignedId: 'typist@example.com', + }, + ], + }, + { + id: authorExternalId, + displayName: 'author', + identities: [ + { + signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS, + issuer: 'issuer', + issuerAssignedId: 'author@example.com', + }, + ], + }, + ]; + }, + }); + let _to = Array(10); + overrideSendgridService(service, { + sendMail: async ( + context: Context, + to: string[], + cc: string[], + from: string, + subject: string, + text: string, + html: string, + ) => { + _to = to; + }, + }); + + const initTask = await getTask(source, taskId); + + await service.checkin( + makeContext('trackingId', 'requestId'), + 1, + 'typist-user-external-id', + ); + const resultTask = await getTask(source, taskId); + + expect(resultTask?.status).toEqual('Finished'); + expect(resultTask?.finished_at).not.toEqual(initTask?.finished_at); + //メール送信処理が呼ばれていない + expect(_to.length).toBe(1) + expect(_to).toEqual(['author@example.com']); + }); }); describe('suspend', () => { diff --git a/dictation_server/src/features/tasks/tasks.service.ts b/dictation_server/src/features/tasks/tasks.service.ts index fd335d4..f816b8f 100644 --- a/dictation_server/src/features/tasks/tasks.service.ts +++ b/dictation_server/src/features/tasks/tasks.service.ts @@ -474,11 +474,7 @@ export class TasksService { if (!typist) { throw new Error(`typist not found. id=${externalId}`); } - const { displayName: typistName, emailAddress: typistEmail } = - getUserNameAndMailAddress(typist); - if (!typistEmail) { - throw new Error(`typist email not found. id=${externalId}`); - } + const { displayName: typistName } = getUserNameAndMailAddress(typist); const primaryAdmin = usersInfo.find( (x) => x.id === primaryAdminExternalId, @@ -495,7 +491,6 @@ export class TasksService { await this.sendgridService.sendMailWithU117( context, authorNotification ? authorEmail : null, - typistEmail, authorName, task.file.file_name.replace('.zip', ''), typistName, diff --git a/dictation_server/src/features/users/users.service.spec.ts b/dictation_server/src/features/users/users.service.spec.ts index 899167e..438bb3b 100644 --- a/dictation_server/src/features/users/users.service.spec.ts +++ b/dictation_server/src/features/users/users.service.spec.ts @@ -3417,7 +3417,7 @@ describe('UsersService.deleteUser', () => { const userArchive = await getUserArchive(source); expect(userArchive[0].external_id).toBe(external_id); } - },600000); + }); it('存在しないユーザは削除できない', async () => { if (!source) fail(); const module = await makeTestingModule(source); @@ -4568,7 +4568,7 @@ describe('UsersService.deleteUser', () => { fail(); } } - },600000); + }); it('削除対象ユーザー(Typist)が文字起こし担当のタスクがまだ持っている場合、削除できない(statusがBackup)', async () => { if (!source) fail(); const module = await makeTestingModule(source); diff --git a/dictation_server/src/gateways/sendgrid/sendgrid.service.ts b/dictation_server/src/gateways/sendgrid/sendgrid.service.ts index 7432e72..8d90c20 100644 --- a/dictation_server/src/gateways/sendgrid/sendgrid.service.ts +++ b/dictation_server/src/gateways/sendgrid/sendgrid.service.ts @@ -1081,7 +1081,6 @@ export class SendGridService { async sendMailWithU117( context: Context, authorEmail: string | null, - typistEmail: string, authorName: string, fileName: string, typistName: string, @@ -1105,16 +1104,14 @@ export class SendGridService { .replaceAll(TYPIST_NAME, typistName) .replaceAll(PRIMARY_ADMIN_NAME, adminName); + // OMDS_IS-380 Dictation Workflow完了通知 [U-117]  をTypistには送信しないようにしたいの対応のため送信先からtypistEmailを削除 2024年8月7日 + const to = [authorEmail].filter((x): x is string => x !== null); + if (to.length === 0) { + this.logger.log('There is no email recipient.'); + return; + } // メールを送信する - await this.sendMail( - context, - [authorEmail, typistEmail].filter((x): x is string => x !== null), // authorEmailがnullの場合は除外する - [], - this.mailFrom, - subject, - text, - html, - ); + await this.sendMail(context, to, [], this.mailFrom, subject, text, html); } finally { this.logger.log( `[OUT] [${context.getTrackingId()}] ${this.sendMailWithU117.name}`,