Merged PR 724: API実装
## 概要 [Task3535: API実装](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3535) - タイピストグループ削除APIとテストを実装しました。 accountのテストがうまくいっていないようなので別途見直します。 ※タイピストグループ削除のテストはうまくいっています ## レビューポイント - エラーケースと出力されるコードは適切でしょうか? - テストケースは適切でしょうか? ## UIの変更 - なし ## 動作確認状況 - ローカルで確認
This commit is contained in:
parent
feeec9d1f5
commit
19b544540e
@ -76,4 +76,7 @@ export const ErrorCodes = [
|
||||
'E014007', // ユーザー削除エラー(削除しようとしたユーザーが有効なライセンスを持っていた)
|
||||
'E014008', // ユーザー削除エラー(削除しようとしたユーザーが自分自身だった)
|
||||
'E014009', // ユーザー削除エラー(削除しようとしたユーザーがタスクのルーティング(文字起こし候補)になっている場合)
|
||||
'E015001', // タイピストグループ削除エラー(削除しようとしたタイピストグループがすでに削除済みだった)
|
||||
'E015002', // タイピストグループ削除エラー(削除しようとしたタイピストグループがWorkflowのTypist候補として指定されていた)
|
||||
'E015003', // タイピストグループ削除エラー(削除しようとしたタイピストグループがチェックアウト可能なタスクが存在した)
|
||||
] as const;
|
||||
|
||||
@ -65,4 +65,7 @@ export const errors: Errors = {
|
||||
E014007: 'User delete failed Error: enabled license assigned',
|
||||
E014008: 'User delete failed Error: delete myself',
|
||||
E014009: 'User delete failed Error: user has checkout permissions.',
|
||||
E015001: 'Typist Group delete failed Error: already deleted',
|
||||
E015002: 'Typist Group delete failed Error: workflow assigned',
|
||||
E015003: 'Typist Group delete failed Error: checkout permission existed',
|
||||
};
|
||||
|
||||
@ -80,7 +80,7 @@ export const makeTestingModule = async (
|
||||
WorktypesRepositoryModule,
|
||||
TermsRepositoryModule,
|
||||
RedisModule,
|
||||
CacheModule.register({ isGlobal: true }),
|
||||
CacheModule.register({ isGlobal: true, ttl: 86400 }),
|
||||
],
|
||||
providers: [
|
||||
AuthService,
|
||||
|
||||
@ -834,7 +834,7 @@ export class AccountsController {
|
||||
const context = makeContext(userId, requestId);
|
||||
this.logger.log(`[${context.getTrackingId()}] ip : ${ip}`);
|
||||
|
||||
// TODO: 削除処理
|
||||
await this.accountService.deleteTypistGroup(context, userId, typistGroupId);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@ import {
|
||||
getSortCriteria,
|
||||
getTypistGroup,
|
||||
getTypistGroupMember,
|
||||
getTypistGroupMembers,
|
||||
getWorktypes,
|
||||
} from './test/utility';
|
||||
import { DataSource } from 'typeorm';
|
||||
@ -46,6 +47,7 @@ import {
|
||||
LICENSE_ISSUE_STATUS,
|
||||
LICENSE_TYPE,
|
||||
OPTION_ITEM_VALUE_TYPE,
|
||||
TASK_STATUS,
|
||||
TIERS,
|
||||
USER_ROLES,
|
||||
WORKTYPE_MAX_COUNT,
|
||||
@ -76,9 +78,16 @@ import { AdB2cUser } from '../../gateways/adb2c/types/types';
|
||||
import { Worktype } from '../../repositories/worktypes/entity/worktype.entity';
|
||||
import { AccountsRepositoryService } from '../../repositories/accounts/accounts.repository.service';
|
||||
import { UsersRepositoryService } from '../../repositories/users/users.repository.service';
|
||||
import { createWorkflow, getWorkflows } from '../workflows/test/utility';
|
||||
import {
|
||||
createWorkflow,
|
||||
createWorkflowTypist,
|
||||
getWorkflowTypists,
|
||||
getWorkflows,
|
||||
} from '../workflows/test/utility';
|
||||
import { UsersService } from '../users/users.service';
|
||||
import { truncateAllTable } from '../../common/test/init';
|
||||
import { createTask, getCheckoutPermissions } from '../tasks/test/utility';
|
||||
import { createCheckoutPermissions } from '../tasks/test/utility';
|
||||
|
||||
describe('createAccount', () => {
|
||||
let source: DataSource | null = null;
|
||||
@ -134,8 +143,8 @@ describe('createAccount', () => {
|
||||
},
|
||||
});
|
||||
|
||||
let _subject: string = "";
|
||||
let _url: string | undefined = "";
|
||||
let _subject: string = '';
|
||||
let _url: string | undefined = '';
|
||||
overrideSendgridService(service, {
|
||||
sendMail: async (
|
||||
context: Context,
|
||||
@ -199,7 +208,9 @@ describe('createAccount', () => {
|
||||
|
||||
// 想定通りのメールが送られているか確認
|
||||
expect(_subject).toBe('User Registration Notification [U-102]');
|
||||
expect(_url?.startsWith('http://localhost:8081/mail-confirm?verify=')).toBeTruthy();
|
||||
expect(
|
||||
_url?.startsWith('http://localhost:8081/mail-confirm?verify='),
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
it('アカウントを作成がAzure AD B2Cへの通信失敗によって失敗すると500エラーが発生する', async () => {
|
||||
@ -2281,6 +2292,9 @@ describe('issueLicense', () => {
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
overrideAdB2cService(service, {
|
||||
getUsers: async () => [],
|
||||
});
|
||||
overrideSendgridService(service, {});
|
||||
|
||||
const now = new Date();
|
||||
@ -2378,6 +2392,9 @@ describe('issueLicense', () => {
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
overrideAdB2cService(service, {
|
||||
getUsers: async () => [],
|
||||
});
|
||||
overrideSendgridService(service, {});
|
||||
const now = new Date();
|
||||
// 親と子アカウントを作成する
|
||||
@ -2477,6 +2494,9 @@ describe('issueLicense', () => {
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
overrideAdB2cService(service, {
|
||||
getUsers: async () => [],
|
||||
});
|
||||
const now = new Date();
|
||||
// 親と子アカウントを作成する
|
||||
const { id: parentAccountId } = (
|
||||
@ -3611,6 +3631,319 @@ describe('updateTypistGroup', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('deleteTypistGroup', () => {
|
||||
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();
|
||||
})();
|
||||
}
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
if (source) {
|
||||
await truncateAllTable(source);
|
||||
}
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await source?.destroy();
|
||||
source = null;
|
||||
});
|
||||
|
||||
it('TypistGroupを削除できる', async () => {
|
||||
if (!source) fail();
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
// 第五階層のアカウント作成
|
||||
const { account, admin } = await makeTestAccount(source, { tier: 5 });
|
||||
// 作成したアカウントにユーザーを追加する
|
||||
const { id: typistUserId } = await makeTestUser(source, {
|
||||
account_id: account.id,
|
||||
external_id: 'typist-user-external-id',
|
||||
role: USER_ROLES.TYPIST,
|
||||
});
|
||||
});
|
||||
it('TypistGroupを削除できる', async () => {
|
||||
if (!source) fail();
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
// 第五階層のアカウント作成
|
||||
const { account, admin } = await makeTestAccount(source, { tier: 5 });
|
||||
// 作成したアカウントにユーザーを追加する
|
||||
const { id: typistUserId } = await makeTestUser(source, {
|
||||
account_id: account.id,
|
||||
external_id: 'typist-user-external-id',
|
||||
role: USER_ROLES.TYPIST,
|
||||
});
|
||||
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
const context = makeContext(admin.external_id, 'requestId');
|
||||
const typistGroupName = 'typist-group-name';
|
||||
await service.createTypistGroup(
|
||||
context,
|
||||
admin.external_id,
|
||||
typistGroupName,
|
||||
[typistUserId],
|
||||
);
|
||||
|
||||
//作成したデータを確認
|
||||
const group = await getTypistGroup(source, account.id);
|
||||
{
|
||||
expect(group.length).toBe(1);
|
||||
expect(group[0].name).toBe(typistGroupName);
|
||||
const groupUsers = await getTypistGroupMember(source, group[0].id);
|
||||
expect(groupUsers.length).toBe(1);
|
||||
expect(groupUsers[0].user_group_id).toBe(group[0].id);
|
||||
expect(groupUsers[0].user_id).toBe(typistUserId);
|
||||
}
|
||||
|
||||
await service.deleteTypistGroup(context, admin.external_id, group[0].id);
|
||||
//実行結果を確認
|
||||
{
|
||||
const typistGroups = await getTypistGroup(source, account.id);
|
||||
expect(typistGroups.length).toBe(0);
|
||||
|
||||
const typistGroupUsers = await getTypistGroupMembers(source);
|
||||
expect(typistGroupUsers.length).toBe(0);
|
||||
}
|
||||
});
|
||||
it('タイピストグループが存在しない場合、400エラーを返却する', async () => {
|
||||
if (!source) fail();
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
// 第五階層のアカウント作成
|
||||
const { account, admin } = await makeTestAccount(source, { tier: 5 });
|
||||
|
||||
// 作成したアカウントにユーザーを追加する
|
||||
const user = await makeTestUser(source, {
|
||||
account_id: account.id,
|
||||
external_id: 'typist-user-external-id',
|
||||
role: USER_ROLES.TYPIST,
|
||||
});
|
||||
|
||||
const typistGroupName = 'typist-group-name';
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
const context = makeContext(admin.external_id, 'requestId');
|
||||
await service.createTypistGroup(
|
||||
context,
|
||||
admin.external_id,
|
||||
typistGroupName,
|
||||
[user.id],
|
||||
);
|
||||
|
||||
//作成したデータを確認
|
||||
const group = await getTypistGroup(source, account.id);
|
||||
{
|
||||
expect(group.length).toBe(1);
|
||||
expect(group[0].name).toBe(typistGroupName);
|
||||
const groupUsers = await getTypistGroupMember(source, group[0].id);
|
||||
expect(groupUsers.length).toBe(1);
|
||||
expect(groupUsers[0].user_group_id).toBe(group[0].id);
|
||||
}
|
||||
|
||||
try {
|
||||
await service.deleteTypistGroup(context, admin.external_id, 999);
|
||||
} catch (e) {
|
||||
if (e instanceof HttpException) {
|
||||
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
|
||||
expect(e.getResponse()).toEqual(makeErrorResponse('E015001'));
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
});
|
||||
it('タイピストグループがルーティングルールに紐づいていた場合、400エラーを返却する', async () => {
|
||||
if (!source) fail();
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
// 第五階層のアカウント作成
|
||||
const { account, admin } = await makeTestAccount(source, { tier: 5 });
|
||||
// 作成したアカウントにユーザーを追加する
|
||||
const { id: typistUserId } = await makeTestUser(source, {
|
||||
account_id: account.id,
|
||||
external_id: 'typist-user-external-id',
|
||||
role: USER_ROLES.TYPIST,
|
||||
});
|
||||
const { id: authorUserId } = await makeTestUser(source, {
|
||||
account_id: account.id,
|
||||
external_id: 'author-user-external-id',
|
||||
role: USER_ROLES.AUTHOR,
|
||||
});
|
||||
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
const context = makeContext(admin.external_id, 'requestId');
|
||||
const typistGroupName = 'typist-group-name';
|
||||
await service.createTypistGroup(
|
||||
context,
|
||||
admin.external_id,
|
||||
typistGroupName,
|
||||
[typistUserId],
|
||||
);
|
||||
|
||||
const group = await getTypistGroup(source, account.id);
|
||||
const workflow = await createWorkflow(source, account.id, authorUserId);
|
||||
await createWorkflowTypist(source, workflow.id, undefined, group[0].id);
|
||||
//作成したデータを確認
|
||||
{
|
||||
const workflowTypists = await getWorkflowTypists(source, workflow.id);
|
||||
expect(group.length).toBe(1);
|
||||
expect(group[0].name).toBe(typistGroupName);
|
||||
const groupUsers = await getTypistGroupMember(source, group[0].id);
|
||||
expect(groupUsers.length).toBe(1);
|
||||
expect(groupUsers[0].user_group_id).toBe(group[0].id);
|
||||
expect(groupUsers[0].user_id).toBe(typistUserId);
|
||||
expect(workflowTypists.length).toBe(1);
|
||||
expect(workflowTypists[0].typist_group_id).toBe(group[0].id);
|
||||
}
|
||||
|
||||
try {
|
||||
await service.deleteTypistGroup(context, admin.external_id, group[0].id);
|
||||
} catch (e) {
|
||||
if (e instanceof HttpException) {
|
||||
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
|
||||
expect(e.getResponse()).toEqual(makeErrorResponse('E015002'));
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
});
|
||||
it('タイピストグループがタスクのチェックアウト候補だった場合、400エラーを返却する', async () => {
|
||||
if (!source) fail();
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
// 第五階層のアカウント作成
|
||||
const { account, admin } = await makeTestAccount(source, { tier: 5 });
|
||||
// 作成したアカウントにユーザーを追加する
|
||||
const { id: typistUserId } = await makeTestUser(source, {
|
||||
account_id: account.id,
|
||||
external_id: 'typist-user-external-id',
|
||||
role: USER_ROLES.TYPIST,
|
||||
});
|
||||
const authorId = 'AUTHOR_ID';
|
||||
const { id: authorUserId } = await makeTestUser(source, {
|
||||
account_id: account.id,
|
||||
external_id: 'author-user-external-id',
|
||||
role: USER_ROLES.AUTHOR,
|
||||
author_id: authorId,
|
||||
});
|
||||
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
const context = makeContext(admin.external_id, 'requestId');
|
||||
const typistGroupName = 'typist-group-name';
|
||||
await service.createTypistGroup(
|
||||
context,
|
||||
admin.external_id,
|
||||
typistGroupName,
|
||||
[typistUserId],
|
||||
);
|
||||
|
||||
const group = await getTypistGroup(source, account.id);
|
||||
const { taskId } = await createTask(
|
||||
source,
|
||||
account.id,
|
||||
authorUserId,
|
||||
authorId,
|
||||
'worktypeId',
|
||||
'01',
|
||||
'00000001',
|
||||
TASK_STATUS.UPLOADED,
|
||||
);
|
||||
|
||||
await createCheckoutPermissions(source, taskId, undefined, group[0].id);
|
||||
|
||||
//作成したデータを確認
|
||||
{
|
||||
const checkoutPermission = await getCheckoutPermissions(source, taskId);
|
||||
expect(group.length).toBe(1);
|
||||
expect(group[0].name).toBe(typistGroupName);
|
||||
const groupUsers = await getTypistGroupMember(source, group[0].id);
|
||||
expect(groupUsers.length).toBe(1);
|
||||
expect(groupUsers[0].user_group_id).toBe(group[0].id);
|
||||
expect(groupUsers[0].user_id).toBe(typistUserId);
|
||||
expect(checkoutPermission.length).toBe(1);
|
||||
expect(checkoutPermission[0].user_group_id).toBe(group[0].id);
|
||||
}
|
||||
|
||||
try {
|
||||
await service.deleteTypistGroup(context, admin.external_id, group[0].id);
|
||||
} catch (e) {
|
||||
if (e instanceof HttpException) {
|
||||
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
|
||||
expect(e.getResponse()).toEqual(makeErrorResponse('E015003'));
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('DBアクセスに失敗した場合、500エラーを返却する', async () => {
|
||||
if (!source) fail();
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
// 第五階層のアカウント作成
|
||||
const { account, admin } = await makeTestAccount(source, { tier: 5 });
|
||||
// 作成したアカウントにユーザーを追加する
|
||||
const typiptUserExternalId = 'typist-user-external-id';
|
||||
const { id: typistUserId } = await makeTestUser(source, {
|
||||
account_id: account.id,
|
||||
external_id: typiptUserExternalId,
|
||||
role: USER_ROLES.TYPIST,
|
||||
});
|
||||
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
const context = makeContext(admin.external_id, 'requestId');
|
||||
const typistGroupName = 'typist-group-name';
|
||||
await service.createTypistGroup(
|
||||
context,
|
||||
admin.external_id,
|
||||
typistGroupName,
|
||||
[typistUserId],
|
||||
);
|
||||
|
||||
//作成したデータを確認
|
||||
const group = await getTypistGroup(source, account.id);
|
||||
{
|
||||
expect(group.length).toBe(1);
|
||||
expect(group[0].name).toBe(typistGroupName);
|
||||
const groupUsers = await getTypistGroupMember(source, group[0].id);
|
||||
expect(groupUsers.length).toBe(1);
|
||||
expect(groupUsers[0].user_group_id).toEqual(group[0].id);
|
||||
expect(groupUsers[0].user_id).toEqual(typistUserId);
|
||||
}
|
||||
|
||||
//DBアクセスに失敗するようにする
|
||||
const typistGroupService = module.get<UserGroupsRepositoryService>(
|
||||
UserGroupsRepositoryService,
|
||||
);
|
||||
typistGroupService.deleteTypistGroup = jest
|
||||
.fn()
|
||||
.mockRejectedValue('DB failed');
|
||||
|
||||
try {
|
||||
await service.deleteTypistGroup(context, admin.external_id, group[0].id);
|
||||
} catch (e) {
|
||||
if (e instanceof HttpException) {
|
||||
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('getWorktypes', () => {
|
||||
let source: DataSource | null = null;
|
||||
beforeAll(async () => {
|
||||
@ -5256,6 +5589,9 @@ describe('ライセンス発行キャンセル', () => {
|
||||
);
|
||||
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
overrideAdB2cService(service, {
|
||||
getUsers: async () => [],
|
||||
});
|
||||
overrideSendgridService(service, {});
|
||||
await service.cancelIssue(
|
||||
makeContext('trackingId', 'requestId'),
|
||||
@ -5320,6 +5656,9 @@ describe('ライセンス発行キャンセル', () => {
|
||||
);
|
||||
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
overrideAdB2cService(service, {
|
||||
getUsers: async () => [],
|
||||
});
|
||||
overrideSendgridService(service, {});
|
||||
await service.cancelIssue(
|
||||
makeContext('trackingId', 'requestId'),
|
||||
@ -5358,6 +5697,9 @@ describe('ライセンス発行キャンセル', () => {
|
||||
});
|
||||
const poNumber = 'CANCEL_TEST';
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
overrideAdB2cService(service, {
|
||||
getUsers: async () => [],
|
||||
});
|
||||
overrideSendgridService(service, {});
|
||||
await expect(
|
||||
service.cancelIssue(
|
||||
@ -5405,6 +5747,9 @@ describe('ライセンス発行キャンセル', () => {
|
||||
null,
|
||||
);
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
overrideAdB2cService(service, {
|
||||
getUsers: async () => [],
|
||||
});
|
||||
overrideSendgridService(service, {});
|
||||
await expect(
|
||||
service.cancelIssue(
|
||||
@ -5452,6 +5797,9 @@ describe('ライセンス発行キャンセル', () => {
|
||||
null,
|
||||
);
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
overrideAdB2cService(service, {
|
||||
getUsers: async () => [],
|
||||
});
|
||||
overrideSendgridService(service, {});
|
||||
await expect(
|
||||
service.cancelIssue(
|
||||
@ -5500,6 +5848,9 @@ describe('ライセンス発行キャンセル', () => {
|
||||
null,
|
||||
);
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
overrideAdB2cService(service, {
|
||||
getUsers: async () => [],
|
||||
});
|
||||
overrideSendgridService(service, {});
|
||||
await expect(
|
||||
service.cancelIssue(
|
||||
@ -5729,8 +6080,13 @@ describe('アカウント情報更新', () => {
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
let _subject: string = "";
|
||||
let _url: string | undefined = "";
|
||||
overrideAdB2cService(service, {
|
||||
getUser: async () => {
|
||||
return { id: 'admin.external_id', displayName: 'admin' };
|
||||
},
|
||||
});
|
||||
let _subject: string = '';
|
||||
let _url: string | undefined = '';
|
||||
overrideSendgridService(service, {
|
||||
sendMail: async (
|
||||
context: Context,
|
||||
@ -5797,6 +6153,11 @@ describe('アカウント情報更新', () => {
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
overrideAdB2cService(service, {
|
||||
getUser: async () => {
|
||||
return { id: 'admin.external_id', displayName: 'admin' };
|
||||
},
|
||||
});
|
||||
overrideSendgridService(service, {
|
||||
sendMail: async () => {
|
||||
return;
|
||||
@ -5831,6 +6192,11 @@ describe('アカウント情報更新', () => {
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
overrideAdB2cService(service, {
|
||||
getUser: async () => {
|
||||
return { id: 'admin.external_id', displayName: 'admin' };
|
||||
},
|
||||
});
|
||||
overrideSendgridService(service, {
|
||||
sendMail: async () => {
|
||||
return;
|
||||
@ -5866,6 +6232,11 @@ describe('アカウント情報更新', () => {
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
overrideAdB2cService(service, {
|
||||
getUser: async () => {
|
||||
return { id: 'admin.external_id', displayName: 'admin' };
|
||||
},
|
||||
});
|
||||
overrideSendgridService(service, {
|
||||
sendMail: async () => {
|
||||
return;
|
||||
@ -5898,6 +6269,11 @@ describe('アカウント情報更新', () => {
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
overrideAdB2cService(service, {
|
||||
getUser: async () => {
|
||||
return { id: 'admin.external_id', displayName: 'admin' };
|
||||
},
|
||||
});
|
||||
overrideSendgridService(service, {
|
||||
sendMail: async () => {
|
||||
return;
|
||||
@ -5929,6 +6305,11 @@ describe('アカウント情報更新', () => {
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
overrideAdB2cService(service, {
|
||||
getUser: async () => {
|
||||
return { id: 'admin.external_id', displayName: 'admin' };
|
||||
},
|
||||
});
|
||||
overrideSendgridService(service, {
|
||||
sendMail: async () => {
|
||||
return;
|
||||
@ -6000,6 +6381,9 @@ describe('getAccountInfo', () => {
|
||||
});
|
||||
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
overrideAdB2cService(service, {
|
||||
getUsers: async () => [],
|
||||
});
|
||||
const context = makeContext(admin.external_id, 'requestId');
|
||||
|
||||
const accountResponse = await service.getAccountInfo(
|
||||
@ -6422,6 +6806,14 @@ describe('deleteAccountAndData', () => {
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
// ADB2Cユーザーの削除成功
|
||||
overrideAdB2cService(service, {
|
||||
deleteUsers: jest.fn(),
|
||||
getUsers: jest.fn(),
|
||||
getUser: async () => {
|
||||
return { id: 'admin.external_id', displayName: 'admin' };
|
||||
},
|
||||
});
|
||||
let _subject: string = '';
|
||||
let _url: string | undefined = '';
|
||||
overrideSendgridService(service, {
|
||||
@ -6672,6 +7064,14 @@ describe('deleteAccountAndData', () => {
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
// ADB2Cユーザーの削除成功
|
||||
overrideAdB2cService(service, {
|
||||
deleteUsers: jest.fn(),
|
||||
getUsers: jest.fn(),
|
||||
getUser: async () => {
|
||||
return { id: 'admin.external_id', displayName: 'admin' };
|
||||
},
|
||||
});
|
||||
overrideSendgridService(service, {});
|
||||
const loggerSpy = jest.spyOn(service['logger'], 'log').mockImplementation();
|
||||
// 第五階層のアカウント作成
|
||||
@ -6698,11 +7098,6 @@ describe('deleteAccountAndData', () => {
|
||||
deleteAccountAndInsertArchives: jest.fn().mockRejectedValue(new Error()),
|
||||
});
|
||||
|
||||
// ADB2Cユーザーの削除成功
|
||||
overrideAdB2cService(service, {
|
||||
deleteUsers: jest.fn(),
|
||||
});
|
||||
|
||||
// blobstorageコンテナの削除成功
|
||||
overrideBlobstorageService(service, {
|
||||
deleteContainer: jest.fn(),
|
||||
@ -6737,6 +7132,14 @@ describe('deleteAccountAndData', () => {
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
// ADB2Cユーザーの削除失敗
|
||||
overrideAdB2cService(service, {
|
||||
deleteUsers: jest.fn().mockRejectedValue(new Error()),
|
||||
getUsers: jest.fn(),
|
||||
getUser: async () => {
|
||||
return { id: 'admin.external_id', displayName: 'admin' };
|
||||
},
|
||||
});
|
||||
overrideSendgridService(service, {});
|
||||
const loggerSpy = jest.spyOn(service['logger'], 'log').mockImplementation();
|
||||
// 第五階層のアカウント作成
|
||||
@ -6758,11 +7161,6 @@ describe('deleteAccountAndData', () => {
|
||||
account_id: tier5Accounts.account.id,
|
||||
});
|
||||
|
||||
// ADB2Cユーザーの削除失敗
|
||||
overrideAdB2cService(service, {
|
||||
deleteUsers: jest.fn().mockRejectedValue(new Error()),
|
||||
});
|
||||
|
||||
// blobstorageコンテナの削除成功
|
||||
overrideBlobstorageService(service, {
|
||||
deleteContainer: jest.fn(),
|
||||
@ -6792,6 +7190,14 @@ describe('deleteAccountAndData', () => {
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
// ADB2Cユーザーの削除成功
|
||||
overrideAdB2cService(service, {
|
||||
deleteUsers: jest.fn(),
|
||||
getUsers: jest.fn(),
|
||||
getUser: async () => {
|
||||
return { id: 'admin.external_id', displayName: 'admin' };
|
||||
},
|
||||
});
|
||||
overrideSendgridService(service, {});
|
||||
const loggerSpy = jest.spyOn(service['logger'], 'log').mockImplementation();
|
||||
|
||||
@ -6814,11 +7220,6 @@ describe('deleteAccountAndData', () => {
|
||||
account_id: tier5Accounts.account.id,
|
||||
});
|
||||
|
||||
// ADB2Cユーザーの削除成功
|
||||
overrideAdB2cService(service, {
|
||||
deleteUsers: jest.fn(),
|
||||
});
|
||||
|
||||
// blobstorageコンテナの削除失敗
|
||||
overrideBlobstorageService(service, {
|
||||
deleteContainer: jest.fn().mockRejectedValue(new Error()),
|
||||
@ -6989,6 +7390,7 @@ describe('getAccountInfoMinimalAccess', () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('getCompanyName', () => {
|
||||
let source: DataSource | null = null;
|
||||
beforeAll(async () => {
|
||||
|
||||
@ -60,6 +60,8 @@ import {
|
||||
} from '../../repositories/licenses/errors/types';
|
||||
import { BlobstorageService } from '../../gateways/blobstorage/blobstorage.service';
|
||||
import {
|
||||
AssignedWorkflowDeleteFailedError,
|
||||
ExistsCheckoutPermissionDeleteFailedError,
|
||||
TypistGroupNameAlreadyExistError,
|
||||
TypistGroupNotExistError,
|
||||
TypistIdInvalidError,
|
||||
@ -1348,6 +1350,78 @@ export class AccountsService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* タイピストグループを削除する
|
||||
* @param context
|
||||
* @param externalId
|
||||
* @param typistGroupId
|
||||
* @returns typist group
|
||||
*/
|
||||
async deleteTypistGroup(
|
||||
context: Context,
|
||||
externalId: string,
|
||||
typistGroupId: number,
|
||||
): Promise<void> {
|
||||
this.logger.log(
|
||||
`[IN] [${context.getTrackingId()}] ${
|
||||
this.deleteTypistGroup.name
|
||||
} | params: { ` +
|
||||
`externalId: ${externalId}, ` +
|
||||
`typistGroupId: ${typistGroupId}, `,
|
||||
);
|
||||
try {
|
||||
// 外部IDをもとにユーザー情報を取得する
|
||||
const { account_id } = await this.usersRepository.findUserByExternalId(
|
||||
context,
|
||||
externalId,
|
||||
);
|
||||
|
||||
// タイピストグループを削除する
|
||||
await this.userGroupsRepository.deleteTypistGroup(
|
||||
context,
|
||||
account_id,
|
||||
typistGroupId,
|
||||
);
|
||||
} catch (e) {
|
||||
this.logger.error(`[${context.getTrackingId()}] error=${e}`);
|
||||
if (e instanceof Error) {
|
||||
switch (e.constructor) {
|
||||
// タイピストグループ削除済み
|
||||
case TypistGroupNotExistError:
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E015001'),
|
||||
HttpStatus.BAD_REQUEST,
|
||||
);
|
||||
// タイピストグループがルーティングルールに使用されている
|
||||
case AssignedWorkflowDeleteFailedError:
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E015002'),
|
||||
HttpStatus.BAD_REQUEST,
|
||||
);
|
||||
// タイピストグループがタスクの文字起こし候補に使用されている
|
||||
case ExistsCheckoutPermissionDeleteFailedError:
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E015003'),
|
||||
HttpStatus.BAD_REQUEST,
|
||||
);
|
||||
default:
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E009999'),
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
}
|
||||
}
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E009999'),
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
} finally {
|
||||
this.logger.log(
|
||||
`[OUT] [${context.getTrackingId()}] ${this.deleteTypistGroup.name}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ライセンス発行をキャンセルする
|
||||
* @param context
|
||||
|
||||
@ -42,6 +42,7 @@ export type UserGroupsRepositoryMockValue = {
|
||||
export type AdB2cMockValue = {
|
||||
createUser: string | ConflictError | Error;
|
||||
getUsers: AdB2cUser[] | Error;
|
||||
getUser: AdB2cUser | Error;
|
||||
};
|
||||
export type SendGridMockValue = {
|
||||
sendMail: undefined | Error;
|
||||
@ -206,7 +207,7 @@ export const makeUserGroupsRepositoryMock = (
|
||||
};
|
||||
};
|
||||
export const makeAdB2cServiceMock = (value: AdB2cMockValue) => {
|
||||
const { createUser, getUsers } = value;
|
||||
const { createUser, getUsers, getUser } = value;
|
||||
|
||||
return {
|
||||
createUser:
|
||||
@ -219,6 +220,10 @@ export const makeAdB2cServiceMock = (value: AdB2cMockValue) => {
|
||||
getUsers instanceof Error
|
||||
? jest.fn<Promise<void>, []>().mockRejectedValue(getUsers)
|
||||
: jest.fn<Promise<AdB2cUser[]>, []>().mockResolvedValue(getUsers),
|
||||
getUser:
|
||||
getUser instanceof Error
|
||||
? jest.fn<Promise<void>, []>().mockRejectedValue(getUser)
|
||||
: jest.fn<Promise<AdB2cUser>, []>().mockResolvedValue(getUser),
|
||||
};
|
||||
};
|
||||
export const makeConfigMock = (value: ConfigMockValue) => {
|
||||
@ -437,6 +442,10 @@ export const makeDefaultAdB2cMockValue = (): AdB2cMockValue => {
|
||||
displayName: 'Typist3',
|
||||
},
|
||||
],
|
||||
getUser: {
|
||||
id: 'typist1',
|
||||
displayName: 'Typist1',
|
||||
},
|
||||
};
|
||||
};
|
||||
export const makeDefaultSendGridlValue = (): SendGridMockValue => {
|
||||
|
||||
@ -123,6 +123,13 @@ export const getTypistGroupMember = async (
|
||||
});
|
||||
};
|
||||
|
||||
// タイピストグループメンバー一覧を取得する
|
||||
export const getTypistGroupMembers = async (
|
||||
datasource: DataSource,
|
||||
): Promise<UserGroupMember[]> => {
|
||||
return await datasource.getRepository(UserGroupMember).find();
|
||||
};
|
||||
|
||||
// Worktypeを作成する
|
||||
export const createWorktype = async (
|
||||
datasource: DataSource,
|
||||
|
||||
@ -12,10 +12,26 @@ export class TypistIdInvalidError extends Error {
|
||||
this.name = 'TypistIdInvalidError';
|
||||
}
|
||||
}
|
||||
|
||||
// 削除対象グループがWorkflowにアサインされている事が原因の削除失敗エラー
|
||||
export class AssignedWorkflowDeleteFailedError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = 'AssignedWorkflowDeleteFailedError';
|
||||
}
|
||||
}
|
||||
|
||||
// 削除対象グループがチェックアウト権限を持っている事が原因の削除失敗エラー
|
||||
export class ExistsCheckoutPermissionDeleteFailedError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = 'ExistsCheckoutPermissionDeleteFailedError';
|
||||
}
|
||||
}
|
||||
// 同名のタイピストグループが存在する場合のエラー
|
||||
export class TypistGroupNameAlreadyExistError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = 'TypistGroupNameAlreadyExistError';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,10 @@ import { DataSource, In, IsNull, Not } from 'typeorm';
|
||||
import { UserGroup } from './entity/user_group.entity';
|
||||
import { UserGroupMember } from './entity/user_group_member.entity';
|
||||
import { User } from '../users/entity/user.entity';
|
||||
import { WorkflowTypist } from '../workflows/entity/workflow_typists.entity';
|
||||
import {
|
||||
AssignedWorkflowDeleteFailedError,
|
||||
ExistsCheckoutPermissionDeleteFailedError,
|
||||
TypistGroupNameAlreadyExistError,
|
||||
TypistGroupNotExistError,
|
||||
TypistIdInvalidError,
|
||||
@ -16,6 +19,7 @@ import {
|
||||
deleteEntity,
|
||||
} from '../../common/repository';
|
||||
import { Context } from '../../common/log';
|
||||
import { CheckoutPermission } from '../checkout_permissions/entity/checkout_permission.entity';
|
||||
|
||||
@Injectable()
|
||||
export class UserGroupsRepositoryService {
|
||||
@ -285,4 +289,81 @@ export class UserGroupsRepositoryService {
|
||||
return typistGroup;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定したIDのタイピストグループを削除します
|
||||
* @param context
|
||||
* @param accountId
|
||||
* @param typistGroupId
|
||||
* @returns typist group
|
||||
*/
|
||||
async deleteTypistGroup(
|
||||
context: Context,
|
||||
accountId: number,
|
||||
typistGroupId: number,
|
||||
): Promise<void> {
|
||||
await this.dataSource.transaction(async (entityManager) => {
|
||||
const userGroupRepo = entityManager.getRepository(UserGroup);
|
||||
// GroupIdが自アカウント内に存在するか確認する
|
||||
const typistGroup = await userGroupRepo.findOne({
|
||||
relations: { userGroupMembers: true },
|
||||
where: {
|
||||
id: typistGroupId,
|
||||
account_id: accountId,
|
||||
},
|
||||
lock: { mode: 'pessimistic_write' },
|
||||
comment: `${context.getTrackingId()}_${new Date().toUTCString()}`,
|
||||
});
|
||||
if (!typistGroup) {
|
||||
throw new TypistGroupNotExistError(
|
||||
`TypistGroup not exists Error. accountId: ${accountId}; typistGroupId: ${typistGroupId}`,
|
||||
);
|
||||
}
|
||||
|
||||
// ルーティングルールに紐づくタイピストグループは削除できない
|
||||
const workflowTypistRepo = entityManager.getRepository(WorkflowTypist);
|
||||
const workflowTypist = await workflowTypistRepo.findOne({
|
||||
where: { typist_group_id: typistGroupId },
|
||||
comment: `${context.getTrackingId()}_${new Date().toUTCString()}`,
|
||||
});
|
||||
|
||||
if (workflowTypist) {
|
||||
throw new AssignedWorkflowDeleteFailedError(
|
||||
`Typist Group is used in routing rule. typistGroupId: ${typistGroupId}`,
|
||||
);
|
||||
}
|
||||
|
||||
// タスクのチェックアウト候補のタイピストグループは削除できない
|
||||
const checkoutPermissionRepo =
|
||||
entityManager.getRepository(CheckoutPermission);
|
||||
|
||||
const checkoutPermission = await checkoutPermissionRepo.findOne({
|
||||
where: { user_group_id: typistGroupId },
|
||||
comment: `${context.getTrackingId()}_${new Date().toUTCString()}`,
|
||||
});
|
||||
|
||||
if (checkoutPermission) {
|
||||
throw new ExistsCheckoutPermissionDeleteFailedError(
|
||||
`Typist Group is used in task checkout permission. typistGroupId: ${typistGroupId}`,
|
||||
);
|
||||
}
|
||||
|
||||
const userGroupMemberRepo = entityManager.getRepository(UserGroupMember);
|
||||
// 対象のタイピストグループのユーザーを削除する
|
||||
await deleteEntity(
|
||||
userGroupMemberRepo,
|
||||
{ user_group_id: typistGroupId },
|
||||
this.isCommentOut,
|
||||
context,
|
||||
);
|
||||
|
||||
// 対象のタイピストグループを削除する
|
||||
await deleteEntity(
|
||||
userGroupRepo,
|
||||
{ id: typistGroupId },
|
||||
this.isCommentOut,
|
||||
context,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user