+ {
+ setIsCheckedPrivacyNotice(e.target.checked);
}}
/>
{t(getTranslationID("signupPage.label.termsCheckBox"))}
@@ -396,8 +433,9 @@ const SignupInput: React.FC = (): JSX.Element => {
getTranslationID("signupPage.label.createAccountButton")
)}
className={`${styles.formSubmit}
- ${isAgreePolicy && styles.isActive}
- ${styles.marginBtm0}`}
+ ${styles.marginBtm0}
+ ${canClickButton() ? styles.isActive : ""}
+ `}
onClick={() => {
setIsPushCreateButton(true);
onSubmit();
diff --git a/dictation_client/src/pages/TermsPage/index.tsx b/dictation_client/src/pages/TermsPage/index.tsx
index 52f2a0b..4e5e910 100644
--- a/dictation_client/src/pages/TermsPage/index.tsx
+++ b/dictation_client/src/pages/TermsPage/index.tsx
@@ -166,8 +166,9 @@ const TermsPage: React.FC = (): JSX.Element => {
{` ${t(getTranslationID("termsPage.label.forOdms"))}`}
-
+
{
{` ${t(getTranslationID("termsPage.label.forOdms"))}`}
-
+
{
{` ${t(getTranslationID("termsPage.label.forOdms"))}`}
-
+
Date: Thu, 18 Jan 2024 06:28:28 +0000
Subject: [PATCH 13/17] =?UTF-8?q?Merged=20PR=20693:=20[=E3=83=86=E3=82=B9?=
=?UTF-8?q?=E3=83=88FB=E5=AF=BE=E5=BF=9C]Workflow=E7=94=BB=E9=9D=A2?=
=?UTF-8?q?=E3=81=A7=E3=81=AE=E3=82=BD=E3=83=BC=E3=83=88=E6=A9=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## 概要
[Task3503: テスト対応](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3503)
- workflowsのソート条件を変更
- AuthorIDの昇順
- AuthorIDが同じ場合は、WorktypeIDの昇順
## レビューポイント
- 修正内容の認識があっているか
## 動作確認状況
- ローカルで確認
## 補足
- 相談、参考資料などがあれば
---
.../workflows/workflows.service.spec.ts | 75 +++++++++++++------
.../workflows/workflows.repository.service.ts | 5 +-
2 files changed, 57 insertions(+), 23 deletions(-)
diff --git a/dictation_server/src/features/workflows/workflows.service.spec.ts b/dictation_server/src/features/workflows/workflows.service.spec.ts
index 177a048..4728510 100644
--- a/dictation_server/src/features/workflows/workflows.service.spec.ts
+++ b/dictation_server/src/features/workflows/workflows.service.spec.ts
@@ -47,22 +47,23 @@ describe('getWorkflows', () => {
const { account, admin } = await makeTestAccount(source, { tier: 5 });
const { id: authorId1 } = await makeTestUser(source, {
external_id: 'author1',
- author_id: 'AUTHOR1',
+ author_id: 'BBBBB',
account_id: account.id,
role: USER_ROLES.AUTHOR,
});
const { id: authorId2 } = await makeTestUser(source, {
external_id: 'author2',
- author_id: 'AUTHOR2',
+ author_id: 'AAAAA',
account_id: account.id,
role: USER_ROLES.AUTHOR,
});
const { id: authorId3 } = await makeTestUser(source, {
external_id: 'author3',
- author_id: 'AUTHOR3',
+ author_id: 'CCCCC',
account_id: account.id,
role: USER_ROLES.AUTHOR,
});
+
const { id: typistId, external_id: typistExternalId } = await makeTestUser(
source,
{
@@ -84,6 +85,12 @@ describe('getWorkflows', () => {
'worktype1',
);
+ const { id: worktypeId2 } = await createWorktype(
+ source,
+ account.id,
+ 'worktype2',
+ );
+
const { id: templateId1 } = await createTemplateFile(
source,
account.id,
@@ -106,6 +113,13 @@ describe('getWorkflows', () => {
templateId1,
);
const workflow3 = await createWorkflow(
+ source,
+ account.id,
+ authorId3,
+ worktypeId2,
+ undefined,
+ );
+ const workflow4 = await createWorkflow(
source,
account.id,
authorId3,
@@ -116,6 +130,7 @@ describe('getWorkflows', () => {
await createWorkflowTypist(source, workflow1.id, typistId, undefined);
await createWorkflowTypist(source, workflow2.id, undefined, userGroupId);
await createWorkflowTypist(source, workflow3.id, undefined, userGroupId);
+ await createWorkflowTypist(source, workflow4.id, undefined, userGroupId);
const service = module.get(WorkflowsService);
const context = makeContext(admin.external_id, 'requestId');
@@ -123,7 +138,7 @@ describe('getWorkflows', () => {
//作成したデータを確認
{
const workflows = await getWorkflows(source, account.id);
- expect(workflows.length).toBe(3);
+ expect(workflows.length).toBe(4);
expect(workflows[0].id).toBe(workflow1.id);
expect(workflows[0].author_id).toBe(authorId1);
expect(workflows[0].worktype_id).toBe(worktypeId1);
@@ -136,8 +151,13 @@ describe('getWorkflows', () => {
expect(workflows[2].id).toBe(workflow3.id);
expect(workflows[2].author_id).toBe(authorId3);
- expect(workflows[2].worktype_id).toBe(worktypeId1);
+ expect(workflows[2].worktype_id).toBe(worktypeId2);
expect(workflows[2].template_id).toBe(null);
+
+ expect(workflows[3].id).toBe(workflow4.id);
+ expect(workflows[3].author_id).toBe(authorId3);
+ expect(workflows[3].worktype_id).toBe(worktypeId1);
+ expect(workflows[3].template_id).toBe(null);
}
overrideAdB2cService(service, {
@@ -148,37 +168,48 @@ describe('getWorkflows', () => {
//実行結果を確認
{
- expect(resWorkflows.length).toBe(3);
- expect(resWorkflows[0].id).toBe(workflow1.id);
- expect(resWorkflows[0].author.id).toBe(authorId1);
- expect(resWorkflows[0].author.authorId).toBe('AUTHOR1');
- expect(resWorkflows[0].worktype?.id).toBe(worktypeId1);
- expect(resWorkflows[0].worktype?.worktypeId).toBe('worktype1');
+ expect(resWorkflows.length).toBe(4);
+
+ expect(resWorkflows[0].id).toBe(workflow2.id);
+ expect(resWorkflows[0].author.id).toBe(authorId2);
+ expect(resWorkflows[0].author.authorId).toBe('AAAAA');
+ expect(resWorkflows[0].worktype).toBe(undefined);
expect(resWorkflows[0].template?.id).toBe(templateId1);
expect(resWorkflows[0].template?.fileName).toBe('fileName1');
expect(resWorkflows[0].typists.length).toBe(1);
- expect(resWorkflows[0].typists[0].typistUserId).toBe(typistId);
- expect(resWorkflows[0].typists[0].typistName).toBe('typist1');
+ expect(resWorkflows[0].typists[0].typistGroupId).toBe(userGroupId);
+ expect(resWorkflows[0].typists[0].typistName).toBe('group1');
- expect(resWorkflows[1].id).toBe(workflow2.id);
- expect(resWorkflows[1].author.id).toBe(authorId2);
- expect(resWorkflows[1].author.authorId).toBe('AUTHOR2');
- expect(resWorkflows[1].worktype).toBe(undefined);
+ expect(resWorkflows[1].id).toBe(workflow1.id);
+ expect(resWorkflows[1].author.id).toBe(authorId1);
+ expect(resWorkflows[1].author.authorId).toBe('BBBBB');
+ expect(resWorkflows[1].worktype?.id).toBe(worktypeId1);
+ expect(resWorkflows[1].worktype?.worktypeId).toBe('worktype1');
expect(resWorkflows[1].template?.id).toBe(templateId1);
expect(resWorkflows[1].template?.fileName).toBe('fileName1');
expect(resWorkflows[1].typists.length).toBe(1);
- expect(resWorkflows[1].typists[0].typistGroupId).toBe(userGroupId);
- expect(resWorkflows[1].typists[0].typistName).toBe('group1');
+ expect(resWorkflows[1].typists[0].typistUserId).toBe(typistId);
+ expect(resWorkflows[1].typists[0].typistName).toBe('typist1');
- expect(resWorkflows[2].id).toBe(workflow3.id);
+ expect(resWorkflows[2].id).toBe(workflow4.id);
expect(resWorkflows[2].author.id).toBe(authorId3);
- expect(resWorkflows[2].author.authorId).toBe('AUTHOR3');
+ expect(resWorkflows[2].author.authorId).toBe('CCCCC');
expect(resWorkflows[2].worktype?.id).toBe(worktypeId1);
expect(resWorkflows[2].worktype?.worktypeId).toBe('worktype1');
expect(resWorkflows[2].template).toBe(undefined);
expect(resWorkflows[2].typists.length).toBe(1);
expect(resWorkflows[2].typists[0].typistGroupId).toBe(userGroupId);
expect(resWorkflows[2].typists[0].typistName).toBe('group1');
+
+ expect(resWorkflows[3].id).toBe(workflow3.id);
+ expect(resWorkflows[3].author.id).toBe(authorId3);
+ expect(resWorkflows[3].author.authorId).toBe('CCCCC');
+ expect(resWorkflows[3].worktype?.id).toBe(worktypeId2);
+ expect(resWorkflows[3].worktype?.worktypeId).toBe('worktype2');
+ expect(resWorkflows[3].template).toBe(undefined);
+ expect(resWorkflows[3].typists.length).toBe(1);
+ expect(resWorkflows[3].typists[0].typistGroupId).toBe(userGroupId);
+ expect(resWorkflows[3].typists[0].typistName).toBe('group1');
}
});
@@ -209,7 +240,7 @@ describe('getWorkflows', () => {
const module = await makeTestingModule(source);
if (!module) fail();
// 第五階層のアカウント作成
- const { account, admin } = await makeTestAccount(source, { tier: 5 });
+ const { admin } = await makeTestAccount(source, { tier: 5 });
const service = module.get(WorkflowsService);
const context = makeContext(admin.external_id, 'requestId');
diff --git a/dictation_server/src/repositories/workflows/workflows.repository.service.ts b/dictation_server/src/repositories/workflows/workflows.repository.service.ts
index b945380..563daee 100644
--- a/dictation_server/src/repositories/workflows/workflows.repository.service.ts
+++ b/dictation_server/src/repositories/workflows/workflows.repository.service.ts
@@ -50,7 +50,10 @@ export class WorkflowsRepositoryService {
},
},
order: {
- id: 'ASC',
+ author: {
+ author_id: 'ASC',
+ },
+ worktype_id: 'ASC',
},
comment: `${context.getTrackingId()}_${new Date().toUTCString()}`,
});
From d23336a0658bfcc5ddc333f69962e88172286c62 Mon Sep 17 00:00:00 2001
From: "SAITO-PC-3\\saito.k"
Date: Fri, 19 Jan 2024 10:25:17 +0900
Subject: [PATCH 14/17] =?UTF-8?q?workflow=E3=81=AE=E3=82=BD=E3=83=BC?=
=?UTF-8?q?=E3=83=88=E6=9D=A1=E4=BB=B6=E3=81=AE=E6=8C=87=E5=AE=9A=E3=81=AB?=
=?UTF-8?q?=E8=AA=A4=E3=82=8A=E3=81=8C=E3=81=82=E3=81=A3=E3=81=9F=E3=81=AE?=
=?UTF-8?q?=E3=81=A7=E4=BF=AE=E6=AD=A3=20=E3=83=86=E3=82=B9=E3=83=88?=
=?UTF-8?q?=E3=82=82=E3=81=9D=E3=81=AE=E8=AA=A4=E3=82=8A=E3=82=92=E6=A4=9C?=
=?UTF-8?q?=E7=9F=A5=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?=
=?UTF-8?q?=E4=BF=AE=E6=AD=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../workflows/workflows.service.spec.ts | 22 +++++++++----------
.../workflows/workflows.repository.service.ts | 4 +++-
2 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/dictation_server/src/features/workflows/workflows.service.spec.ts b/dictation_server/src/features/workflows/workflows.service.spec.ts
index 4728510..7b0e3cc 100644
--- a/dictation_server/src/features/workflows/workflows.service.spec.ts
+++ b/dictation_server/src/features/workflows/workflows.service.spec.ts
@@ -82,13 +82,13 @@ describe('getWorkflows', () => {
const { id: worktypeId1 } = await createWorktype(
source,
account.id,
- 'worktype1',
+ 'worktype2',
);
const { id: worktypeId2 } = await createWorktype(
source,
account.id,
- 'worktype2',
+ 'worktype1',
);
const { id: templateId1 } = await createTemplateFile(
@@ -102,7 +102,7 @@ describe('getWorkflows', () => {
source,
account.id,
authorId1,
- worktypeId1,
+ worktypeId2,
templateId1,
);
const workflow2 = await createWorkflow(
@@ -116,14 +116,14 @@ describe('getWorkflows', () => {
source,
account.id,
authorId3,
- worktypeId2,
+ worktypeId1,
undefined,
);
const workflow4 = await createWorkflow(
source,
account.id,
authorId3,
- worktypeId1,
+ worktypeId2,
undefined,
);
@@ -141,7 +141,7 @@ describe('getWorkflows', () => {
expect(workflows.length).toBe(4);
expect(workflows[0].id).toBe(workflow1.id);
expect(workflows[0].author_id).toBe(authorId1);
- expect(workflows[0].worktype_id).toBe(worktypeId1);
+ expect(workflows[0].worktype_id).toBe(worktypeId2);
expect(workflows[0].template_id).toBe(templateId1);
expect(workflows[1].id).toBe(workflow2.id);
@@ -151,12 +151,12 @@ describe('getWorkflows', () => {
expect(workflows[2].id).toBe(workflow3.id);
expect(workflows[2].author_id).toBe(authorId3);
- expect(workflows[2].worktype_id).toBe(worktypeId2);
+ expect(workflows[2].worktype_id).toBe(worktypeId1);
expect(workflows[2].template_id).toBe(null);
expect(workflows[3].id).toBe(workflow4.id);
expect(workflows[3].author_id).toBe(authorId3);
- expect(workflows[3].worktype_id).toBe(worktypeId1);
+ expect(workflows[3].worktype_id).toBe(worktypeId2);
expect(workflows[3].template_id).toBe(null);
}
@@ -183,7 +183,7 @@ describe('getWorkflows', () => {
expect(resWorkflows[1].id).toBe(workflow1.id);
expect(resWorkflows[1].author.id).toBe(authorId1);
expect(resWorkflows[1].author.authorId).toBe('BBBBB');
- expect(resWorkflows[1].worktype?.id).toBe(worktypeId1);
+ expect(resWorkflows[1].worktype?.id).toBe(worktypeId2);
expect(resWorkflows[1].worktype?.worktypeId).toBe('worktype1');
expect(resWorkflows[1].template?.id).toBe(templateId1);
expect(resWorkflows[1].template?.fileName).toBe('fileName1');
@@ -194,7 +194,7 @@ describe('getWorkflows', () => {
expect(resWorkflows[2].id).toBe(workflow4.id);
expect(resWorkflows[2].author.id).toBe(authorId3);
expect(resWorkflows[2].author.authorId).toBe('CCCCC');
- expect(resWorkflows[2].worktype?.id).toBe(worktypeId1);
+ expect(resWorkflows[2].worktype?.id).toBe(worktypeId2);
expect(resWorkflows[2].worktype?.worktypeId).toBe('worktype1');
expect(resWorkflows[2].template).toBe(undefined);
expect(resWorkflows[2].typists.length).toBe(1);
@@ -204,7 +204,7 @@ describe('getWorkflows', () => {
expect(resWorkflows[3].id).toBe(workflow3.id);
expect(resWorkflows[3].author.id).toBe(authorId3);
expect(resWorkflows[3].author.authorId).toBe('CCCCC');
- expect(resWorkflows[3].worktype?.id).toBe(worktypeId2);
+ expect(resWorkflows[3].worktype?.id).toBe(worktypeId1);
expect(resWorkflows[3].worktype?.worktypeId).toBe('worktype2');
expect(resWorkflows[3].template).toBe(undefined);
expect(resWorkflows[3].typists.length).toBe(1);
diff --git a/dictation_server/src/repositories/workflows/workflows.repository.service.ts b/dictation_server/src/repositories/workflows/workflows.repository.service.ts
index 563daee..cf28006 100644
--- a/dictation_server/src/repositories/workflows/workflows.repository.service.ts
+++ b/dictation_server/src/repositories/workflows/workflows.repository.service.ts
@@ -53,7 +53,9 @@ export class WorkflowsRepositoryService {
author: {
author_id: 'ASC',
},
- worktype_id: 'ASC',
+ worktype: {
+ custom_worktype_id: 'ASC',
+ },
},
comment: `${context.getTrackingId()}_${new Date().toUTCString()}`,
});
From 6e931c5afb56637b5e783eeb88e53687aa5a5dd5 Mon Sep 17 00:00:00 2001
From: "makabe.t"
Date: Tue, 23 Jan 2024 00:21:17 +0000
Subject: [PATCH 15/17] =?UTF-8?q?Merged=20PR=20694:=20=E3=83=86=E3=82=B9?=
=?UTF-8?q?=E3=83=88=E5=AF=BE=E5=BF=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## 概要
[Task3504: テスト対応](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3504)
- ユーザー取得APIで取得するユーザーの順序をAuthor、Typist、Noneの順になるようにしました。
## レビューポイント
- 単純なorderの指定ではうまくいかないようでしたのでDBからの取得後にソートするようにしていますが処理として適切でしょうか?
## UIの変更
- なし
## 動作確認状況
- ローカルで確認
---
dictation_server/src/constants/index.ts | 10 +++++++++
.../src/features/users/users.service.spec.ts | 22 +++++++++----------
.../users/users.repository.service.ts | 16 +++++++++++++-
3 files changed, 35 insertions(+), 13 deletions(-)
diff --git a/dictation_server/src/constants/index.ts b/dictation_server/src/constants/index.ts
index da502d7..511e4b8 100644
--- a/dictation_server/src/constants/index.ts
+++ b/dictation_server/src/constants/index.ts
@@ -88,6 +88,16 @@ export const USER_ROLES = {
TYPIST: 'typist',
} as const;
+/**
+ * ロールのソート順
+ * @const {string[]}
+ */
+export const USER_ROLE_ORDERS = [
+ USER_ROLES.AUTHOR,
+ USER_ROLES.TYPIST,
+ USER_ROLES.NONE,
+] as string[];
+
/**
* ライセンス注文状態
* @const {string[]}
diff --git a/dictation_server/src/features/users/users.service.spec.ts b/dictation_server/src/features/users/users.service.spec.ts
index 82a8199..a02016e 100644
--- a/dictation_server/src/features/users/users.service.spec.ts
+++ b/dictation_server/src/features/users/users.service.spec.ts
@@ -1,5 +1,4 @@
import { HttpException, HttpStatus } from '@nestjs/common';
-import { AccessToken } from '../../common/token';
import { makeErrorResponse } from '../../common/error/makeErrorResponse';
import {
makeDefaultAdB2cMockValue,
@@ -1389,6 +1388,16 @@ describe('UsersService.getUsers', () => {
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
+ const { id: typistUserId } = await makeTestUser(source, {
+ account_id: accountId,
+ external_id: 'external_id2',
+ role: 'typist',
+ author_id: undefined,
+ auto_renew: true,
+ encryption: false,
+ encryption_password: undefined,
+ prompt: false,
+ });
const { external_id: externalId_author, id: authorUserId } =
await makeTestUser(source, {
account_id: accountId,
@@ -1401,17 +1410,6 @@ describe('UsersService.getUsers', () => {
prompt: false,
});
- const { id: typistUserId } = await makeTestUser(source, {
- account_id: accountId,
- external_id: 'external_id2',
- role: 'typist',
- author_id: undefined,
- auto_renew: true,
- encryption: false,
- encryption_password: undefined,
- prompt: false,
- });
-
await createUserGroup(source, accountId, 'group1', [typistUserId]);
const { id: noneUserId } = await makeTestUser(source, {
diff --git a/dictation_server/src/repositories/users/users.repository.service.ts b/dictation_server/src/repositories/users/users.repository.service.ts
index 9237bdd..ae3fccc 100644
--- a/dictation_server/src/repositories/users/users.repository.service.ts
+++ b/dictation_server/src/repositories/users/users.repository.service.ts
@@ -29,6 +29,7 @@ import {
TIERS,
TRIAL_LICENSE_ISSUE_NUM,
USER_ROLES,
+ USER_ROLE_ORDERS,
} from '../../constants';
import { License } from '../licenses/entity/license.entity';
import { NewTrialLicenseExpirationDate } from '../../features/licenses/types/types';
@@ -496,10 +497,23 @@ export class UsersRepositoryService {
license: true,
},
where: { account_id: accountId },
+
comment: `${context.getTrackingId()}_${new Date().toUTCString()}`,
});
- return dbUsers;
+ // RoleのAuthor、Typist、Noneの順に並び替える
+ const roleSortedUsers = dbUsers.sort((a, b) => {
+ // Roleが同じ場合はIDの昇順で並び替える
+ if (a.role === b.role) {
+ return a.id - b.id;
+ }
+
+ return (
+ USER_ROLE_ORDERS.indexOf(a.role) - USER_ROLE_ORDERS.indexOf(b.role)
+ );
+ });
+
+ return roleSortedUsers;
});
}
From cf56239da22b4dfd02fad087f38a2ed90b9c82c2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=B9=AF=E6=9C=AC=20=E9=96=8B?=
Date: Tue, 23 Jan 2024 07:58:42 +0000
Subject: [PATCH 16/17] =?UTF-8?q?Merged=20PR=20669:=20Pipeline=E4=B8=8A?=
=?UTF-8?q?=E3=81=A7docker-compose=E3=82=92=E7=94=A8=E3=81=84=E3=81=A6MySQ?=
=?UTF-8?q?L=E3=82=92=E8=B5=B7=E5=8B=95=E3=81=99=E3=82=8B=E6=96=B9?=
=?UTF-8?q?=E6=B3=95=E3=82=92=E8=AA=BF=E6=9F=BB=E3=81=99=E3=82=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## 概要
[Task3427: Pipeline上でdocker-composeを用いてMySQLを起動する方法を調査する](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3427)
- MySQLでUnitTestを実施する仕組みを作成
- DevContainerにUnitTestからのみアクセスされるMySQLが動くコンテナ( `test_mysql_db` )を追加
- テストでMySQLを使用し、上記 `test_mysql_db` に対してアクセスするよう構成
- テストの前処理で `test_mysql_db` の全てのテーブルをTRUNCATEする処理を実行し、データをクリアする
- 常にテスト用MySQLは起動しているが、テスト実行前にクリアされるので空っぽ前提の状態でテストを実施できる
- 実際にMySQLを使用して実行されるテストを1つ追加
- `users.service.spec.ts | UsersService.createUser` が対象
- Pipeline上でDevContainerを起動し、DevContainer内で `npm ci` `(UnitTest用DBへの) migration` `npm run test` を行う仕組みを作成
- Pipelineを追加
- **StagingPipelineでテスト・ステップを切り出し**
- Pipelineテスト用DevContainer(のdocker-compose.yml)を作成
- 構成は通常の物と同一だが、ネットワーク設定だけ外部のMySQLやRedisと通信しない前提に変更している
- テストの実行環境を自己ホストではなく、一般で提供されているマシンに変更
- 自己ホストのマシンにdocker-composeが入ってない/ビルド後のクリア処理が大変等の理由
- テストで使用する環境変数を `.env.test` という別環境変数に切り出し
- そうすることで、PipelineでKeyVaultへのアクセスをする必要がなくなる
- **migrationの漏れを修正**
- テストが通らないことで発覚したmigration漏れを修正
- **テストコードを修正**
- **Date型のミリ秒単位の誤差を setMillseconds(0) を用いることで0にセットするコードを追加(ライセンス付近)**
## レビューポイント
- **WIPレビュー以降の追加の修正で違和感のある箇所はないか**
- コミット履歴等で追っていただいた方が楽かと思います
- 直近の`Merge branch 'develop' into feature/3427/poc-mysql-test` 以降がWIP以降に変更されたコードです
- **レビュー通過後、developのPipelineについては手動で同等のコードに変更→PRをdevelopにマージ予定だが進め方として問題はないか**
- [※WIPでレビュー済み] テスト用DevContainerを別途作成したが、現行のDevContainerを使用するよう頑張った方がいいか?
- [※WIPでレビュー済み] CI/CDの実行速度面を考慮し、使用されないMySQLとRedisのサービスとネットワーク作成が同居しているdocker-compose.ymlの実行を避けたが、管理対象は増えているので議論の余地はある
- [※WIPでレビュー済み] MySQLでUnitTestを実行する際に懸念事項はないか
- [※WIPでレビュー済み] Dockerを起動する関係でCI/CDのスピードが数分遅くなると思われるが、許容可能か
- [※WIPでレビュー済み] `.env.test` に置き換えて問題ないか
## 動作確認状況
- ローカル&Pipelineで実行して確認済
---
azure-pipelines-staging.yml | 68 +-
.../.devcontainer/docker-compose.yml | 10 +
.../.devcontainer/pipeline-docker-compose.yml | 35 +
dictation_server/.env.test | 37 +
dictation_server/db/dbconfig.yml | 4 +
.../migrations/053-delete-license-alert.sql | 6 +
dictation_server/package.json | 5 +-
dictation_server/src/common/test/init.ts | 21 +
dictation_server/src/common/test/modules.ts | 2 +-
.../accounts/accounts.controller.spec.ts | 2 +-
.../accounts/accounts.service.spec.ts | 951 ++++++++++++------
.../src/features/auth/auth.controller.spec.ts | 2 +-
.../src/features/auth/auth.service.spec.ts | 147 ++-
.../features/files/files.controller.spec.ts | 2 +-
.../src/features/files/files.service.spec.ts | 217 ++--
.../src/features/files/test/utility.ts | 2 +-
.../licenses/licenses.controller.spec.ts | 2 +-
.../licenses/licenses.service.spec.ts | 227 +++--
.../src/features/licenses/test/utility.ts | 1 +
.../notification.controller.spec.ts | 2 +-
.../test/notification.service.mock.ts | 2 +-
.../features/tasks/tasks.controller.spec.ts | 2 +-
.../src/features/tasks/tasks.service.spec.ts | 297 ++++--
.../src/features/tasks/test/utility.ts | 2 +-
.../templates/templates.controller.spec.ts | 2 +-
.../templates/templates.service.spec.ts | 41 +-
.../src/features/terms/terms.service.spec.ts | 37 +-
.../features/users/test/users.service.mock.ts | 2 +-
.../src/features/users/test/utility.ts | 2 +-
.../features/users/users.controller.spec.ts | 2 +-
.../src/features/users/users.service.spec.ts | 255 +++--
.../workflows/workflows.controller.spec.ts | 2 +-
.../workflows/workflows.service.spec.ts | 154 ++-
33 files changed, 1708 insertions(+), 835 deletions(-)
create mode 100644 dictation_server/.devcontainer/pipeline-docker-compose.yml
create mode 100644 dictation_server/.env.test
create mode 100644 dictation_server/db/migrations/053-delete-license-alert.sql
create mode 100644 dictation_server/src/common/test/init.ts
diff --git a/azure-pipelines-staging.yml b/azure-pipelines-staging.yml
index 86f970d..65c19c4 100644
--- a/azure-pipelines-staging.yml
+++ b/azure-pipelines-staging.yml
@@ -27,9 +27,30 @@ jobs:
exit 1
fi
displayName: 'タグが付けられたCommitがmainブランチに存在するか確認'
-- job: backend_build
+- job: backend_test
dependsOn: initialize
condition: succeeded('initialize')
+ displayName: UnitTest
+ pool:
+ vmImage: ubuntu-latest
+ steps:
+ - checkout: self
+ clean: true
+ fetchDepth: 1
+ - task: Bash@3
+ displayName: Bash Script (Test)
+ inputs:
+ targetType: inline
+ workingDirectory: dictation_server/.devcontainer
+ script: |
+ docker-compose -f pipeline-docker-compose.yml build
+ docker-compose -f pipeline-docker-compose.yml up -d
+ docker-compose exec -T dictation_server sudo npm ci
+ docker-compose exec -T dictation_server sudo npm run migrate:up:test
+ docker-compose exec -T dictation_server sudo npm run test
+- job: backend_build
+ dependsOn: backend_test
+ condition: succeeded('backend_test')
displayName: Build And Push Backend Image
pool:
name: odms-deploy-pipeline
@@ -43,51 +64,6 @@ jobs:
command: ci
workingDir: dictation_server
verbose: false
- - task: AzureKeyVault@2
- displayName: 'Azure Key Vault: kv-odms-secret-stg'
- inputs:
- ConnectedServiceName: 'omds-service-connection-stg'
- KeyVaultName: kv-odms-secret-stg
- SecretsFilter: '*'
- - task: Bash@3
- displayName: Bash Script (Test)
- inputs:
- targetType: inline
- script: |
- cd dictation_server
- npm run test
- env:
- JWT_PUBLIC_KEY: $(token-public-key)
- JWT_PRIVATE_KEY: $(token-private-key)
- SENDGRID_API_KEY: $(sendgrid-api-key)
- NOTIFICATION_HUB_NAME: $(notification-hub-name)
- NOTIFICATION_HUB_CONNECT_STRING: $(notification-hub-connect-string)
- STORAGE_ACCOUNT_NAME_US: $(storage-account-name-us)
- STORAGE_ACCOUNT_NAME_AU: $(storage-account-name-au)
- STORAGE_ACCOUNT_NAME_EU: $(storage-account-name-eu)
- STORAGE_ACCOUNT_KEY_US: $(storage-account-key-us)
- STORAGE_ACCOUNT_KEY_AU: $(storage-account-key-au)
- STORAGE_ACCOUNT_KEY_EU: $(storage-account-key-eu)
- STORAGE_ACCOUNT_ENDPOINT_US: $(storage-account-endpoint-us)
- STORAGE_ACCOUNT_ENDPOINT_AU: $(storage-account-endpoint-au)
- STORAGE_ACCOUNT_ENDPOINT_EU: $(storage-account-endpoint-eu)
- ADB2C_TENANT_ID: $(adb2c-tenant-id)
- ADB2C_CLIENT_ID: $(adb2c-client-id)
- ADB2C_CLIENT_SECRET: $(adb2c-client-secret)
- MAIL_FROM: xxxxxx
- APP_DOMAIN: xxxxxxxxx
- EMAIL_CONFIRM_LIFETIME: 0
- TENANT_NAME: xxxxxxxxxxxx
- SIGNIN_FLOW_NAME: xxxxxxxxxxxx
- STORAGE_TOKEN_EXPIRE_TIME: 0
- REFRESH_TOKEN_LIFETIME_WEB: 86400000
- REFRESH_TOKEN_LIFETIME_DEFAULT: 2592000000
- ACCESS_TOKEN_LIFETIME_WEB: 7200000
- REDIS_HOST: xxxxxxxxxxxx
- REDIS_PORT: 0
- REDIS_PASSWORD: xxxxxxxxxxxx
- ADB2C_CACHE_TTL: 0
- STAGE: local
- task: Docker@0
displayName: build
inputs:
diff --git a/dictation_server/.devcontainer/docker-compose.yml b/dictation_server/.devcontainer/docker-compose.yml
index 47cf396..ca3a9a8 100644
--- a/dictation_server/.devcontainer/docker-compose.yml
+++ b/dictation_server/.devcontainer/docker-compose.yml
@@ -2,6 +2,7 @@ version: '3'
services:
dictation_server:
+ container_name: dictation_server_dev_container
env_file: ../.env
build: .
working_dir: /app/dictation_server
@@ -16,6 +17,15 @@ services:
- CHOKIDAR_USEPOLLING=true
networks:
- external
+ test_mysql_db:
+ image: mysql:8.0-bullseye
+ environment:
+ MYSQL_ROOT_PASSWORD: root_password
+ MYSQL_DATABASE: odms
+ MYSQL_USER: user
+ MYSQL_PASSWORD: password
+ networks:
+ - external
networks:
external:
name: omds_network
diff --git a/dictation_server/.devcontainer/pipeline-docker-compose.yml b/dictation_server/.devcontainer/pipeline-docker-compose.yml
new file mode 100644
index 0000000..19708a2
--- /dev/null
+++ b/dictation_server/.devcontainer/pipeline-docker-compose.yml
@@ -0,0 +1,35 @@
+version: '3'
+
+services:
+ dictation_server:
+ container_name: dictation_server_dev_container
+ env_file: ../.env
+ build: .
+ working_dir: /app/dictation_server
+ ports:
+ - '8081:8081'
+ volumes:
+ - ../../:/app
+ - node_modules:/app/dictation_server/node_modules
+ expose:
+ - '8081'
+ environment:
+ - CHOKIDAR_USEPOLLING=true
+ depends_on:
+ - test_mysql_db
+ networks:
+ - network
+ test_mysql_db:
+ image: mysql:8.0-bullseye
+ environment:
+ MYSQL_ROOT_PASSWORD: root_password
+ MYSQL_DATABASE: odms
+ MYSQL_USER: user
+ MYSQL_PASSWORD: password
+ networks:
+ - network
+networks:
+ network:
+ name: test_network
+volumes:
+ node_modules:
\ No newline at end of file
diff --git a/dictation_server/.env.test b/dictation_server/.env.test
new file mode 100644
index 0000000..a2748df
--- /dev/null
+++ b/dictation_server/.env.test
@@ -0,0 +1,37 @@
+STAGE=local
+NO_COLOR=TRUE
+CORS=TRUE
+PORT=8081
+TENANT_NAME=xxxxxxxxxx
+SIGNIN_FLOW_NAME=b2c_1_signin_xxx
+ADB2C_TENANT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
+ADB2C_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
+ADB2C_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ADB2C_ORIGIN=https://example.com/xxxxxxxxx.onmicrosoft.com/b2c_1_signin_xxx/
+KEY_VAULT_NAME=xxxxxxxxxxxx
+JWT_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEA5IZZNgDew9eGmuFTezwdHYLSaJvUPPIKYoiOeVLD1paWNI51\n7Vkaoh0ngprcKOdv6T1N07V4igK7mOim2zY3yCTR6wcWR3PfFJrl9vh5SOo79koZ\noJb27YiM4jtxfx2dezzp0T2GoNR5rRolPUbWFJXnDe0DVXYXpJLb4LAlF2XAyYX0\nSYKUVUsJnzm5k4xbXtnwPwVbpm0EdswBE6qSfiL9zWk9dvHoKzSnfSDzDFoFcEoV\nchawzYXf/MM1YR4wo5XyzECc6Q5Ah4z522//mBNNaDHv83Yuw3mGShT73iJ0JQdk\nTturshv2Ecma38r6ftrIwNYXw4VVatJM8+GOOQIDAQABAoIBADrwp7u097+dK/tw\nWD61n3DIGAqg/lmFt8X4IH8MKLSE/FKr16CS1bqwOEuIM3ZdUtDeXd9Xs7IsyEPE\n5ZwuXK7DSF0M4+Mj8Ip49Q0Aww9aUoLQU9HGfgN/r4599GTrt31clZXA/6Mlighq\ncOZgCcEfdItz8OMu5SQuOIW4CKkCuaWnPOP26UqZocaXNZfpZH0iFLATMMH/TT8x\nay9ToHTQYE17ijdQ/EOLSwoeDV1CU1CIE3P4YfLJjvpKptly5dTevriHEzBi70Jx\n/KEPUn9Jj2gZafrUxRVhmMbm1zkeYxL3gsqRuTzRjEeeILuZhSJyCkQZyUNARxsg\nQY4DZfECgYEA+YLKUtmYTx60FS6DJ4s31TAsXY8kwhq/lB9E3GBZKDd0DPayXEeK\n4UWRQDTT6MI6fedW69FOZJ5sFLp8HQpcssb4Weq9PCpDhNTx8MCbdH3Um5QR3vfW\naKq/1XM8MDUnx5XcNYd87Aw3azvJAvOPr69as8IPnj6sKaRR9uQjbYUCgYEA6nfV\n5j0qmn0EJXZJblk4mvvjLLoWSs17j9YlrZJlJxXMDFRYtgnelv73xMxOMvcGoxn5\nifs7dpaM2x5EmA6jVU5sYaB/beZGEPWqPYGyjIwXPvUGAAv8Gbnvpp+xlSco/Dum\nIq0w+43ry5/xWh6CjfrvKV0J2bDOiJwPEdu/8iUCgYEAnBBSvL+dpN9vhFAzeOh7\nY71eAqcmNsLEUcG9MJqTKbSFwhYMOewF0iHRWHeylEPokhfBJn8kqYrtz4lVWFTC\n5o/Nh3BsLNXCpbMMIapXkeWiti1HgE9ErPMgSkJpwz18RDpYIqM8X+jEQS6D7HSr\nyxfDg+w+GJza0rEVE3hfMIECgYBw+KZ2VfhmEWBjEHhXE+QjQMR3s320MwebCUqE\nNCpKx8TWF/naVC0MwfLtvqbbBY0MHyLN6d//xpA9r3rLbRojqzKrY2KiuDYAS+3n\nzssRzxoQOozWju+8EYu30/ADdqfXyIHG6X3VZs87AGiQzGyJLmP3oR1y5y7MQa09\nJI16hQKBgHK5uwJhGa281Oo5/FwQ3uYLymbNwSGrsOJXiEu2XwJEXwVi2ELOKh4/\n03pBk3Kva3fIwEK+vCzDNnxShIQqBE76/2I1K1whOfoUehhYvKHGaXl2j70Zz9Ks\nrkGW1cx7p+yDqATDrwHBHTHFh5bUTTn8dN40n0e0W/llurpbBkJM\n-----END RSA PRIVATE KEY-----\n"
+JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5IZZNgDew9eGmuFTezwd\nHYLSaJvUPPIKYoiOeVLD1paWNI517Vkaoh0ngprcKOdv6T1N07V4igK7mOim2zY3\nyCTR6wcWR3PfFJrl9vh5SOo79koZoJb27YiM4jtxfx2dezzp0T2GoNR5rRolPUbW\nFJXnDe0DVXYXpJLb4LAlF2XAyYX0SYKUVUsJnzm5k4xbXtnwPwVbpm0EdswBE6qS\nfiL9zWk9dvHoKzSnfSDzDFoFcEoVchawzYXf/MM1YR4wo5XyzECc6Q5Ah4z522//\nmBNNaDHv83Yuw3mGShT73iJ0JQdkTturshv2Ecma38r6ftrIwNYXw4VVatJM8+GO\nOQIDAQAB\n-----END PUBLIC KEY-----\n"
+SENDGRID_API_KEY=SG.P_xxxx_xxxxxxxxxxxxxxx.xxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxx-pc
+MAIL_FROM=noreply@example.com
+NOTIFICATION_HUB_NAME=ntf-odms-dev
+NOTIFICATION_HUB_CONNECT_STRING=Endpoint=sb://example.com/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=
+APP_DOMAIN=http://localhost:8081/
+STORAGE_TOKEN_EXPIRE_TIME=30
+STORAGE_ACCOUNT_NAME_US=saxxxxusxxx
+STORAGE_ACCOUNT_NAME_AU=saxxxxauxxx
+STORAGE_ACCOUNT_NAME_EU=saxxxxeuxxx
+STORAGE_ACCOUNT_KEY_US=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX==
+STORAGE_ACCOUNT_KEY_AU=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX==
+STORAGE_ACCOUNT_KEY_EU=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX==
+STORAGE_ACCOUNT_ENDPOINT_US=https://xxxxxxxxxxxx.blob.core.windows.net/
+STORAGE_ACCOUNT_ENDPOINT_AU=https://xxxxxxxxxxxx.blob.core.windows.net/
+STORAGE_ACCOUNT_ENDPOINT_EU=https://xxxxxxxxxxxx.blob.core.windows.net/
+ACCESS_TOKEN_LIFETIME_WEB=7200000
+REFRESH_TOKEN_LIFETIME_WEB=86400000
+REFRESH_TOKEN_LIFETIME_DEFAULT=2592000000
+EMAIL_CONFIRM_LIFETIME=86400000
+REDIS_HOST=redis-cache
+REDIS_PORT=6379
+REDIS_PASSWORD=omdsredispass
+ADB2C_CACHE_TTL=86400
+TEMPLATE_ROOT=dist
\ No newline at end of file
diff --git a/dictation_server/db/dbconfig.yml b/dictation_server/db/dbconfig.yml
index 25fdfa9..f19fc0c 100644
--- a/dictation_server/db/dbconfig.yml
+++ b/dictation_server/db/dbconfig.yml
@@ -6,3 +6,7 @@ ci:
dialect: mysql
dir: ./dictation_server/db/migrations
datasource: DB_USERNAME:DB_PASS@tcp(DB_HOST:DB_PORT)/DB_NAME?charset=utf8mb4&collation=utf8mb4_0900_ai_ci&parseTime=true
+test:
+ dialect: mysql
+ dir: /app/dictation_server/db/migrations
+ datasource: user:password@tcp(test_mysql_db:3306)/odms?charset=utf8mb4&collation=utf8mb4_0900_ai_ci&parseTime=true
\ No newline at end of file
diff --git a/dictation_server/db/migrations/053-delete-license-alert.sql b/dictation_server/db/migrations/053-delete-license-alert.sql
new file mode 100644
index 0000000..e7e6871
--- /dev/null
+++ b/dictation_server/db/migrations/053-delete-license-alert.sql
@@ -0,0 +1,6 @@
+-- +migrate Up
+ALTER TABLE `users_archive` DROP COLUMN `license_alert`;
+
+
+-- +migrate Down
+ALTER TABLE `users_archive` ADD COLUMN `license_alert` BOOLEAN NOT NULL COMMENT 'ライセンスの期限切れ通知をするかどうか';
\ No newline at end of file
diff --git a/dictation_server/package.json b/dictation_server/package.json
index 1afac08..7ca9f5b 100644
--- a/dictation_server/package.json
+++ b/dictation_server/package.json
@@ -17,7 +17,7 @@
"tc": "tsc --noEmit",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\"",
"lint:fix": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
- "test": "jest",
+ "test": "jest -w 1",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
@@ -26,7 +26,8 @@
"openapi-format": "cat \"src/api/odms/openapi.json\" | jq -c . > \"src/api/odms/openapi.json\" && prettier --write \"src/api/odms/*.json\"",
"migrate:up": "sql-migrate up -config=/app/dictation_server/db/dbconfig.yml -env=local",
"migrate:down": "sql-migrate down -config=/app/dictation_server/db/dbconfig.yml -env=local",
- "migrate:status": "sql-migrate status -config=/app/dictation_server/db/dbconfig.yml -env=local"
+ "migrate:status": "sql-migrate status -config=/app/dictation_server/db/dbconfig.yml -env=local",
+ "migrate:up:test": "sql-migrate up -config=/app/dictation_server/db/dbconfig.yml -env=test"
},
"dependencies": {
"@azure/identity": "^3.1.3",
diff --git a/dictation_server/src/common/test/init.ts b/dictation_server/src/common/test/init.ts
new file mode 100644
index 0000000..e919d16
--- /dev/null
+++ b/dictation_server/src/common/test/init.ts
@@ -0,0 +1,21 @@
+import { DataSource } from "typeorm";
+
+export const truncateAllTable = async (source: DataSource) => {
+ const entities = source.entityMetadatas;
+ const queryRunner = source.createQueryRunner();
+
+ try {
+ await queryRunner.startTransaction();
+ await queryRunner.query('SET FOREIGN_KEY_CHECKS=0');
+ for (const entity of entities) {
+ await queryRunner.query(`TRUNCATE TABLE \`${entity.tableName}\``);
+ }
+ await queryRunner.query('SET FOREIGN_KEY_CHECKS=1');
+ await queryRunner.commitTransaction();
+ } catch (err) {
+ await queryRunner.rollbackTransaction();
+ throw err;
+ } finally {
+ await queryRunner.release();
+ }
+};
\ No newline at end of file
diff --git a/dictation_server/src/common/test/modules.ts b/dictation_server/src/common/test/modules.ts
index 61c0396..7c51a50 100644
--- a/dictation_server/src/common/test/modules.ts
+++ b/dictation_server/src/common/test/modules.ts
@@ -48,7 +48,7 @@ export const makeTestingModule = async (
const module: TestingModule = await Test.createTestingModule({
imports: [
ConfigModule.forRoot({
- envFilePath: ['.env.local', '.env'],
+ envFilePath: ['.env.test', '.env'],
isGlobal: true,
}),
AuthModule,
diff --git a/dictation_server/src/features/accounts/accounts.controller.spec.ts b/dictation_server/src/features/accounts/accounts.controller.spec.ts
index 2761b0e..f69ece1 100644
--- a/dictation_server/src/features/accounts/accounts.controller.spec.ts
+++ b/dictation_server/src/features/accounts/accounts.controller.spec.ts
@@ -13,7 +13,7 @@ describe('AccountsController', () => {
const module: TestingModule = await Test.createTestingModule({
imports: [
ConfigModule.forRoot({
- envFilePath: ['.env.local', '.env'],
+ envFilePath: ['.env.test', '.env'],
isGlobal: true,
}),
],
diff --git a/dictation_server/src/features/accounts/accounts.service.spec.ts b/dictation_server/src/features/accounts/accounts.service.spec.ts
index 9b192c9..4bfd687 100644
--- a/dictation_server/src/features/accounts/accounts.service.spec.ts
+++ b/dictation_server/src/features/accounts/accounts.service.spec.ts
@@ -78,23 +78,36 @@ import { AccountsRepositoryService } from '../../repositories/accounts/accounts.
import { UsersRepositoryService } from '../../repositories/users/users.repository.service';
import { createWorkflow, getWorkflows } from '../workflows/test/utility';
import { UsersService } from '../users/users.service';
+import { truncateAllTable } from '../../common/test/init';
describe('createAccount', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
it('アカウントを作成できる', async () => {
@@ -754,20 +767,32 @@ describe('createAccount', () => {
describe('createPartnerAccount', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -1740,20 +1765,32 @@ describe('AccountsService', () => {
describe('getLicenseSummary', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
it('第五階層のライセンス情報を取得する', async () => {
@@ -1787,7 +1824,7 @@ describe('getLicenseSummary', () => {
// 有効期限が14日後のライセンスを追加(5ライセンス)
const expiryDate = new Date();
expiryDate.setDate(expiryDate.getDate() + 14);
- expiryDate.setHours(23, 59, 59, 999);
+ expiryDate.setHours(23, 59, 59, 0);
for (let i = 0; i < 5; i++) {
await createLicenseSetExpiryDateAndStatus(
source,
@@ -1812,7 +1849,7 @@ describe('getLicenseSummary', () => {
await createLicenseSetExpiryDateAndStatus(
source,
childAccountId1,
- new Date(2500, 1, 1, 23, 59, 59),
+ new Date(2037, 1, 1, 23, 59, 59),
element,
1,
);
@@ -1823,7 +1860,7 @@ describe('getLicenseSummary', () => {
await createLicenseSetExpiryDateAndStatus(
source,
childAccountId2,
- new Date(2500, 1, 1, 23, 59, 59),
+ new Date(2037, 1, 1, 23, 59, 59),
'Unallocated',
);
}
@@ -1887,20 +1924,32 @@ describe('getLicenseSummary', () => {
describe('getPartnerAccount', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -1942,7 +1991,7 @@ describe('getPartnerAccount', () => {
// 有効期限が14日後のライセンスを追加(5ライセンス)
const expiryDate = new Date();
expiryDate.setDate(expiryDate.getDate() + 14);
- expiryDate.setHours(23, 59, 59, 999);
+ expiryDate.setHours(23, 59, 59, 0);
for (let i = 0; i < 5; i++) {
await createLicenseSetExpiryDateAndStatus(
source,
@@ -1960,7 +2009,7 @@ describe('getPartnerAccount', () => {
// 有効期限が15日後のライセンスを追加
expiryDate.setDate(expiryDate.getDate() + 15);
- expiryDate.setHours(23, 59, 59, 999);
+ expiryDate.setHours(23, 59, 59, 0);
await createLicenseSetExpiryDateAndStatus(
source,
childAccountId3,
@@ -1975,7 +2024,7 @@ describe('getPartnerAccount', () => {
await createLicenseSetExpiryDateAndStatus(
source,
childAccountId1,
- new Date(2500, 1, 1, 23, 59, 59),
+ new Date(2037, 1, 1, 23, 59, 59),
element,
);
});
@@ -1985,7 +2034,7 @@ describe('getPartnerAccount', () => {
await createLicenseSetExpiryDateAndStatus(
source,
childAccountId2,
- new Date(2500, 1, 1, 23, 59, 59),
+ new Date(2037, 1, 1, 23, 59, 59),
'Unallocated',
);
}
@@ -2029,20 +2078,32 @@ describe('getPartnerAccount', () => {
describe('getOrderHistories', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -2161,20 +2222,32 @@ describe('getOrderHistories', () => {
describe('issueLicense', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -2468,20 +2541,32 @@ describe('issueLicense', () => {
describe('getDealers', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
it('Dealerを取得できる', async () => {
@@ -2551,20 +2636,32 @@ describe('getDealers', () => {
describe('createTypistGroup', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
it('TypistGroupを作成できる', async () => {
@@ -2851,20 +2948,32 @@ describe('createTypistGroup', () => {
describe('getTypistGroup', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
it('指定したIDのTypistGroupを取得できる', async () => {
@@ -3051,20 +3160,32 @@ describe('getTypistGroup', () => {
describe('updateTypistGroup', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
it('TypistGroupを更新できる', async () => {
@@ -3467,20 +3588,32 @@ describe('updateTypistGroup', () => {
describe('getWorktypes', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -3587,20 +3720,32 @@ describe('getWorktypes', () => {
describe('createWorktype', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -3740,20 +3885,32 @@ describe('createWorktype', () => {
describe('updateWorktype', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -4019,20 +4176,32 @@ describe('updateWorktype', () => {
describe('deleteWorktype', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -4267,20 +4436,32 @@ describe('deleteWorktype', () => {
describe('getOptionItems', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -4406,20 +4587,32 @@ describe('getOptionItems', () => {
describe('updateOptionItems', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -4732,20 +4925,32 @@ describe('updateOptionItems', () => {
describe('updateActiveWorktype', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -4960,20 +5165,32 @@ describe('updateActiveWorktype', () => {
describe('ライセンス発行キャンセル', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
it('ライセンス発行のキャンセルが完了する(第一階層で実行)', async () => {
@@ -5274,20 +5491,32 @@ describe('ライセンス発行キャンセル', () => {
describe('パートナー一覧取得', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
it('パートナー一覧を取得する', async () => {
@@ -5442,20 +5671,32 @@ describe('パートナー一覧取得', () => {
describe('アカウント情報更新', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
it('アカウント情報を更新する(第五階層が実行/セカンダリ管理者ユーザがnull)', async () => {
@@ -5660,20 +5901,32 @@ describe('アカウント情報更新', () => {
describe('getAccountInfo', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
it('パラメータのユーザに対応するアカウント情報を取得できる', async () => {
@@ -5720,20 +5973,32 @@ describe('getAccountInfo', () => {
});
describe('getAuthors', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
it('アカウント内のAuthorユーザーの一覧を取得できる', async () => {
@@ -5872,20 +6137,32 @@ describe('getAuthors', () => {
describe('getTypists', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
it('アカウント内のTypistユーザーの一覧を取得できる', async () => {
@@ -6054,20 +6331,32 @@ describe('getTypists', () => {
describe('deleteAccountAndData', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
it('アカウント情報が削除されること', async () => {
@@ -6450,20 +6739,32 @@ describe('deleteAccountAndData', () => {
});
describe('getAccountInfoMinimalAccess', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
it('IDトークンのsub情報からアカウントの階層情報を取得できること(第五階層)', async () => {
@@ -6583,20 +6884,32 @@ describe('getAccountInfoMinimalAccess', () => {
});
describe('getCompanyName', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
diff --git a/dictation_server/src/features/auth/auth.controller.spec.ts b/dictation_server/src/features/auth/auth.controller.spec.ts
index 93a7999..a762b74 100644
--- a/dictation_server/src/features/auth/auth.controller.spec.ts
+++ b/dictation_server/src/features/auth/auth.controller.spec.ts
@@ -14,7 +14,7 @@ describe('AuthController', () => {
const module: TestingModule = await Test.createTestingModule({
imports: [
ConfigModule.forRoot({
- envFilePath: ['.env.local', '.env'],
+ envFilePath: ['.env.test', '.env'],
isGlobal: true,
}),
],
diff --git a/dictation_server/src/features/auth/auth.service.spec.ts b/dictation_server/src/features/auth/auth.service.spec.ts
index 856f719..c0b47d4 100644
--- a/dictation_server/src/features/auth/auth.service.spec.ts
+++ b/dictation_server/src/features/auth/auth.service.spec.ts
@@ -20,6 +20,7 @@ import { v4 as uuidv4 } from 'uuid';
import { TIERS, USER_ROLES } from '../../constants';
import { decode, isVerifyError } from '../../common/jwt';
import { RefreshToken, AccessToken } from '../../common/token';
+import { truncateAllTable } from '../../common/test/init';
describe('AuthService', () => {
it('IDトークンの検証とペイロードの取得に成功する', async () => {
@@ -162,20 +163,32 @@ describe('AuthService', () => {
describe('checkIsAcceptedLatestVersion', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
it('同意済み利用規約バージョンが最新のときにチェックが通ること(第五)', async () => {
@@ -325,20 +338,32 @@ describe('checkIsAcceptedLatestVersion', () => {
describe('generateDelegationRefreshToken', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
it('代行操作が許可されたパートナーの代行操作用リフレッシュトークンを取得できること', async () => {
@@ -459,20 +484,32 @@ describe('generateDelegationRefreshToken', () => {
describe('generateDelegationAccessToken', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
it('代行操作用リフレッシュトークンから代行操作用アクセストークンを取得できること', async () => {
@@ -558,20 +595,32 @@ describe('generateDelegationAccessToken', () => {
describe('updateDelegationAccessToken', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -743,7 +792,7 @@ describe('updateDelegationAccessToken', () => {
}
// 代行操作対象アカウントを削除
- deleteAccount(source, partnerAccount.id);
+ await deleteAccount(source, partnerAccount.id);
try {
await service.updateDelegationAccessToken(
diff --git a/dictation_server/src/features/files/files.controller.spec.ts b/dictation_server/src/features/files/files.controller.spec.ts
index 9b7eb76..3986b38 100644
--- a/dictation_server/src/features/files/files.controller.spec.ts
+++ b/dictation_server/src/features/files/files.controller.spec.ts
@@ -10,7 +10,7 @@ describe('FilesController', () => {
const module: TestingModule = await Test.createTestingModule({
imports: [
ConfigModule.forRoot({
- envFilePath: ['.env.local', '.env'],
+ envFilePath: ['.env.test', '.env'],
isGlobal: true,
}),
],
diff --git a/dictation_server/src/features/files/files.service.spec.ts b/dictation_server/src/features/files/files.service.spec.ts
index 89c9f68..62e4286 100644
--- a/dictation_server/src/features/files/files.service.spec.ts
+++ b/dictation_server/src/features/files/files.service.spec.ts
@@ -40,23 +40,36 @@ import {
TASK_STATUS,
USER_ROLES,
} from '../../constants';
+import { truncateAllTable } from '../../common/test/init';
describe('publishUploadSas', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -287,20 +300,32 @@ describe('publishUploadSas', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
it('タスク作成時に、自動ルーティングを行うことができる(APIの引数として渡されたAuthorIDとworkType)', async () => {
@@ -997,20 +1022,32 @@ describe('タスク作成から自動ルーティング(DB使用)', () => {
describe('音声ファイルダウンロードURL取得', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -1490,20 +1527,32 @@ describe('音声ファイルダウンロードURL取得', () => {
describe('テンプレートファイルダウンロードURL取得', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -1933,20 +1982,32 @@ describe('テンプレートファイルダウンロードURL取得', () => {
describe('publishTemplateFileUploadSas', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -2036,20 +2097,32 @@ describe('publishTemplateFileUploadSas', () => {
describe('templateUploadFinished', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
diff --git a/dictation_server/src/features/files/test/utility.ts b/dictation_server/src/features/files/test/utility.ts
index 12bb21c..1fe086b 100644
--- a/dictation_server/src/features/files/test/utility.ts
+++ b/dictation_server/src/features/files/test/utility.ts
@@ -152,7 +152,7 @@ export const makeTestingModuleWithBlobAndNotification = async (
const module: TestingModule = await Test.createTestingModule({
imports: [
ConfigModule.forRoot({
- envFilePath: ['.env.local', '.env'],
+ envFilePath: ['.env.test', '.env'],
isGlobal: true,
}),
AuthModule,
diff --git a/dictation_server/src/features/licenses/licenses.controller.spec.ts b/dictation_server/src/features/licenses/licenses.controller.spec.ts
index 70daf6c..1b3fdc4 100644
--- a/dictation_server/src/features/licenses/licenses.controller.spec.ts
+++ b/dictation_server/src/features/licenses/licenses.controller.spec.ts
@@ -11,7 +11,7 @@ describe('LicensesController', () => {
const module: TestingModule = await Test.createTestingModule({
imports: [
ConfigModule.forRoot({
- envFilePath: ['.env.local', '.env'],
+ envFilePath: ['.env.test', '.env'],
isGlobal: true,
}),
],
diff --git a/dictation_server/src/features/licenses/licenses.service.spec.ts b/dictation_server/src/features/licenses/licenses.service.spec.ts
index 1a5b023..63db663 100644
--- a/dictation_server/src/features/licenses/licenses.service.spec.ts
+++ b/dictation_server/src/features/licenses/licenses.service.spec.ts
@@ -26,23 +26,36 @@ import {
} from '../../common/test/utility';
import { LicensesRepositoryService } from '../../repositories/licenses/licenses.repository.service';
import { overrideSendgridService } from '../../common/test/overrides';
+import { truncateAllTable } from '../../common/test/init';
describe('ライセンス注文', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -190,20 +203,32 @@ describe('ライセンス注文', () => {
describe('カードライセンス発行', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -268,20 +293,32 @@ describe('カードライセンス発行', () => {
describe('カードライセンスを取り込む', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
it('カードライセンス取り込みが完了する', async () => {
@@ -601,20 +638,32 @@ describe('カードライセンスを取り込む', () => {
describe('ライセンス割り当て', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -702,6 +751,7 @@ describe('ライセンス割り当て', () => {
});
const date = new Date();
date.setDate(date.getDate() + 30);
+ date.setMilliseconds(0);
await createLicense(
source,
1,
@@ -768,6 +818,8 @@ describe('ライセンス割り当て', () => {
});
const date = new Date();
date.setDate(date.getDate() + 30);
+ date.setMilliseconds(0);
+
await createLicense(
source,
1,
@@ -874,6 +926,7 @@ describe('ライセンス割り当て', () => {
});
const date = new Date();
date.setDate(date.getDate() + 30);
+ date.setMilliseconds(0);
await createLicense(
source,
1,
@@ -939,6 +992,7 @@ describe('ライセンス割り当て', () => {
});
const date = new Date();
date.setDate(date.getDate() + 30);
+ date.setMilliseconds(0);
await createLicense(
source,
1,
@@ -1004,6 +1058,7 @@ describe('ライセンス割り当て', () => {
});
const date = new Date();
date.setDate(date.getDate() + 30);
+ date.setMilliseconds(0);
await createLicense(
source,
1,
@@ -1069,6 +1124,7 @@ describe('ライセンス割り当て', () => {
});
const date = new Date();
date.setDate(date.getDate() - 30);
+ date.setMilliseconds(0);
await createLicense(
source,
1,
@@ -1110,6 +1166,7 @@ describe('ライセンス割り当て', () => {
});
const date = new Date();
date.setDate(date.getDate() + 30);
+ date.setMilliseconds(0);
await createLicense(
source,
1,
@@ -1161,20 +1218,32 @@ describe('ライセンス割り当て', () => {
describe('ライセンス割り当て解除', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -1192,6 +1261,7 @@ describe('ライセンス割り当て解除', () => {
});
const date = new Date();
date.setDate(date.getDate() + 30);
+ date.setMilliseconds(0);
await createLicense(
source,
1,
@@ -1271,6 +1341,7 @@ describe('ライセンス割り当て解除', () => {
});
const date = new Date();
date.setDate(date.getDate() + 30);
+ date.setMilliseconds(0);
await createLicense(
source,
1,
@@ -1316,20 +1387,32 @@ describe('ライセンス割り当て解除', () => {
describe('ライセンス注文キャンセル', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
diff --git a/dictation_server/src/features/licenses/test/utility.ts b/dictation_server/src/features/licenses/test/utility.ts
index 321f9c0..3dfdda3 100644
--- a/dictation_server/src/features/licenses/test/utility.ts
+++ b/dictation_server/src/features/licenses/test/utility.ts
@@ -172,6 +172,7 @@ export const selectLicenseAllocationHistory = async (
license_id: licence_id,
},
order: {
+ id: 'DESC',
executed_at: 'DESC',
},
});
diff --git a/dictation_server/src/features/notification/notification.controller.spec.ts b/dictation_server/src/features/notification/notification.controller.spec.ts
index fc14685..bbf71a7 100644
--- a/dictation_server/src/features/notification/notification.controller.spec.ts
+++ b/dictation_server/src/features/notification/notification.controller.spec.ts
@@ -10,7 +10,7 @@ describe('NotificationController', () => {
const module: TestingModule = await Test.createTestingModule({
imports: [
ConfigModule.forRoot({
- envFilePath: ['.env.local', '.env'],
+ envFilePath: ['.env.test', '.env'],
isGlobal: true,
}),
],
diff --git a/dictation_server/src/features/notification/test/notification.service.mock.ts b/dictation_server/src/features/notification/test/notification.service.mock.ts
index b11c985..1984c27 100644
--- a/dictation_server/src/features/notification/test/notification.service.mock.ts
+++ b/dictation_server/src/features/notification/test/notification.service.mock.ts
@@ -21,7 +21,7 @@ export const makeNotificationServiceMock = async (
providers: [NotificationService],
imports: [
ConfigModule.forRoot({
- envFilePath: ['.env.local', '.env'],
+ envFilePath: ['.env.test', '.env'],
}),
],
})
diff --git a/dictation_server/src/features/tasks/tasks.controller.spec.ts b/dictation_server/src/features/tasks/tasks.controller.spec.ts
index 01e7e75..72b8ac5 100644
--- a/dictation_server/src/features/tasks/tasks.controller.spec.ts
+++ b/dictation_server/src/features/tasks/tasks.controller.spec.ts
@@ -10,7 +10,7 @@ describe('TasksController', () => {
const module: TestingModule = await Test.createTestingModule({
imports: [
ConfigModule.forRoot({
- envFilePath: ['.env.local', '.env'],
+ envFilePath: ['.env.test', '.env'],
isGlobal: true,
}),
],
diff --git a/dictation_server/src/features/tasks/tasks.service.spec.ts b/dictation_server/src/features/tasks/tasks.service.spec.ts
index eaf6e56..02d361c 100644
--- a/dictation_server/src/features/tasks/tasks.service.spec.ts
+++ b/dictation_server/src/features/tasks/tasks.service.spec.ts
@@ -37,6 +37,7 @@ 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 { truncateAllTable } from '../../common/test/init';
describe('TasksService', () => {
it('タスク一覧を取得できる(admin)', async () => {
@@ -584,22 +585,34 @@ describe('TasksService', () => {
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();
- });
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
+ });
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
- source = null;
- });
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
+ source = null;
+ });
it('[Admin] Taskが0件であっても実行できる', async () => {
const notificationhubServiceMockValue =
@@ -775,20 +788,32 @@ describe('TasksService', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -1405,20 +1430,32 @@ describe('changeCheckoutPermission', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -1605,7 +1642,6 @@ describe('checkout', () => {
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,
@@ -1652,7 +1688,6 @@ describe('checkout', () => {
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,
@@ -1989,20 +2024,32 @@ describe('checkout', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -2192,20 +2239,32 @@ describe('checkin', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -2391,20 +2450,32 @@ describe('suspend', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -3007,20 +3078,32 @@ describe('cancel', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -3301,20 +3384,32 @@ describe('backup', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
diff --git a/dictation_server/src/features/tasks/test/utility.ts b/dictation_server/src/features/tasks/test/utility.ts
index b4de930..171f061 100644
--- a/dictation_server/src/features/tasks/test/utility.ts
+++ b/dictation_server/src/features/tasks/test/utility.ts
@@ -47,7 +47,7 @@ export const makeTaskTestingModuleWithNotificaiton = async (
const module: TestingModule = await Test.createTestingModule({
imports: [
ConfigModule.forRoot({
- envFilePath: ['.env.local', '.env'],
+ envFilePath: ['.env.test', '.env'],
isGlobal: true,
}),
AuthModule,
diff --git a/dictation_server/src/features/templates/templates.controller.spec.ts b/dictation_server/src/features/templates/templates.controller.spec.ts
index 00bd2fc..20ffb00 100644
--- a/dictation_server/src/features/templates/templates.controller.spec.ts
+++ b/dictation_server/src/features/templates/templates.controller.spec.ts
@@ -10,7 +10,7 @@ describe('TemplatesController', () => {
const module: TestingModule = await Test.createTestingModule({
imports: [
ConfigModule.forRoot({
- envFilePath: ['.env.local', '.env'],
+ envFilePath: ['.env.test', '.env'],
isGlobal: true,
}),
],
diff --git a/dictation_server/src/features/templates/templates.service.spec.ts b/dictation_server/src/features/templates/templates.service.spec.ts
index a366b30..8ef101f 100644
--- a/dictation_server/src/features/templates/templates.service.spec.ts
+++ b/dictation_server/src/features/templates/templates.service.spec.ts
@@ -7,24 +7,37 @@ import { makeContext } from '../../common/log';
import { TemplateFilesRepositoryService } from '../../repositories/template_files/template_files.repository.service';
import { HttpException, HttpStatus } from '@nestjs/common';
import { makeErrorResponse } from '../../common/error/makeErrorResponse';
+import { truncateAllTable } from '../../common/test/init';
describe('getTemplates', () => {
- let source: DataSource | undefined = undefined;
- beforeEach(async () => {
- source = new DataSource({
- type: 'sqlite',
- database: ':memory:',
- logging: false,
- entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
- synchronize: true, // trueにすると自動的にmigrationが行われるため注意
- });
- return source.initialize();
+ let source: DataSource | null = null;
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
- source = undefined;
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
+ source = null;
});
it('テンプレートファイル一覧を取得できる', async () => {
diff --git a/dictation_server/src/features/terms/terms.service.spec.ts b/dictation_server/src/features/terms/terms.service.spec.ts
index 5950404..4a6ac7e 100644
--- a/dictation_server/src/features/terms/terms.service.spec.ts
+++ b/dictation_server/src/features/terms/terms.service.spec.ts
@@ -6,23 +6,36 @@ import { makeContext } from '../../common/log';
import { v4 as uuidv4 } from 'uuid';
import { HttpException, HttpStatus } from '@nestjs/common';
import { makeErrorResponse } from '../../common/error/makeErrorResponse';
+import { truncateAllTable } from '../../common/test/init';
describe('利用規約取得', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
diff --git a/dictation_server/src/features/users/test/users.service.mock.ts b/dictation_server/src/features/users/test/users.service.mock.ts
index 0984d0f..c2da3db 100644
--- a/dictation_server/src/features/users/test/users.service.mock.ts
+++ b/dictation_server/src/features/users/test/users.service.mock.ts
@@ -67,7 +67,7 @@ export const makeUsersServiceMock = async (
providers: [UsersService],
imports: [
ConfigModule.forRoot({
- envFilePath: ['.env.local', '.env'],
+ envFilePath: ['.env.test', '.env'],
}),
],
})
diff --git a/dictation_server/src/features/users/test/utility.ts b/dictation_server/src/features/users/test/utility.ts
index 58a7512..849aa34 100644
--- a/dictation_server/src/features/users/test/utility.ts
+++ b/dictation_server/src/features/users/test/utility.ts
@@ -113,7 +113,7 @@ export const makeTestingModuleWithAdb2c = async (
const module: TestingModule = await Test.createTestingModule({
imports: [
ConfigModule.forRoot({
- envFilePath: ['.env.local', '.env'],
+ envFilePath: ['.env.test', '.env'],
isGlobal: true,
}),
AuthModule,
diff --git a/dictation_server/src/features/users/users.controller.spec.ts b/dictation_server/src/features/users/users.controller.spec.ts
index b64a9fc..d060ac2 100644
--- a/dictation_server/src/features/users/users.controller.spec.ts
+++ b/dictation_server/src/features/users/users.controller.spec.ts
@@ -13,7 +13,7 @@ describe('UsersController', () => {
const module: TestingModule = await Test.createTestingModule({
imports: [
ConfigModule.forRoot({
- envFilePath: ['.env.local', '.env'],
+ envFilePath: ['.env.test', '.env'],
isGlobal: true,
}),
],
diff --git a/dictation_server/src/features/users/users.service.spec.ts b/dictation_server/src/features/users/users.service.spec.ts
index a02016e..dc3b656 100644
--- a/dictation_server/src/features/users/users.service.spec.ts
+++ b/dictation_server/src/features/users/users.service.spec.ts
@@ -46,21 +46,36 @@ import {
import { v4 as uuidv4 } from 'uuid';
import { createOptionItems, createWorktype } from '../accounts/test/utility';
import { createWorkflow, getWorkflows } from '../workflows/test/utility';
+import { truncateAllTable } from '../../common/test/init';
describe('UsersService.confirmUser', () => {
let source: DataSource | null = null;
- beforeEach(async () => {
- source = new DataSource({
- type: 'sqlite',
- database: ':memory:',
- entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
- synchronize: true, // trueにすると自動的にmigrationが行われるため注意
- });
- return source.initialize();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -419,20 +434,32 @@ describe('UsersService.confirmUserAndInitPassword', () => {
describe('UsersService.createUser', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -1364,20 +1391,32 @@ describe('UsersService.createUser', () => {
describe('UsersService.getUsers', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -1841,20 +1880,32 @@ describe('UsersService.getSortCriteria', () => {
describe('UsersService.updateUser', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -2425,20 +2476,32 @@ describe('UsersService.updateUser', () => {
describe('UsersService.updateAcceptedVersion', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -2513,20 +2576,32 @@ describe('UsersService.updateAcceptedVersion', () => {
describe('UsersService.getUserName', () => {
let source: DataSource | null = null;
- beforeEach(async () => {
- source = new DataSource({
- type: 'sqlite',
- database: ':memory:',
- logging: false,
- entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
- synchronize: true,
- });
- return source.initialize();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -2555,20 +2630,32 @@ describe('UsersService.getUserName', () => {
describe('UsersService.getRelations', () => {
let source: DataSource | null = null;
- beforeEach(async () => {
- source = new DataSource({
- type: 'sqlite',
- database: ':memory:',
- logging: false,
- entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
- synchronize: true,
- });
- return source.initialize();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -2620,6 +2707,8 @@ describe('UsersService.getRelations', () => {
// 作成したデータを確認
{
const workflows = await getWorkflows(source, account.id);
+ workflows.sort((a, b) => a.id - b.id);
+
expect(workflows.length).toBe(4);
expect(workflows[0].worktype_id).toBe(worktype1.id);
expect(workflows[0].author_id).toBe(user1);
diff --git a/dictation_server/src/features/workflows/workflows.controller.spec.ts b/dictation_server/src/features/workflows/workflows.controller.spec.ts
index afab754..3b12b75 100644
--- a/dictation_server/src/features/workflows/workflows.controller.spec.ts
+++ b/dictation_server/src/features/workflows/workflows.controller.spec.ts
@@ -10,7 +10,7 @@ describe('WorkflowsController', () => {
const module: TestingModule = await Test.createTestingModule({
imports: [
ConfigModule.forRoot({
- envFilePath: ['.env.local', '.env'],
+ envFilePath: ['.env.test', '.env'],
isGlobal: true,
}),
],
diff --git a/dictation_server/src/features/workflows/workflows.service.spec.ts b/dictation_server/src/features/workflows/workflows.service.spec.ts
index 7b0e3cc..d04e4c5 100644
--- a/dictation_server/src/features/workflows/workflows.service.spec.ts
+++ b/dictation_server/src/features/workflows/workflows.service.spec.ts
@@ -19,23 +19,36 @@ import { overrideAdB2cService } from '../../common/test/overrides';
import { WorkflowsRepositoryService } from '../../repositories/workflows/workflows.repository.service';
import { HttpException, HttpStatus } from '@nestjs/common';
import { makeErrorResponse } from '../../common/error/makeErrorResponse';
+import { truncateAllTable } from '../../common/test/init';
describe('getWorkflows', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await(async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -267,22 +280,34 @@ describe('getWorkflows', () => {
describe('createWorkflows', () => {
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;
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
+ source = null;
+ });
it('アカウント内にWorkflowを作成できる(WorktypeIDあり、テンプレートファイルあり)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
@@ -606,6 +631,7 @@ describe('createWorkflows', () => {
//実行結果を確認
{
const workflows = await getWorkflows(source, account.id);
+ workflows.sort((a, b) => a.id - b.id);
expect(workflows.length).toBe(2);
expect(workflows[1].account_id).toBe(account.id);
expect(workflows[1].author_id).toBe(authorId);
@@ -1193,19 +1219,32 @@ describe('createWorkflows', () => {
describe('updateWorkflow', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
@@ -1623,6 +1662,7 @@ describe('updateWorkflow', () => {
//作成したデータを確認
{
const workflows = await getWorkflows(source, account.id);
+ workflows.sort((a, b) => a.id - b.id);
const workflowTypists = await getAllWorkflowTypists(source);
expect(workflows.length).toBe(2);
expect(workflows[0].id).toBe(preWorkflow1.id);
@@ -1658,6 +1698,7 @@ describe('updateWorkflow', () => {
//実行結果を確認
{
const workflows = await getWorkflows(source, account.id);
+ workflows.sort((a, b) => a.id - b.id);
expect(workflows.length).toBe(2);
expect(workflows[1].account_id).toBe(account.id);
expect(workflows[1].author_id).toBe(authorId2);
@@ -2380,19 +2421,32 @@ describe('updateWorkflow', () => {
describe('deleteWorkflows', () => {
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();
+ beforeAll(async () => {
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
});
- afterEach(async () => {
- if (!source) return;
- await source.destroy();
+
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
+
+ afterAll(async () => {
+ await source?.destroy();
source = null;
});
From a59cb0fffbdb76e83277fecadf323c756166668a Mon Sep 17 00:00:00 2001
From: "saito.k"
Date: Tue, 23 Jan 2024 11:02:50 +0000
Subject: [PATCH 17/17] =?UTF-8?q?Merged=20PR=20700:=20[=E3=83=86=E3=82=B9?=
=?UTF-8?q?=E3=83=88FB=E5=AF=BE=E5=BF=9C]User=E7=94=BB=E9=9D=A2=E3=81=A7?=
=?UTF-8?q?=E3=83=A9=E3=82=A4=E3=82=BB=E3=83=B3=E3=82=B9=E3=81=AEStatus?=
=?UTF-8?q?=E3=81=AE=E8=A1=A8=E7=A4=BA=E3=82=92=E5=A4=89=E6=9B=B4=E3=81=97?=
=?UTF-8?q?=E3=81=9F=E3=81=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## 概要
[Task3506: テスト対応](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3506)
- ライセンスが割り当たっている状態の表示をLicense Assignedにする
- ライセンスの期限切れ状態の表示をNo Licenseとする
- ヘッダーのOMDSCloudの表記を削除
## レビューポイント
- 修正内容に不足はないか
- 修正の認識ずれはないか
- ほかに修正が影響している箇所はないか
## UIの変更
- https://ndstokyo.sharepoint.com/:f:/r/sites/Piranha/Shared%20Documents/General/OMDS/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88/Task3506?csf=1&web=1&e=g2Hkr3
## 動作確認状況
- ローカルで確認
## 補足
- 相談、参考資料などがあれば
---
.../src/components/header/constants.ts | 2 -
.../src/components/header/loginedHeader.tsx | 2 -
.../src/components/header/notLoginHeader.tsx | 2 -
.../src/features/user/constants.ts | 6 +
.../src/features/user/selectors.ts | 60 ++++-
dictation_client/src/features/user/types.ts | 15 +-
.../src/features/user/userSlice.ts | 4 +-
.../src/pages/UserListPage/index.tsx | 251 ++++++++----------
dictation_server/src/common/test/init.ts | 4 +-
.../src/features/auth/auth.service.spec.ts | 6 +-
.../src/features/files/files.service.spec.ts | 12 +-
.../licenses/licenses.service.spec.ts | 12 +-
.../src/features/tasks/tasks.service.spec.ts | 64 ++---
.../src/features/terms/terms.service.spec.ts | 2 +-
.../src/features/users/users.service.spec.ts | 14 +-
.../workflows/workflows.service.spec.ts | 2 +-
16 files changed, 245 insertions(+), 213 deletions(-)
diff --git a/dictation_client/src/components/header/constants.ts b/dictation_client/src/components/header/constants.ts
index 6b3f7dc..0e2219c 100644
--- a/dictation_client/src/components/header/constants.ts
+++ b/dictation_client/src/components/header/constants.ts
@@ -51,8 +51,6 @@ export const HEADER_MENUS: {
},
];
-export const HEADER_NAME = "ODMS Cloud";
-
/**
* adminのみに表示するヘッダータブ
*/
diff --git a/dictation_client/src/components/header/loginedHeader.tsx b/dictation_client/src/components/header/loginedHeader.tsx
index 7b900ab..d6e48ac 100644
--- a/dictation_client/src/components/header/loginedHeader.tsx
+++ b/dictation_client/src/components/header/loginedHeader.tsx
@@ -17,7 +17,6 @@ import { getFilteredMenus } from "./utils";
import logo from "../../assets/images/OMS_logo_black.svg";
import ac from "../../assets/images/account_circle.svg";
import { LoginedPaths } from "./types";
-import { HEADER_NAME } from "./constants";
import logout from "../../assets/images/logout.svg";
import { getTranslationID } from "../../translation";
@@ -74,7 +73,6 @@ const LoginedHeader: React.FC = (props: HeaderProps) => {
- {HEADER_NAME}
{filterMenus.map((x) => (
diff --git a/dictation_client/src/components/header/notLoginHeader.tsx b/dictation_client/src/components/header/notLoginHeader.tsx
index 67c71cc..d1e15f9 100644
--- a/dictation_client/src/components/header/notLoginHeader.tsx
+++ b/dictation_client/src/components/header/notLoginHeader.tsx
@@ -1,7 +1,6 @@
import React from "react";
import styles from "styles/app.module.scss";
import logo from "../../assets/images/OMS_logo_black.svg";
-import { HEADER_NAME } from "./constants";
interface NotLoginHeaderProps {
isMobile?: boolean;
@@ -16,7 +15,6 @@ const NotLoginHeader: React.FC = (
- {HEADER_NAME}
);
};
diff --git a/dictation_client/src/features/user/constants.ts b/dictation_client/src/features/user/constants.ts
index 27bb5dd..1acd5da 100644
--- a/dictation_client/src/features/user/constants.ts
+++ b/dictation_client/src/features/user/constants.ts
@@ -11,3 +11,9 @@ export const LICENSE_ALLOCATE_STATUS = {
ALLOCATED: "Allocated",
NOTALLOCATED: "Not Allocated",
} as const;
+
+// NoLicenseの表示
+export const NO_LICENSE = "No License" as const;
+
+// ライセンスが割り当てられている場合の表示
+export const LICENSE_NORMAL = "License Assigned" as const;
diff --git a/dictation_client/src/features/user/selectors.ts b/dictation_client/src/features/user/selectors.ts
index ee1f3fa..b7c7c60 100644
--- a/dictation_client/src/features/user/selectors.ts
+++ b/dictation_client/src/features/user/selectors.ts
@@ -3,6 +3,7 @@ import { USER_ROLES } from "components/auth/constants";
import { convertLocalToUTCDate } from "common/convertLocalToUTCDate";
import {
AddUser,
+ LicenseStatusType,
RoleType,
UserView,
isLicenseStatusType,
@@ -163,6 +164,12 @@ export const selectUserViews = (state: RootState): UserView[] => {
prompt,
typistGroupName
);
+ // licenseStatus,remaining,expirationの値を変換する
+ const {
+ licenseStatus: convertedLicenseStatus,
+ expiration: convertedExpiration,
+ remaining: convertedRemaining,
+ } = convertValueBasedOnLicenseStatus(licenseStatus, expiration, remaining);
// restのid以外をUserViewに追加する
return {
typistGroupName: convertedValues.typistGroupName,
@@ -171,10 +178,9 @@ export const selectUserViews = (state: RootState): UserView[] => {
authorId: convertedValues.authorId,
// roleの一文字目を大文字に変換する
role: role.charAt(0).toUpperCase() + role.slice(1),
- licenseStatus:
- licenseStatus === LICENSE_STATUS.NORMAL ? "-" : licenseStatus,
- expiration: expiration ?? "-",
- remaining: remaining ?? "-",
+ licenseStatus: convertedLicenseStatus,
+ expiration: convertedExpiration,
+ remaining: convertedRemaining,
...rest,
};
});
@@ -254,7 +260,7 @@ export const selectLicenseAllocateUserExpirationDate = (state: RootState) => {
return "-";
}
- return `${expiration}(${remaining})`;
+ return `${expiration ?? "-"}(${remaining ?? "-"})`;
};
export const selectSelectedlicenseId = (state: RootState) =>
@@ -328,3 +334,47 @@ const calculateExpiryDate = (expiryDate: string) => {
return `${formattedExpirationDate} (${daysDifference})`;
};
+
+// licenseStatus,remainingに応じて値を変換する
+const convertValueBasedOnLicenseStatus = (
+ licenseStatus: LicenseStatusType,
+ expiration?: string,
+ remaining?: number
+): {
+ licenseStatus: LicenseStatusType;
+ expiration?: string;
+ remaining?: number;
+} => {
+ if (licenseStatus === LICENSE_STATUS.NOLICENSE) {
+ return {
+ licenseStatus,
+ expiration: undefined,
+ remaining: undefined,
+ };
+ }
+ // remainingが存在し、かつ負の値である場合は、NoLicenseとする
+ if (remaining && remaining < 0) {
+ return {
+ licenseStatus: LICENSE_STATUS.NOLICENSE,
+ expiration: undefined,
+ remaining: undefined,
+ };
+ }
+ if (
+ licenseStatus === LICENSE_STATUS.RENEW ||
+ licenseStatus === LICENSE_STATUS.NORMAL ||
+ licenseStatus === LICENSE_STATUS.ALERT
+ ) {
+ return {
+ licenseStatus,
+ expiration,
+ remaining,
+ };
+ }
+ // ここに到達することはない
+ return {
+ licenseStatus,
+ expiration: undefined,
+ remaining: undefined,
+ };
+};
diff --git a/dictation_client/src/features/user/types.ts b/dictation_client/src/features/user/types.ts
index 649b63f..a96e236 100644
--- a/dictation_client/src/features/user/types.ts
+++ b/dictation_client/src/features/user/types.ts
@@ -4,14 +4,11 @@ import { LICENSE_STATUS } from "./constants";
// 画面表示用のUserの型を独自に定義
export interface UserView
- extends Omit<
- User,
- "typistGroupName" | "prompt" | "encryption" | "remaining"
- > {
+ extends Omit {
authorId: string;
typistGroupName: string[] | string;
role: string;
- licenseStatus: LicenseStatusType | string;
+ licenseStatus: LicenseStatusType;
prompt: boolean | string;
encryption: boolean | string;
emailVerified: boolean;
@@ -19,8 +16,8 @@ export interface UserView
notification: boolean;
name: string;
email: string;
- expiration: string;
- remaining: number | string;
+ expiration?: string;
+ remaining?: number;
}
export interface AddUser {
name: string;
@@ -53,8 +50,8 @@ export interface LicenseAllocateUser {
email: string;
authorId: string;
licenseStatus: LicenseStatusType | string;
- expiration: string;
- remaining: number | string;
+ expiration?: string;
+ remaining?: number;
}
export type RoleType = typeof USER_ROLES[keyof typeof USER_ROLES];
diff --git a/dictation_client/src/features/user/userSlice.ts b/dictation_client/src/features/user/userSlice.ts
index ef0589a..881dba9 100644
--- a/dictation_client/src/features/user/userSlice.ts
+++ b/dictation_client/src/features/user/userSlice.ts
@@ -54,8 +54,8 @@ const initialState: UsersState = {
email: "",
authorId: "",
licenseStatus: "",
- expiration: "",
- remaining: "",
+ expiration: undefined,
+ remaining: undefined,
},
selectedlicenseId: 0,
hasPasswordMask: false,
diff --git a/dictation_client/src/pages/UserListPage/index.tsx b/dictation_client/src/pages/UserListPage/index.tsx
index 48e0805..b6b0072 100644
--- a/dictation_client/src/pages/UserListPage/index.tsx
+++ b/dictation_client/src/pages/UserListPage/index.tsx
@@ -13,8 +13,12 @@ import {
} from "features/user";
import { useTranslation } from "react-i18next";
import { getTranslationID } from "translation";
-import { isLicenseStatusType, UserView } from "features/user/types";
-import { LICENSE_STATUS } from "features/user/constants";
+import { LicenseStatusType, UserView } from "features/user/types";
+import {
+ LICENSE_NORMAL,
+ LICENSE_STATUS,
+ NO_LICENSE,
+} from "features/user/constants";
import { isApproveTier } from "features/auth";
import { TIERS } from "components/auth/constants";
import {
@@ -184,66 +188,63 @@ const UserListPage: React.FC = (): JSX.Element => {
{!isLoading &&
- users.map((user) => {
- const { isAlertLicenseStatus, isAlertRemaining } =
- isAlertElement(user.licenseStatus);
- return (
-
-
-
+
+ {user.name}
+ {user.role}
+ {user.authorId}
+ {boolToElement(user.encryption)}
+ {boolToElement(user.prompt)}
+ {arrayToElement(user.typistGroupName)}
+ {user.email}
+
+
+ {getLicenseStatus(user.licenseStatus)}
+
+
+
+
+ {user.expiration ?? "-"}
+
+
+
+
+ {user.remaining ?? "-"}
+
+
+ {boolToElement(user.autoRenew)}
+ {boolToElement(user.notification)}
+ {boolToElement(user.emailVerified)}
+
+ ))}
{!isLoading && users.length === 0 && (
@@ -352,38 +360,15 @@ const arrayToElement = (
));
};
-const isAlertElement = (
- licenseStatus: string
-): {
- isAlertLicenseStatus: boolean;
- isAlertRemaining: boolean;
-} => {
- // licenseStatusの型がLicenseStatusTypeでない場合(Normal)、どちらもfalseにする
- if (isLicenseStatusType(licenseStatus) === false) {
- return {
- isAlertLicenseStatus: false,
- isAlertRemaining: false,
- };
- }
- // licenseStatusがNOLICENSEの場合、isAlertLicenseStatusをtrueにする(Remainingはハイフン)
+// ライセンスステータスに応じて、ライセンスステータスの文字列を返す
+const getLicenseStatus = (licenseStatus: LicenseStatusType): string => {
if (licenseStatus === LICENSE_STATUS.NOLICENSE) {
- return {
- isAlertLicenseStatus: true,
- isAlertRemaining: false,
- };
+ return NO_LICENSE;
}
- // licenseStatusがALERTの場合、どちらもtrueにする
- if (licenseStatus === LICENSE_STATUS.ALERT) {
- return {
- isAlertLicenseStatus: true,
- isAlertRemaining: true,
- };
+ if (licenseStatus === LICENSE_STATUS.NORMAL) {
+ return LICENSE_NORMAL;
}
- // licenseStatusがRENEWの場合、どちらもfalseにする
- return {
- isAlertLicenseStatus: false,
- isAlertRemaining: false,
- };
+ return licenseStatus;
};
export default UserListPage;
diff --git a/dictation_server/src/common/test/init.ts b/dictation_server/src/common/test/init.ts
index e919d16..bfe1512 100644
--- a/dictation_server/src/common/test/init.ts
+++ b/dictation_server/src/common/test/init.ts
@@ -1,4 +1,4 @@
-import { DataSource } from "typeorm";
+import { DataSource } from 'typeorm';
export const truncateAllTable = async (source: DataSource) => {
const entities = source.entityMetadatas;
@@ -18,4 +18,4 @@ export const truncateAllTable = async (source: DataSource) => {
} finally {
await queryRunner.release();
}
-};
\ No newline at end of file
+};
diff --git a/dictation_server/src/features/auth/auth.service.spec.ts b/dictation_server/src/features/auth/auth.service.spec.ts
index c0b47d4..85473b3 100644
--- a/dictation_server/src/features/auth/auth.service.spec.ts
+++ b/dictation_server/src/features/auth/auth.service.spec.ts
@@ -340,7 +340,7 @@ describe('generateDelegationRefreshToken', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -486,7 +486,7 @@ describe('generateDelegationAccessToken', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -597,7 +597,7 @@ describe('updateDelegationAccessToken', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
diff --git a/dictation_server/src/features/files/files.service.spec.ts b/dictation_server/src/features/files/files.service.spec.ts
index 62e4286..17d1253 100644
--- a/dictation_server/src/features/files/files.service.spec.ts
+++ b/dictation_server/src/features/files/files.service.spec.ts
@@ -46,7 +46,7 @@ describe('publishUploadSas', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -302,7 +302,7 @@ describe('タスク作成から自動ルーティング(DB使用)', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -1024,7 +1024,7 @@ describe('音声ファイルダウンロードURL取得', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -1529,7 +1529,7 @@ describe('テンプレートファイルダウンロードURL取得', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -1984,7 +1984,7 @@ describe('publishTemplateFileUploadSas', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -2099,7 +2099,7 @@ describe('templateUploadFinished', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
diff --git a/dictation_server/src/features/licenses/licenses.service.spec.ts b/dictation_server/src/features/licenses/licenses.service.spec.ts
index 63db663..c3473ab 100644
--- a/dictation_server/src/features/licenses/licenses.service.spec.ts
+++ b/dictation_server/src/features/licenses/licenses.service.spec.ts
@@ -32,7 +32,7 @@ describe('ライセンス注文', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -205,7 +205,7 @@ describe('カードライセンス発行', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -295,7 +295,7 @@ describe('カードライセンスを取り込む', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -640,7 +640,7 @@ describe('ライセンス割り当て', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -1220,7 +1220,7 @@ describe('ライセンス割り当て解除', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -1389,7 +1389,7 @@ describe('ライセンス注文キャンセル', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
diff --git a/dictation_server/src/features/tasks/tasks.service.spec.ts b/dictation_server/src/features/tasks/tasks.service.spec.ts
index 02d361c..712f498 100644
--- a/dictation_server/src/features/tasks/tasks.service.spec.ts
+++ b/dictation_server/src/features/tasks/tasks.service.spec.ts
@@ -586,33 +586,33 @@ describe('TasksService', () => {
describe('DBテスト', () => {
let source: DataSource | null = null;
beforeAll(async () => {
- if (source == null) {
- source = await(async () => {
- const s = new DataSource({
- type: 'mysql',
- host: 'test_mysql_db',
- port: 3306,
- username: 'user',
- password: 'password',
- database: 'odms',
- entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
- synchronize: false, // trueにすると自動的にmigrationが行われるため注意
- });
- return await s.initialize();
- })();
- }
- });
+ if (source == null) {
+ source = await (async () => {
+ const s = new DataSource({
+ type: 'mysql',
+ host: 'test_mysql_db',
+ port: 3306,
+ username: 'user',
+ password: 'password',
+ database: 'odms',
+ entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
+ synchronize: false, // trueにすると自動的にmigrationが行われるため注意
+ });
+ return await s.initialize();
+ })();
+ }
+ });
- beforeEach(async () => {
- if (source) {
- await truncateAllTable(source);
- }
- });
+ beforeEach(async () => {
+ if (source) {
+ await truncateAllTable(source);
+ }
+ });
- afterAll(async () => {
- await source?.destroy();
- source = null;
- });
+ afterAll(async () => {
+ await source?.destroy();
+ source = null;
+ });
it('[Admin] Taskが0件であっても実行できる', async () => {
const notificationhubServiceMockValue =
@@ -790,7 +790,7 @@ describe('changeCheckoutPermission', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -1432,7 +1432,7 @@ describe('checkout', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -2026,7 +2026,7 @@ describe('checkin', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -2241,7 +2241,7 @@ describe('suspend', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -2452,7 +2452,7 @@ describe('cancel', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -3080,7 +3080,7 @@ describe('backup', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -3386,7 +3386,7 @@ describe('getNextTask', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
diff --git a/dictation_server/src/features/terms/terms.service.spec.ts b/dictation_server/src/features/terms/terms.service.spec.ts
index 4a6ac7e..3607f41 100644
--- a/dictation_server/src/features/terms/terms.service.spec.ts
+++ b/dictation_server/src/features/terms/terms.service.spec.ts
@@ -12,7 +12,7 @@ describe('利用規約取得', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
diff --git a/dictation_server/src/features/users/users.service.spec.ts b/dictation_server/src/features/users/users.service.spec.ts
index dc3b656..8e4a9fe 100644
--- a/dictation_server/src/features/users/users.service.spec.ts
+++ b/dictation_server/src/features/users/users.service.spec.ts
@@ -436,7 +436,7 @@ describe('UsersService.createUser', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -1393,7 +1393,7 @@ describe('UsersService.getUsers', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -1882,7 +1882,7 @@ describe('UsersService.updateUser', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -2478,7 +2478,7 @@ describe('UsersService.updateAcceptedVersion', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -2578,7 +2578,7 @@ describe('UsersService.getUserName', () => {
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -2632,7 +2632,7 @@ describe('UsersService.getRelations', () => {
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',
@@ -2708,7 +2708,7 @@ describe('UsersService.getRelations', () => {
{
const workflows = await getWorkflows(source, account.id);
workflows.sort((a, b) => a.id - b.id);
-
+
expect(workflows.length).toBe(4);
expect(workflows[0].worktype_id).toBe(worktype1.id);
expect(workflows[0].author_id).toBe(user1);
diff --git a/dictation_server/src/features/workflows/workflows.service.spec.ts b/dictation_server/src/features/workflows/workflows.service.spec.ts
index d04e4c5..5c464aa 100644
--- a/dictation_server/src/features/workflows/workflows.service.spec.ts
+++ b/dictation_server/src/features/workflows/workflows.service.spec.ts
@@ -25,7 +25,7 @@ describe('getWorkflows', () => {
let source: DataSource | null = null;
beforeAll(async () => {
if (source == null) {
- source = await(async () => {
+ source = await (async () => {
const s = new DataSource({
type: 'mysql',
host: 'test_mysql_db',