OMDSCloud/dictation_server/src/features/users/users.service.spec.ts
saito.k 6690302ac3 Merged PR 920: API修正
## 概要
[Task4336: API修正](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/4336)

- 文字起こし完了時のメールを文字起こし担当のTypistに送信しないようにする

## レビューポイント
- 特になし

## UIの変更
- Before/Afterのスクショなど
- スクショ置き場

## 動作確認状況
- ローカルで確認
- ほかのテストケースがすべて通ることを確認
- メール送信処理を確認するテストケースを追加

## 補足
- 相談、参考資料などがあれば
2024-08-09 07:47:33 +00:00

5147 lines
154 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { HttpException, HttpStatus } from '@nestjs/common';
import { makeErrorResponse } from '../../common/error/makeErrorResponse';
import {
makeDefaultAdB2cMockValue,
makeDefaultConfigValue,
makeDefaultSendGridlValue,
makeDefaultSortCriteriaRepositoryMockValue,
makeDefaultUsersRepositoryMockValue,
makeUsersServiceMock,
} from './test/users.service.mock';
import {
createLicense,
createUserGroup,
getLicenses,
makeTestingModuleWithAdb2c,
} from './test/utility';
import { DataSource } from 'typeorm';
import { UsersService } from './users.service';
import {
ADB2C_SIGN_IN_TYPE,
LICENSE_ALLOCATED_STATUS,
LICENSE_EXPIRATION_THRESHOLD_DAYS,
LICENSE_TYPE,
MANUAL_RECOVERY_REQUIRED,
TASK_STATUS,
USER_AUDIO_FORMAT,
USER_LICENSE_EXPIRY_STATUS,
USER_ROLES,
} from '../../constants';
import { makeTestingModule } from '../../common/test/modules';
import { Context, makeContext } from '../../common/log';
import {
overrideAdB2cService,
overrideBlobstorageService,
overrideSendgridService,
overrideUsersRepositoryService,
} from '../../common/test/overrides';
import { NewTrialLicenseExpirationDate } from '../licenses/types/types';
import { License } from '../../repositories/licenses/entity/license.entity';
import { AdB2cService } from '../../gateways/adb2c/adb2c.service';
import {
getUser,
getUserArchive,
getUserFromExternalId,
getUsers,
makeTestAccount,
makeTestSimpleAccount,
makeTestUser,
} from '../../common/test/utility';
import { v4 as uuidv4 } from 'uuid';
import { createOptionItems, createWorktype } from '../accounts/test/utility';
import {
createWorkflow,
createWorkflowTypist,
getWorkflows,
} from '../workflows/test/utility';
import { truncateAllTable } from '../../common/test/init';
import { createTask } from '../files/test/utility';
import { createCheckoutPermissions } from '../tasks/test/utility';
import { MultipleImportErrors } from './types/types';
import { TestLogger } from '../../common/test/logger';
import { SendGridService } from '../../gateways/sendgrid/sendgrid.service';
describe('UsersService.confirmUser', () => {
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が行われるため注意
logger: new TestLogger('none'),
logging: true,
});
return await s.initialize();
})();
}
});
beforeEach(async () => {
if (source) {
await truncateAllTable(source);
}
});
afterAll(async () => {
await source?.destroy();
source = null;
});
it('ユーザの仮登録時に払い出されるトークンにより、未認証のユーザが認証済みになり、トライアルライセンスが100件作成される', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = (await makeTestAccount(source)).account;
const { id: userId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'externalId_user1',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
email_verified: false,
});
await makeTestUser(source, {
account_id: accountId,
external_id: 'externalId_user2',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
email_verified: false,
});
const service = module.get<UsersService>(UsersService);
let _subject: string = '';
let _url: string | undefined = '';
overrideSendgridService(service, {
sendMail: async (
context: Context,
to: string[],
cc: string[],
from: string,
subject: string,
text: string,
html: string,
) => {
const urlPattern = /https?:\/\/[^\s]+/g;
const urls = text.match(urlPattern);
const url = urls?.pop();
_subject = subject;
_url = url;
},
});
// account id:1, user id: 2のトークン
const token =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw';
const context = makeContext(`uuidv4`, 'requestId');
await service.confirmUser(context, token);
//result
const resultUser = await getUser(source, userId);
const resultLicenses = await getLicenses(source, accountId);
// トライアルライセンスは有効期限は今日を起算日として30日後の日付が変わるまで
const expiryDate = new NewTrialLicenseExpirationDate();
const resultLicensesCheckParam: Omit<
License,
'deleted_at' | 'created_by' | 'created_at' | 'updated_at' | 'updated_by'
> = {
id: 0,
expiry_date: resultLicenses[0].expiry_date,
account_id: resultLicenses[0].account_id,
type: resultLicenses[0].type,
status: resultLicenses[0].status,
allocated_user_id: resultLicenses[0].allocated_user_id,
order_id: resultLicenses[0].order_id,
delete_order_id: resultLicenses[0].delete_order_id,
user: resultLicenses[0].user ?? null,
};
expect(resultUser?.email_verified).toBe(true);
expect(resultLicenses.length).toBe(100);
expect(resultLicensesCheckParam).toEqual({
id: 0,
expiry_date: expiryDate,
account_id: accountId,
type: LICENSE_TYPE.TRIAL,
status: LICENSE_ALLOCATED_STATUS.UNALLOCATED,
allocated_user_id: null,
order_id: null,
delete_order_id: null,
user: null,
});
expect(_subject).toBe('Account Registered Notification [U-101]');
expect(_url).toBe('http://localhost:8081/');
});
it('トークンの形式が不正な場合、形式不正エラーとなる。', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const token = 'invalid.id.token';
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const context = makeContext(`uuidv4`, 'requestId');
await expect(service.confirmUser(context, token)).rejects.toEqual(
new HttpException(makeErrorResponse('E000101'), HttpStatus.BAD_REQUEST),
);
});
it('ユーザが既に認証済みだった場合、認証済みユーザエラーとなる。', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = (await makeTestAccount(source)).account;
await makeTestUser(source, {
account_id: accountId,
external_id: 'externalId_user1',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
email_verified: true, //emailを認証済みにする
});
await makeTestUser(source, {
account_id: accountId,
external_id: 'externalId_user2',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
email_verified: false,
});
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const token =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw';
const context = makeContext(`uuidv4`, 'requestId');
await expect(service.confirmUser(context, token)).rejects.toEqual(
new HttpException(makeErrorResponse('E010202'), HttpStatus.BAD_REQUEST),
);
});
it('ユーザーが存在しない場合は、想定外のエラーとなる', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const token =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw';
const context = makeContext(`uuidv4`, 'requestId');
await expect(service.confirmUser(context, token)).rejects.toEqual(
new HttpException(
makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR,
),
);
});
});
describe('UsersService.confirmUserAndInitPassword', () => {
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が行われるため注意
logger: new TestLogger('none'),
logging: true,
});
return await s.initialize();
})();
}
});
beforeEach(async () => {
if (source) {
await truncateAllTable(source);
}
});
afterAll(async () => {
await source?.destroy();
source = null;
});
it('ユーザーが発行されたパスワードでログインできるようにする', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<UsersService>(UsersService);
const adminExternalId = 'ADMIN0001';
const { account } = await makeTestAccount(
source,
{},
{ external_id: adminExternalId },
);
const { id: accountId } = account;
// ユーザー作成
await makeTestUser(source, {
account_id: accountId,
external_id: 'externalId_user1',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
email_verified: false,
});
overrideAdB2cService(service, {
changePassword: jest.fn(),
getUser: async () => {
return {
id: adminExternalId,
displayName: 'admin',
};
},
});
let _subject: string = '';
overrideSendgridService(service, {
sendMail: async (
context: Context,
to: string[],
cc: string[],
from: string,
subject: string,
text: string,
html: string,
) => {
_subject = subject;
},
});
const token =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw';
await service.confirmUserAndInitPassword(
makeContext('trackingId', 'requestId'),
token,
);
expect(_subject).toBe('Temporary password [U-113]');
const user = await getUserFromExternalId(source, 'externalId_user1');
expect(user?.email_verified).toBe(true);
});
it('トークンの形式が不正な場合、形式不正エラーとなる。(メール認証API)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<UsersService>(UsersService);
const sendgridService = module.get<SendGridService>(SendGridService);
const adB2cService = module.get<AdB2cService>(AdB2cService);
const adminExternalId = 'ADMIN0001';
const { account } = await makeTestAccount(
source,
{},
{ external_id: adminExternalId },
);
const { id: accountId } = account;
// ユーザー作成
await makeTestUser(source, {
account_id: accountId,
external_id: 'externalId_user1',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
email_verified: false,
});
overrideAdB2cService(service, {
changePassword: jest.fn(),
getUser: async () => {
return {
id: adminExternalId,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {
sendMail: jest.fn(),
});
const token = 'invalid.id.token';
try {
await service.confirmUserAndInitPassword(
makeContext('trackingId', 'requestId'),
token,
);
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E000101'));
} else {
fail();
}
}
const user = await getUserFromExternalId(source, 'externalId_user1');
// ユーザーが認証されていないことを確認
expect(user?.email_verified).toBe(false);
// メールが送信されていないことを確認
expect(sendgridService.sendMail).toBeCalledTimes(0);
// パスワードが変更されていないことを確認
expect(adB2cService.changePassword).toBeCalledTimes(0);
});
it('ユーザが既に認証済みだった場合、認証済みユーザエラーとなる。(メール認証API)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<UsersService>(UsersService);
const sendgridService = module.get<SendGridService>(SendGridService);
const adB2cService = module.get<AdB2cService>(AdB2cService);
const adminExternalId = 'ADMIN0001';
const { account } = await makeTestAccount(
source,
{},
{ external_id: adminExternalId },
);
const { id: accountId } = account;
// ユーザー作成
await makeTestUser(source, {
account_id: accountId,
external_id: 'externalId_user1',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
email_verified: true, // emailを認証済みにする
});
overrideAdB2cService(service, {
changePassword: jest.fn(),
getUser: async () => {
return {
id: adminExternalId,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {
sendMail: jest.fn(),
});
const token =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw';
try {
await service.confirmUserAndInitPassword(
makeContext('trackingId', 'requestId'),
token,
);
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010202'));
} else {
fail();
}
}
const user = await getUserFromExternalId(source, 'externalId_user1');
// ユーザーが認証されていることを確認
expect(user?.email_verified).toBe(true);
// メールが送信されていないことを確認
expect(sendgridService.sendMail).toBeCalledTimes(0);
// パスワードが変更されていないことを確認
expect(adB2cService.changePassword).toBeCalledTimes(0);
});
it('ADB2Cユーザーのパスワード更新に失敗した場合、リカバリ処理を行い、メールを未認証のままにする。(メール認証API)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<UsersService>(UsersService);
const sendgridService = module.get<SendGridService>(SendGridService);
const adminExternalId = 'ADMIN0001';
const { account } = await makeTestAccount(
source,
{},
{ external_id: adminExternalId },
);
const { id: accountId } = account;
// ユーザー作成
await makeTestUser(source, {
account_id: accountId,
external_id: 'externalId_user1',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
email_verified: false,
});
overrideAdB2cService(service, {
changePassword: async () => {
throw new Error('ADB2C Error');
},
getUser: async () => {
return {
id: adminExternalId,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {
sendMail: jest.fn(),
});
const token =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw';
try {
await service.confirmUserAndInitPassword(
makeContext('trackingId', 'requestId'),
token,
);
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
} else {
fail();
}
}
const user = await getUserFromExternalId(source, 'externalId_user1');
// ユーザーが認証されていないことを確認
expect(user?.email_verified).toBe(false);
// メールが送信されていないことを確認
expect(sendgridService.sendMail).toBeCalledTimes(0);
});
it('ADB2Cユーザーのパスワード更新に失敗した場合、リカバリ処理を行うが、リカバリ処理に失敗すると認証のままになる(メール認証API)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<UsersService>(UsersService);
const sendgridService = module.get<SendGridService>(SendGridService);
const adminExternalId = 'ADMIN0001';
const { account } = await makeTestAccount(
source,
{},
{ external_id: adminExternalId },
);
const { id: accountId } = account;
// ユーザー作成
await makeTestUser(source, {
account_id: accountId,
external_id: 'externalId_user1',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
email_verified: false,
});
const loggerSpy = jest
.spyOn(service['logger'], 'error')
.mockImplementation();
overrideAdB2cService(service, {
changePassword: async () => {
throw new Error('ADB2C Error');
},
getUser: async () => {
return {
id: adminExternalId,
displayName: 'admin',
};
},
});
overrideUsersRepositoryService(service, {
updateUserUnverified: async () => {
throw new Error('DB Error');
},
});
overrideSendgridService(service, {
sendMail: jest.fn(),
});
const token =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw';
try {
await service.confirmUserAndInitPassword(
makeContext('trackingId', 'requestId'),
token,
);
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
} else {
fail();
}
}
const user = await getUserFromExternalId(source, 'externalId_user1');
// ユーザーが認証されたままであることを確認
expect(user?.email_verified).toBe(true);
// メールが送信されていないことを確認
expect(sendgridService.sendMail).toBeCalledTimes(0);
// loggerSpyがスパイしているlogger.logメソッドが出力したログを確認目視確認用
const logs = loggerSpy.mock.calls.map((call) => call[0]);
// 手動復旧が必要なエラーログが出力されていること
expect(logs.some((x) => x.startsWith(MANUAL_RECOVERY_REQUIRED))).toBe(true);
});
it('DBネットワークエラーとなる場合、エラーとなる。(メール認証API)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<UsersService>(UsersService);
const sendgridService = module.get<SendGridService>(SendGridService);
const adB2cService = module.get<AdB2cService>(AdB2cService);
const adminExternalId = 'ADMIN0001';
const { account } = await makeTestAccount(
source,
{},
{ external_id: adminExternalId },
);
const { id: accountId } = account;
// ユーザー作成
await makeTestUser(source, {
account_id: accountId,
external_id: 'externalId_user1',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
email_verified: false,
});
overrideAdB2cService(service, {
changePassword: jest.fn(),
getUser: async () => {
return {
id: adminExternalId,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {
sendMail: jest.fn(),
});
// DBエラーを発生させる
overrideUsersRepositoryService(service, {
updateUserVerified: async () => {
throw new Error('DB Error');
},
});
const token =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw';
try {
await service.confirmUserAndInitPassword(
makeContext('trackingId', 'requestId'),
token,
);
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
} else {
fail();
}
}
const user = await getUserFromExternalId(source, 'externalId_user1');
// ユーザーが認証されていないことを確認
expect(user?.email_verified).toBe(false);
// メールが送信されていないことを確認
expect(sendgridService.sendMail).toBeCalledTimes(0);
// パスワードが変更されていないことを確認
expect(adB2cService.changePassword).toBeCalledTimes(0);
});
it('メール送信に失敗した場合、リカバリ処理を行い、メールを未認証の状態にする。(メール認証API)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<UsersService>(UsersService);
const adb2cService = module.get<AdB2cService>(AdB2cService);
const adminExternalId = 'ADMIN0001';
const { account } = await makeTestAccount(
source,
{},
{ external_id: adminExternalId },
);
const { id: accountId } = account;
// ユーザー作成
await makeTestUser(source, {
account_id: accountId,
external_id: 'externalId_user1',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
email_verified: false,
});
overrideAdB2cService(service, {
changePassword: jest.fn(),
getUser: async () => {
return {
id: adminExternalId,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {
sendMail: async () => {
throw new Error('SendGrid Error');
},
});
const token =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw';
try {
await service.confirmUserAndInitPassword(
makeContext('trackingId', 'requestId'),
token,
);
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
} else {
fail();
}
}
const user = await getUserFromExternalId(source, 'externalId_user1');
// ユーザーが認証されていないことを確認
expect(user?.email_verified).toBe(false);
// ADB2Cのパスワードが変更されていることを確認(パスワードは変更されても、ユーザーにメールが届いていないので問題ない)
expect(adb2cService.changePassword).toBeCalledTimes(1);
});
it('メール送信に失敗した場合、リカバリ処理を行うが、リカバリ処理に失敗するとADB2Cのパスワードが変更され、DB上も認証された状態になる(メール認証API)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<UsersService>(UsersService);
const adB2cService = module.get<AdB2cService>(AdB2cService);
const adminExternalId = 'ADMIN0001';
const { account } = await makeTestAccount(
source,
{},
{ external_id: adminExternalId },
);
const { id: accountId } = account;
// ユーザー作成
await makeTestUser(source, {
account_id: accountId,
external_id: 'externalId_user1',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
email_verified: false,
});
const loggerSpy = jest
.spyOn(service['logger'], 'error')
.mockImplementation();
overrideAdB2cService(service, {
changePassword: jest.fn(),
getUser: async () => {
return {
id: adminExternalId,
displayName: 'admin',
};
},
});
overrideUsersRepositoryService(service, {
updateUserUnverified: async () => {
throw new Error('DB Error');
},
});
overrideSendgridService(service, {
sendMail: async () => {
throw new Error('SendGrid Error');
},
});
const token =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw';
try {
await service.confirmUserAndInitPassword(
makeContext('trackingId', 'requestId'),
token,
);
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
} else {
fail();
}
}
const user = await getUserFromExternalId(source, 'externalId_user1');
// ユーザーが認証されたままであることを確認
expect(user?.email_verified).toBe(true);
// ADB2Cのパスワードが変更されていることを確認
expect(adB2cService.changePassword).toBeCalledTimes(1);
// loggerSpyがスパイしているlogger.logメソッドが出力したログを確認目視確認用
const logs = loggerSpy.mock.calls.map((call) => call[0]);
// 手動復旧が必要なエラーログが出力されていること
expect(logs.some((x) => x.startsWith(MANUAL_RECOVERY_REQUIRED))).toBe(true);
});
});
describe('UsersService.createUser', () => {
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が行われるため注意
logger: new TestLogger('none'),
logging: true,
});
return await s.initialize();
})();
}
});
beforeEach(async () => {
if (source) {
await truncateAllTable(source);
}
});
afterAll(async () => {
await source?.destroy();
source = null;
});
it('管理者権限のあるアクセストークンを使用して、新規ユーザが追加される(role:None)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<UsersService>(UsersService);
const adminExternalId = 'ADMIN0001';
const { account } = await makeTestAccount(
source,
{},
{ external_id: adminExternalId },
);
const { id: accountId } = account;
const name = 'test_user1';
const role = USER_ROLES.NONE;
const email = 'test1@example.com';
const autoRenew = true;
const licenseAlert = true;
const notification = true;
const externalId = '0001';
overrideAdB2cService(service, {
createUser: async (
_context: Context,
_email: string,
_password: string,
_username: string,
) => {
// ユーザー作成時に指定したパラメータが正しく渡されていることを確認
expect(email).toEqual(_email);
expect(name).toEqual(_username);
return { sub: externalId };
},
getUser: async () => {
return {
id: adminExternalId,
displayName: 'admin',
};
},
});
let _subject: string = '';
let _url: string | undefined = '';
overrideSendgridService(service, {
sendMail: async (
context: Context,
to: string[],
cc: string[],
from: string,
subject: string,
text: string,
html: string,
) => {
const urlPattern = /https?:\/\/[^\s]+/g;
const urls = text.match(urlPattern);
const url = urls?.pop();
_subject = subject;
_url = url;
},
});
expect(
await service.createUser(
makeContext('trackingId', 'requestId'),
adminExternalId,
name,
role,
email,
autoRenew,
notification,
),
).toEqual(undefined);
// 追加されたユーザーが正しくDBに登録されていることを確認
const user = await getUserFromExternalId(source, externalId);
expect(user).not.toBeNull();
expect(user?.account_id).toEqual(accountId);
expect(user?.role).toEqual(role);
expect(user?.author_id).toEqual(null);
expect(user?.email_verified).toEqual(false);
expect(user?.auto_renew).toEqual(autoRenew);
expect(user?.notification).toEqual(notification);
expect(user?.encryption).toEqual(false);
expect(user?.encryption_password).toEqual(null);
expect(user?.prompt).toEqual(false);
// 他にユーザーが登録されていないことを確認
const users = await getUsers(source);
expect(users.length).toEqual(2);
expect(_subject).toBe('User Registration Notification [U-114]');
expect(
_url?.startsWith('http://localhost:8081/mail-confirm/user?verify='),
).toBeTruthy();
});
it('管理者権限のあるアクセストークンを使用して、新規ユーザが追加される(role:Author; 暗号化あり)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<UsersService>(UsersService);
const adminExternalId = 'ADMIN0001';
const { account } = await makeTestAccount(
source,
{},
{ external_id: adminExternalId },
);
const { id: accountId } = account;
const name = 'test_user2';
const role = USER_ROLES.AUTHOR;
const email = 'test2@example.com';
const autoRenew = true;
const licenseAlert = true;
const notification = true;
const authorId = 'testID';
const encryption = true;
const prompt = true;
const encryptionPassword = 'testPassword';
const externalId = '0001';
overrideAdB2cService(service, {
createUser: async (
_context: Context,
_email: string,
_password: string,
_username: string,
) => {
// ユーザー作成時に指定したパラメータが正しく渡されていることを確認
expect(email).toEqual(_email);
expect(name).toEqual(_username);
return { sub: externalId };
},
getUser: async () => {
return {
id: adminExternalId,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
expect(
await service.createUser(
makeContext('trackingId', 'requestId'),
adminExternalId,
name,
role,
email,
autoRenew,
notification,
authorId,
encryption,
encryptionPassword,
prompt,
),
).toEqual(undefined);
// 追加されたユーザーが正しくDBに登録されていることを確認
const user = await getUserFromExternalId(source, externalId);
expect(user).not.toBeNull();
expect(user?.account_id).toEqual(accountId);
expect(user?.role).toEqual(role);
expect(user?.author_id).toEqual(authorId);
expect(user?.email_verified).toEqual(false);
expect(user?.auto_renew).toEqual(autoRenew);
expect(user?.notification).toEqual(notification);
expect(user?.encryption).toEqual(encryption);
expect(user?.encryption_password).toEqual(encryptionPassword);
expect(user?.prompt).toEqual(prompt);
// 他にユーザーが登録されていないことを確認
const users = await getUsers(source);
expect(users.length).toEqual(2);
});
it('管理者権限のあるアクセストークンを使用して、新規ユーザが追加される(role:Author; 暗号化無し)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<UsersService>(UsersService);
const adminExternalId = 'ADMIN0001';
const { account } = await makeTestAccount(
source,
{},
{ external_id: adminExternalId },
);
const { id: accountId } = account;
const name = 'test_user2';
const role = USER_ROLES.AUTHOR;
const email = 'test2@example.com';
const autoRenew = true;
const licenseAlert = true;
const notification = true;
const authorId = 'testID';
const encryption = false;
const prompt = true;
const externalId = '0001';
overrideAdB2cService(service, {
createUser: async (
_context: Context,
_email: string,
_password: string,
_username: string,
) => {
// ユーザー作成時に指定したパラメータが正しく渡されていることを確認
expect(email).toEqual(_email);
expect(name).toEqual(_username);
return { sub: externalId };
},
getUser: async () => {
return {
id: adminExternalId,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
expect(
await service.createUser(
makeContext('trackingId', 'requestId'),
adminExternalId,
name,
role,
email,
autoRenew,
notification,
authorId,
encryption,
undefined,
prompt,
),
).toEqual(undefined);
// 追加されたユーザーが正しくDBに登録されていることを確認
const user = await getUserFromExternalId(source, externalId);
expect(user).not.toBeNull();
expect(user?.account_id).toEqual(accountId);
expect(user?.role).toEqual(role);
expect(user?.author_id).toEqual(authorId);
expect(user?.email_verified).toEqual(false);
expect(user?.auto_renew).toEqual(autoRenew);
expect(user?.notification).toEqual(notification);
expect(user?.encryption).toEqual(encryption);
expect(user?.encryption_password).toBeNull();
expect(user?.prompt).toEqual(prompt);
// 他にユーザーが登録されていないことを確認
const users = await getUsers(source);
expect(users.length).toEqual(2);
});
it('管理者権限のあるアクセストークンを使用して、新規ユーザが追加される(role:Transcriptioninst)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<UsersService>(UsersService);
const adminExternalId = 'ADMIN0001';
const { account } = await makeTestAccount(
source,
{},
{ external_id: adminExternalId },
);
const { id: accountId } = account;
const name = 'test_user3';
const role = USER_ROLES.TYPIST;
const email = 'test3@example.com';
const autoRenew = true;
const licenseAlert = true;
const notification = true;
const externalId = '0001';
overrideAdB2cService(service, {
createUser: async (
_context: Context,
_email: string,
_password: string,
_username: string,
) => {
// ユーザー作成時に指定したパラメータが正しく渡されていることを確認
expect(email).toEqual(_email);
expect(name).toEqual(_username);
return { sub: externalId };
},
getUser: async () => {
return {
id: adminExternalId,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
expect(
await service.createUser(
makeContext('trackingId', 'requestId'),
adminExternalId,
name,
role,
email,
autoRenew,
notification,
),
).toEqual(undefined);
// 追加されたユーザーが正しくDBに登録されていることを確認
const user = await getUserFromExternalId(source, externalId);
expect(user).not.toBeNull();
expect(user?.account_id).toEqual(accountId);
expect(user?.role).toEqual(role);
expect(user?.author_id).toBeNull();
expect(user?.email_verified).toEqual(false);
expect(user?.auto_renew).toEqual(autoRenew);
expect(user?.notification).toEqual(notification);
expect(user?.encryption).toEqual(false);
expect(user?.encryption_password).toBeNull();
expect(user?.prompt).toEqual(false);
// 他にユーザーが登録されていないことを確認
const users = await getUsers(source);
expect(users.length).toEqual(2);
});
it('DBネットワークエラーとなる場合、リカバリ処理を実施し、ADB2Cに作成したユーザーを削除する', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<UsersService>(UsersService);
const b2cService = module.get<AdB2cService>(AdB2cService);
const adminExternalId = 'ADMIN0001';
await makeTestAccount(source, {}, { external_id: adminExternalId });
const name = 'test_user1';
const role = USER_ROLES.NONE;
const email = 'test1@example.com';
const autoRenew = true;
const licenseAlert = true;
const notification = true;
const externalId = '0001';
overrideAdB2cService(service, {
createUser: async (
_context: Context,
_email: string,
_password: string,
_username: string,
) => {
// ユーザー作成時に指定したパラメータが正しく渡されていることを確認
expect(email).toEqual(_email);
expect(name).toEqual(_username);
return { sub: externalId };
},
deleteUser: jest.fn(),
getUser: async () => {
return {
id: adminExternalId,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
// DBエラーを発生させる
overrideUsersRepositoryService(service, {
createNormalUser: async () => {
throw new Error('DB error');
},
});
try {
await service.createUser(
makeContext('trackingId', 'requestId'),
adminExternalId,
name,
role,
email,
autoRenew,
notification,
);
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
} else {
fail();
}
}
// ADB2Cに作成したユーザーを削除するメソッドが呼ばれていることを確認
expect(b2cService.deleteUser).toBeCalledWith(
externalId,
makeContext('trackingId', 'requestId'),
);
});
it('DBネットワークエラーとなる場合、リカバリ処理を実施されるが、そのリカバリ処理に失敗した場合、ADB2Cのユーザーは削除されない', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<UsersService>(UsersService);
const b2cService = module.get<AdB2cService>(AdB2cService);
const adminExternalId = 'ADMIN0001';
const { account } = await makeTestAccount(
source,
{},
{ external_id: adminExternalId },
);
const { id: accountId } = account;
const name = 'test_user1';
const role = USER_ROLES.NONE;
const email = 'test1@example.com';
const autoRenew = true;
const licenseAlert = true;
const notification = true;
const externalId = '0001';
overrideAdB2cService(service, {
createUser: async (
_context: Context,
_email: string,
_password: string,
_username: string,
) => {
// ユーザー作成時に指定したパラメータが正しく渡されていることを確認
expect(email).toEqual(_email);
expect(name).toEqual(_username);
return { sub: externalId };
},
deleteUser: jest.fn().mockRejectedValue(new Error('ADB2C error')),
getUser: async () => {
return {
id: adminExternalId,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
// DBエラーを発生させる
overrideUsersRepositoryService(service, {
createNormalUser: async () => {
throw new Error('DB error');
},
});
try {
await service.createUser(
makeContext('trackingId', 'requestId'),
adminExternalId,
name,
role,
email,
autoRenew,
notification,
);
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
} else {
fail();
}
}
// 新規ユーザーが登録されていないことを確認
const users = await getUsers(source);
expect(users.length).toEqual(1);
//アカウントIDがテスト用の管理者ユーザーのものであることを確認
expect(users[0].account_id).toEqual(accountId);
// ADB2Cに作成したユーザーを削除するメソッドが呼ばれていることを確認
expect(b2cService.deleteUser).toBeCalledWith(
externalId,
makeContext('trackingId', 'requestId'),
);
});
it('Azure ADB2Cでネットワークエラーとなる場合、エラーとなる。', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<UsersService>(UsersService);
const adminExternalId = 'ADMIN0001';
await makeTestAccount(source, {}, { external_id: adminExternalId });
const name = 'test_user1';
const role = USER_ROLES.NONE;
const email = 'test1@example.com';
const autoRenew = true;
const licenseAlert = true;
const notification = true;
overrideAdB2cService(service, {
createUser: async (
_context: Context,
_email: string,
_password: string,
_username: string,
) => {
// ユーザー作成時に指定したパラメータが正しく渡されていることを確認
expect(email).toEqual(_email);
expect(name).toEqual(_username);
throw new Error('ADB2C error');
},
});
overrideSendgridService(service, {});
try {
await service.createUser(
makeContext('trackingId', 'requestId'),
adminExternalId,
name,
role,
email,
autoRenew,
notification,
);
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
} else {
fail();
}
}
// ユーザーが登録されていないことを確認
const users = await getUsers(source);
expect(users.length).toEqual(1);
});
it('Azure AD B2C内でメールアドレスが重複している場合、エラーとなる。', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<UsersService>(UsersService);
const adminExternalId = 'ADMIN0001';
await makeTestAccount(source, {}, { external_id: adminExternalId });
const name = 'test_user1';
const role = USER_ROLES.NONE;
const email = 'test1@example.com';
const autoRenew = true;
const licenseAlert = true;
const notification = true;
overrideAdB2cService(service, {
createUser: async (
_context: Context,
_email: string,
_password: string,
_username: string,
) => {
// ユーザー作成時に指定したパラメータが正しく渡されていることを確認
expect(email).toEqual(_email);
expect(name).toEqual(_username);
// Conflictエラーを返す
return {
reason: 'email',
message: 'The email address is already in use by another account.',
};
},
});
overrideSendgridService(service, {});
try {
await service.createUser(
makeContext('trackingId', 'requestId'),
adminExternalId,
name,
role,
email,
autoRenew,
notification,
);
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010301'));
} else {
fail();
}
}
// ユーザーが登録されていないことを確認
const users = await getUsers(source);
expect(users.length).toEqual(1);
});
it('AuthorIDが重複している場合、エラーとなる。(AuthorID重複チェックでエラー)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<UsersService>(UsersService);
const adminExternalId = 'ADMIN0001';
await makeTestAccount(source, {}, { external_id: adminExternalId });
const name = 'test_user2';
const role = USER_ROLES.AUTHOR;
const autoRenew = true;
const licenseAlert = true;
const notification = true;
const authorId = 'testID';
const encryption = true;
const prompt = true;
const encryptionPassword = 'testPassword';
const email_1 = 'test_1@example.com';
const externalId_1 = '0001';
overrideAdB2cService(service, {
createUser: async (
_context: Context,
_email: string,
_password: string,
_username: string,
) => {
// ユーザー作成時に指定したパラメータが正しく渡されていることを確認
expect(email_1).toEqual(_email);
expect(name).toEqual(_username);
return { sub: externalId_1 };
},
getUser: async () => {
return {
id: adminExternalId,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
expect(
await service.createUser(
makeContext('trackingId', 'requestId'),
adminExternalId,
name,
role,
email_1,
autoRenew,
notification,
authorId,
encryption,
encryptionPassword,
prompt,
),
).toEqual(undefined);
{
// 他にユーザーが登録されていないことを確認
const users = await getUsers(source);
expect(users.length).toEqual(2);
}
// Azure Ad B2CのMockをユーザー2用に切り替える
const email_2 = 'test_1@example.com';
const externalId_2 = '0001';
overrideAdB2cService(service, {
createUser: async (
_context: Context,
_email: string,
_password: string,
_username: string,
) => {
// ユーザー作成時に指定したパラメータが正しく渡されていることを確認
expect(email_2).toEqual(_email);
expect(name).toEqual(_username);
return { sub: externalId_2 };
},
});
try {
await service.createUser(
makeContext('trackingId', 'requestId'),
adminExternalId,
name,
role,
email_2,
autoRenew,
notification,
authorId,
encryption,
encryptionPassword,
prompt,
);
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010302'));
} else {
fail();
}
}
// 新規にユーザーが登録されていないことを確認
{
const users = await getUsers(source);
expect(users.length).toEqual(2);
}
});
it('AuthorIDが重複している場合、エラー(insert失敗)となり、リカバリ処理が実行され、ADB2Cに追加したユーザーが削除される', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<UsersService>(UsersService);
const b2cService = module.get<AdB2cService>(AdB2cService);
const adminExternalId = 'ADMIN0001';
const { account } = await makeTestAccount(
source,
{},
{ external_id: adminExternalId },
);
const { id: accountId } = account;
const name = 'test_user2';
const role = USER_ROLES.AUTHOR;
const email = 'test2@example.com';
const autoRenew = true;
const licenseAlert = true;
const notification = true;
const authorId = 'testID';
const encryption = true;
const prompt = true;
const encryptionPassword = 'testPassword';
const externalId = '0001';
overrideAdB2cService(service, {
createUser: async (
_context: Context,
_email: string,
_password: string,
_username: string,
) => {
// ユーザー作成時に指定したパラメータが正しく渡されていることを確認
expect(email).toEqual(_email);
expect(name).toEqual(_username);
return { sub: externalId };
},
deleteUser: jest.fn(),
});
overrideSendgridService(service, {});
// AuthorIDのUNIQUE制約エラーを発生させる
overrideUsersRepositoryService(service, {
createNormalUser: async () => {
throw { code: 'ER_DUP_ENTRY' };
},
});
try {
await service.createUser(
makeContext('trackingId', 'requestId'),
adminExternalId,
name,
role,
email,
autoRenew,
notification,
authorId,
encryption,
encryptionPassword,
prompt,
);
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010302'));
} else {
fail();
}
}
// 新規にユーザーが登録されていないことを確認
const users = await getUsers(source);
expect(users.length).toEqual(1);
expect(users[0].account_id).toEqual(accountId);
// ADB2Cに作成したユーザーを削除するメソッドが呼ばれていることを確認
expect(b2cService.deleteUser).toBeCalledWith(
externalId,
makeContext('trackingId', 'requestId'),
);
});
it('メール送信に失敗した場合、リカバリ処理が実行され、ADB2C,DBのユーザーが削除される', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<UsersService>(UsersService);
const b2cService = module.get<AdB2cService>(AdB2cService);
const adminExternalId = 'ADMIN0001';
const { account } = await makeTestAccount(
source,
{},
{ external_id: adminExternalId },
);
const { id: accountId } = account;
const name = 'test_user1';
const role = USER_ROLES.NONE;
const email = 'test1@example.com';
const autoRenew = true;
const licenseAlert = true;
const notification = true;
const externalId = '0001';
overrideAdB2cService(service, {
createUser: async (
_context: Context,
_email: string,
_password: string,
_username: string,
) => {
// ユーザー作成時に指定したパラメータが正しく渡されていることを確認
expect(email).toEqual(_email);
expect(name).toEqual(_username);
return { sub: externalId };
},
deleteUser: jest.fn(),
});
overrideSendgridService(service, {});
try {
await service.createUser(
makeContext('trackingId', 'requestId'),
adminExternalId,
name,
role,
email,
autoRenew,
notification,
);
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
} else {
fail();
}
}
// 新規ユーザーが登録されていないことを確認
const users = await getUsers(source);
expect(users.length).toEqual(1);
//アカウントIDがテスト用の管理者ユーザーのものであることを確認
expect(users[0].account_id).toEqual(accountId);
// ADB2Cに作成したユーザーを削除するメソッドが呼ばれていることを確認
expect(b2cService.deleteUser).toBeCalledWith(
externalId,
makeContext('trackingId', 'requestId'),
);
});
it('メール送信に失敗した場合、リカバリ処理が実行されるが、そのリカバリ処理に失敗した場合、ADB2C,DBのユーザーが削除されない', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const service = module.get<UsersService>(UsersService);
const b2cService = module.get<AdB2cService>(AdB2cService);
const adminExternalId = 'ADMIN0001';
await makeTestAccount(source, {}, { external_id: adminExternalId });
const name = 'test_user1';
const role = USER_ROLES.NONE;
const email = 'test1@example.com';
const autoRenew = true;
const licenseAlert = true;
const notification = true;
const externalId = '0001';
overrideAdB2cService(service, {
createUser: async (
_context: Context,
_email: string,
_password: string,
_username: string,
) => {
// ユーザー作成時に指定したパラメータが正しく渡されていることを確認
expect(email).toEqual(_email);
expect(name).toEqual(_username);
return { sub: externalId };
},
deleteUser: jest.fn().mockRejectedValue(new Error()),
});
overrideSendgridService(service, {
sendMail: async () => {
throw new Error();
},
});
overrideUsersRepositoryService(service, {
deleteNormalUser: async () => {
throw new Error();
},
});
try {
await service.createUser(
makeContext('trackingId', 'requestId'),
adminExternalId,
name,
role,
email,
autoRenew,
notification,
);
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
} else {
fail();
}
}
// リカバリ処理が失敗したため、DBのユーザーが削除されないことを確認
const users = await getUsers(source);
expect(users.length).toEqual(2);
// ADB2Cに作成したユーザーを削除するメソッドが呼ばれていることを確認
expect(b2cService.deleteUser).toBeCalledWith(
externalId,
makeContext('trackingId', 'requestId'),
);
});
});
describe('UsersService.getUsers', () => {
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が行われるため注意
logger: new TestLogger('none'),
logging: true,
});
return await s.initialize();
})();
}
});
beforeEach(async () => {
if (source) {
await truncateAllTable(source);
}
});
afterAll(async () => {
await source?.destroy();
source = null;
});
it('ユーザーの一覧を取得できる(ライセンス未割当)', async () => {
const adb2cParam = makeDefaultAdB2cMockValue();
if (!source) fail();
const module = await makeTestingModuleWithAdb2c(source, adb2cParam);
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,
external_id: 'external_id1',
role: 'author',
author_id: 'AUTHOR_ID',
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
});
await createUserGroup(source, accountId, 'group1', [typistUserId]);
const { id: noneUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id3',
role: 'none',
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
});
const service = module.get<UsersService>(UsersService);
const expectedUsers = [
{
id: authorUserId,
name: 'test1',
role: 'author',
authorId: 'AUTHOR_ID',
typistGroupName: [],
email: 'test1@mail.com',
emailVerified: true,
autoRenew: true,
notification: true,
encryption: false,
prompt: false,
expiration: undefined,
remaining: undefined,
licenseStatus: USER_LICENSE_EXPIRY_STATUS.NO_LICENSE,
},
{
id: typistUserId,
name: 'test2',
role: 'typist',
authorId: undefined,
typistGroupName: ['group1'],
email: 'test2@mail.com',
emailVerified: true,
autoRenew: true,
notification: true,
encryption: false,
prompt: false,
expiration: undefined,
remaining: undefined,
licenseStatus: USER_LICENSE_EXPIRY_STATUS.NO_LICENSE,
},
{
id: noneUserId,
name: 'test3',
role: 'none',
authorId: undefined,
typistGroupName: [],
email: 'test3@mail.com',
emailVerified: true,
autoRenew: true,
notification: true,
encryption: false,
prompt: false,
expiration: undefined,
remaining: undefined,
licenseStatus: USER_LICENSE_EXPIRY_STATUS.NO_LICENSE,
},
];
const context = makeContext(`uuidv4`, 'requestId');
expect(await service.getUsers(context, externalId_author)).toEqual(
expectedUsers,
);
});
it('ユーザーの一覧を取得できること(ライセンス割当済み)', async () => {
const adb2cParam = makeDefaultAdB2cMockValue();
if (!source) fail();
const module = await makeTestingModuleWithAdb2c(source, adb2cParam);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { id: user1, external_id: external_id1 } = await makeTestUser(
source,
{
account_id: accountId,
external_id: 'external_id1',
role: 'author',
author_id: 'AUTHOR_ID1',
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
},
);
const { id: user2 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id2',
role: 'author',
author_id: 'AUTHOR_ID2',
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
});
const { id: user3 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id3',
role: 'author',
author_id: 'AUTHOR_ID3',
auto_renew: false,
encryption: false,
encryption_password: undefined,
prompt: false,
});
const date1 = new Date();
date1.setDate(date1.getDate() + LICENSE_EXPIRATION_THRESHOLD_DAYS + 1);
const date2 = new Date();
date2.setDate(date2.getDate() + LICENSE_EXPIRATION_THRESHOLD_DAYS);
const date3 = new Date();
date3.setDate(date3.getDate() + LICENSE_EXPIRATION_THRESHOLD_DAYS - 1);
await createLicense(source, accountId, user1, date1);
await createLicense(source, accountId, user2, date2);
await createLicense(source, accountId, user3, date3);
const service = module.get<UsersService>(UsersService);
const expectedUsers = [
{
id: user1,
name: 'test1',
role: 'author',
authorId: 'AUTHOR_ID1',
typistGroupName: [],
email: 'test1@mail.com',
emailVerified: true,
autoRenew: true,
notification: true,
encryption: false,
prompt: false,
expiration: `${date1.getFullYear()}/${
date1.getMonth() + 1
}/${date1.getDate()}`,
remaining: LICENSE_EXPIRATION_THRESHOLD_DAYS + 1,
licenseStatus: USER_LICENSE_EXPIRY_STATUS.NORMAL,
},
{
id: user2,
name: 'test2',
role: 'author',
authorId: 'AUTHOR_ID2',
typistGroupName: [],
email: 'test2@mail.com',
emailVerified: true,
autoRenew: true,
notification: true,
encryption: false,
prompt: false,
expiration: `${date2.getFullYear()}/${
date2.getMonth() + 1
}/${date2.getDate()}`,
remaining: LICENSE_EXPIRATION_THRESHOLD_DAYS,
licenseStatus: USER_LICENSE_EXPIRY_STATUS.RENEW,
},
{
id: user3,
name: 'test3',
role: 'author',
authorId: 'AUTHOR_ID3',
typistGroupName: [],
email: 'test3@mail.com',
emailVerified: true,
autoRenew: false,
notification: true,
encryption: false,
prompt: false,
expiration: `${date3.getFullYear()}/${
date3.getMonth() + 1
}/${date3.getDate()}`,
remaining: LICENSE_EXPIRATION_THRESHOLD_DAYS - 1,
licenseStatus: USER_LICENSE_EXPIRY_STATUS.ALERT,
},
];
const context = makeContext(`uuidv4`, 'requestId');
expect(await service.getUsers(context, external_id1)).toEqual(
expectedUsers,
);
});
it('DBからのユーザーの取得に失敗した場合、エラーとなる', async () => {
const adb2cParam = makeDefaultAdB2cMockValue();
if (!source) fail();
const module = await makeTestingModuleWithAdb2c(source, adb2cParam);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id1',
role: 'author',
author_id: 'AUTHOR_ID',
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
});
const context = makeContext(`uuidv4`, 'requestId');
const service = module.get<UsersService>(UsersService);
await expect(
service.getUsers(context, 'externalId_failed'),
).rejects.toEqual(
new HttpException(makeErrorResponse('E009999'), HttpStatus.NOT_FOUND),
);
});
it('ADB2Cからのユーザーの取得に失敗した場合、エラーとなる', async () => {
const adb2cParam = makeDefaultAdB2cMockValue();
adb2cParam.getUsers = new Error('ADB2C error');
if (!source) fail();
const module = await makeTestingModuleWithAdb2c(source, adb2cParam);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: externalId_author } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id1',
role: 'author',
author_id: 'AUTHOR_ID',
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
});
const context = makeContext(`uuidv4`, 'requestId');
const service = module.get<UsersService>(UsersService);
await expect(service.getUsers(context, externalId_author)).rejects.toEqual(
new HttpException(makeErrorResponse('E009999'), HttpStatus.NOT_FOUND),
);
});
});
describe('UsersService.updateSortCriteria', () => {
it('ソート条件を変更できる', async () => {
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
const licensesRepositoryMockValue = null;
const adb2cParam = makeDefaultAdB2cMockValue();
const sendgridMockValue = makeDefaultSendGridlValue();
const configMockValue = makeDefaultConfigValue();
const sortCriteriaRepositoryMockValue =
makeDefaultSortCriteriaRepositoryMockValue();
const service = await makeUsersServiceMock(
usersRepositoryMockValue,
licensesRepositoryMockValue,
adb2cParam,
sendgridMockValue,
configMockValue,
sortCriteriaRepositoryMockValue,
);
const context = makeContext(`uuidv4`, 'requestId');
expect(
await service.updateSortCriteria(
context,
'AUTHOR_ID',
'ASC',
'external_id',
),
).toEqual(undefined);
});
it('ユーザー情報が存在せず、ソート条件を変更できない', async () => {
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
const licensesRepositoryMockValue = null;
const adb2cParam = makeDefaultAdB2cMockValue();
const sendgridMockValue = makeDefaultSendGridlValue();
const configMockValue = makeDefaultConfigValue();
const sortCriteriaRepositoryMockValue =
makeDefaultSortCriteriaRepositoryMockValue();
usersRepositoryMockValue.findUserByExternalId = new Error('user not found');
const service = await makeUsersServiceMock(
usersRepositoryMockValue,
licensesRepositoryMockValue,
adb2cParam,
sendgridMockValue,
configMockValue,
sortCriteriaRepositoryMockValue,
);
const context = makeContext(`uuidv4`, 'requestId');
await expect(
service.updateSortCriteria(context, 'AUTHOR_ID', 'ASC', 'external_id'),
).rejects.toEqual(
new HttpException(
makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR,
),
);
});
it('ソート条件が存在せず、ソート条件を変更できない', async () => {
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
const licensesRepositoryMockValue = null;
const adb2cParam = makeDefaultAdB2cMockValue();
const sendgridMockValue = makeDefaultSendGridlValue();
const configMockValue = makeDefaultConfigValue();
const sortCriteriaRepositoryMockValue =
makeDefaultSortCriteriaRepositoryMockValue();
sortCriteriaRepositoryMockValue.updateSortCriteria = new Error(
'sort criteria not found',
);
const service = await makeUsersServiceMock(
usersRepositoryMockValue,
licensesRepositoryMockValue,
adb2cParam,
sendgridMockValue,
configMockValue,
sortCriteriaRepositoryMockValue,
);
const context = makeContext(`uuidv4`, 'requestId');
await expect(
service.updateSortCriteria(context, 'AUTHOR_ID', 'ASC', 'external_id'),
).rejects.toEqual(
new HttpException(
makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR,
),
);
});
});
describe('UsersService.getSortCriteria', () => {
it('ソート条件を取得できる', async () => {
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
const licensesRepositoryMockValue = null;
const adb2cParam = makeDefaultAdB2cMockValue();
const sendgridMockValue = makeDefaultSendGridlValue();
const configMockValue = makeDefaultConfigValue();
const sortCriteriaRepositoryMockValue =
makeDefaultSortCriteriaRepositoryMockValue();
const service = await makeUsersServiceMock(
usersRepositoryMockValue,
licensesRepositoryMockValue,
adb2cParam,
sendgridMockValue,
configMockValue,
sortCriteriaRepositoryMockValue,
);
const context = makeContext(`uuidv4`, 'requestId');
expect(await service.getSortCriteria(context, 'external_id')).toEqual({
direction: 'ASC',
paramName: 'JOB_NUMBER',
});
});
it('ソート条件が存在せず、ソート条件を取得できない', async () => {
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
const licensesRepositoryMockValue = null;
const adb2cParam = makeDefaultAdB2cMockValue();
const sendgridMockValue = makeDefaultSendGridlValue();
const configMockValue = makeDefaultConfigValue();
const sortCriteriaRepositoryMockValue =
makeDefaultSortCriteriaRepositoryMockValue();
sortCriteriaRepositoryMockValue.getSortCriteria = new Error(
'sort criteria not found',
);
const service = await makeUsersServiceMock(
usersRepositoryMockValue,
licensesRepositoryMockValue,
adb2cParam,
sendgridMockValue,
configMockValue,
sortCriteriaRepositoryMockValue,
);
const context = makeContext(`uuidv4`, 'requestId');
await expect(
service.getSortCriteria(context, 'external_id'),
).rejects.toEqual(
new HttpException(
makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR,
),
);
});
it('DBから取得した値が不正だった場合、エラーとなる', async () => {
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
const licensesRepositoryMockValue = null;
const adb2cParam = makeDefaultAdB2cMockValue();
const sendgridMockValue = makeDefaultSendGridlValue();
const configMockValue = makeDefaultConfigValue();
const sortCriteriaRepositoryMockValue =
makeDefaultSortCriteriaRepositoryMockValue();
sortCriteriaRepositoryMockValue.getSortCriteria = {
id: 1,
direction: 'AAA',
parameter: 'BBBBB',
user_id: 1,
};
const service = await makeUsersServiceMock(
usersRepositoryMockValue,
licensesRepositoryMockValue,
adb2cParam,
sendgridMockValue,
configMockValue,
sortCriteriaRepositoryMockValue,
);
const context = makeContext(`uuidv4`, 'requestId');
await expect(
service.getSortCriteria(context, 'external_id'),
).rejects.toEqual(
new HttpException(
makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR,
),
);
});
});
describe('UsersService.updateUser', () => {
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が行われるため注意
logger: new TestLogger('none'),
logging: true,
});
return await s.initialize();
})();
}
});
beforeEach(async () => {
if (source) {
await truncateAllTable(source);
}
});
afterAll(async () => {
await source?.destroy();
source = null;
});
it('ユーザー情報を更新できるNone', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: external_id } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
});
const { id: user1 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id1',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
});
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const context = makeContext(`uuidv4`, 'requestId');
expect(
await service.updateUser(
context,
external_id,
user1,
USER_ROLES.NONE,
undefined,
false,
false,
undefined,
undefined,
undefined,
),
).toEqual(undefined);
const createdUser = await getUser(source, user1);
expect(createdUser?.id).toBe(user1);
expect(createdUser?.role).toBe(USER_ROLES.NONE);
expect(createdUser?.author_id).toBeNull();
expect(createdUser?.auto_renew).toBe(false);
expect(createdUser?.notification).toBe(false);
expect(createdUser?.encryption).toBe(false);
expect(createdUser?.encryption_password).toBeNull();
expect(createdUser?.prompt).toBe(false);
});
it('ユーザー情報を更新できるTypist', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: external_id } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
});
const { id: user1 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id1',
role: USER_ROLES.TYPIST,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
});
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const context = makeContext(`uuidv4`, 'requestId');
expect(
await service.updateUser(
context,
external_id,
user1,
USER_ROLES.TYPIST,
undefined,
false,
false,
undefined,
undefined,
undefined,
),
).toEqual(undefined);
const createdUser = await getUser(source, user1);
expect(createdUser?.id).toBe(user1);
expect(createdUser?.role).toBe(USER_ROLES.TYPIST);
expect(createdUser?.author_id).toBeNull();
expect(createdUser?.auto_renew).toBe(false);
expect(createdUser?.notification).toBe(false);
expect(createdUser?.encryption).toBe(false);
expect(createdUser?.encryption_password).toBeNull();
expect(createdUser?.prompt).toBe(false);
});
it('ユーザー情報を更新できるAuthor', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: external_id } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
});
const { id: user1 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id1',
role: USER_ROLES.AUTHOR,
author_id: undefined,
auto_renew: true,
encryption: true,
encryption_password: 'password',
prompt: true,
});
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const context = makeContext(`uuidv4`, 'requestId');
expect(
await service.updateUser(
context,
external_id,
user1,
USER_ROLES.AUTHOR,
'AUTHOR_ID',
false,
false,
true,
'new_password',
true,
),
).toEqual(undefined);
const createdUser = await getUser(source, user1);
expect(createdUser?.id).toBe(user1);
expect(createdUser?.role).toBe(USER_ROLES.AUTHOR);
expect(createdUser?.author_id).toBe('AUTHOR_ID');
expect(createdUser?.auto_renew).toBe(false);
expect(createdUser?.notification).toBe(false);
expect(createdUser?.encryption).toBe(true);
expect(createdUser?.encryption_password).toBe('new_password');
expect(createdUser?.prompt).toBe(true);
});
it('ユーザーのRoleを更新できるNone⇒Typist', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: external_id } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
});
const { id: user1 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id1',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
});
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const context = makeContext(`uuidv4`, 'requestId');
expect(
await service.updateUser(
context,
external_id,
user1,
USER_ROLES.TYPIST,
undefined,
false,
false,
undefined,
undefined,
undefined,
),
).toEqual(undefined);
const createdUser = await getUser(source, user1);
expect(createdUser?.id).toBe(user1);
expect(createdUser?.role).toBe(USER_ROLES.TYPIST);
expect(createdUser?.author_id).toBeNull();
expect(createdUser?.auto_renew).toBe(false);
expect(createdUser?.notification).toBe(false);
expect(createdUser?.encryption).toBe(false);
expect(createdUser?.encryption_password).toBeNull();
expect(createdUser?.prompt).toBe(false);
});
it('ユーザーのRoleを更新できるNone⇒Author', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: external_id } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
});
const { id: user1 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id1',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
});
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const context = makeContext(`uuidv4`, 'requestId');
expect(
await service.updateUser(
context,
external_id,
user1,
USER_ROLES.AUTHOR,
'AUTHOR_ID',
false,
false,
false,
undefined,
false,
),
).toEqual(undefined);
const createdUser = await getUser(source, user1);
expect(createdUser?.id).toBe(user1);
expect(createdUser?.role).toBe(USER_ROLES.AUTHOR);
expect(createdUser?.author_id).toBe('AUTHOR_ID');
expect(createdUser?.auto_renew).toBe(false);
expect(createdUser?.notification).toBe(false);
expect(createdUser?.encryption).toBe(false);
expect(createdUser?.encryption_password).toBeNull();
expect(createdUser?.prompt).toBe(false);
});
it('None以外からRoleを変更した場合、エラーとなるTypist⇒None', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: external_id } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
});
const { id: user1 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id1',
role: USER_ROLES.TYPIST,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
});
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const context = makeContext(`uuidv4`, 'requestId');
await expect(
service.updateUser(
context,
external_id,
user1,
USER_ROLES.NONE,
undefined,
false,
false,
undefined,
undefined,
undefined,
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010207'), HttpStatus.BAD_REQUEST),
);
});
it('Authorがパスワードundefinedで渡されたとき、元のパスワードを維持するEncryptionがtrue', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: external_id } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
});
const { id: user1 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id1',
role: USER_ROLES.AUTHOR,
author_id: 'AUTHOR_ID',
auto_renew: true,
encryption: true,
encryption_password: 'password',
prompt: true,
});
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const context = makeContext(`uuidv4`, 'requestId');
expect(
await service.updateUser(
context,
external_id,
user1,
USER_ROLES.AUTHOR,
'AUTHOR_ID',
false,
false,
true,
undefined,
true,
),
).toEqual(undefined);
const createdUser = await getUser(source, user1);
expect(createdUser?.id).toBe(user1);
expect(createdUser?.role).toBe(USER_ROLES.AUTHOR);
expect(createdUser?.author_id).toBe('AUTHOR_ID');
expect(createdUser?.auto_renew).toBe(false);
expect(createdUser?.notification).toBe(false);
expect(createdUser?.encryption).toBe(true);
expect(createdUser?.encryption_password).toBe('password');
expect(createdUser?.prompt).toBe(true);
});
it('Authorが暗号化なしで更新した場合、パスワードをNULLにするEncryptionがfalse', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: external_id } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
});
const { id: user1 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id1',
role: USER_ROLES.AUTHOR,
author_id: 'AUTHOR_ID',
auto_renew: true,
encryption: false,
encryption_password: 'password',
prompt: true,
});
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const context = makeContext(`uuidv4`, 'requestId');
expect(
await service.updateUser(
context,
external_id,
user1,
USER_ROLES.AUTHOR,
'AUTHOR_ID',
false,
false,
false,
'password',
true,
),
).toEqual(undefined);
const createdUser = await getUser(source, user1);
expect(createdUser?.id).toBe(user1);
expect(createdUser?.role).toBe(USER_ROLES.AUTHOR);
expect(createdUser?.author_id).toBe('AUTHOR_ID');
expect(createdUser?.auto_renew).toBe(false);
expect(createdUser?.notification).toBe(false);
expect(createdUser?.encryption).toBe(false);
expect(createdUser?.encryption_password).toBeNull();
expect(createdUser?.prompt).toBe(true);
});
it('AuthorのDBにパスワードが設定されていない場合、パスワードundefinedでわたすとエラーとなるEncryptionがtrue', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: external_id } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
});
const { id: user1 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id1',
role: USER_ROLES.AUTHOR,
author_id: 'AUTHOR_ID',
auto_renew: true,
encryption: true,
encryption_password: undefined,
prompt: true,
});
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const context = makeContext(`uuidv4`, 'requestId');
await expect(
service.updateUser(
context,
external_id,
user1,
USER_ROLES.AUTHOR,
'AUTHOR_ID',
false,
false,
true,
undefined,
true,
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010208'), HttpStatus.BAD_REQUEST),
);
});
it('AuthorIdが既存のユーザーと重複した場合、エラーとなる', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const { external_id: external_id } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id',
role: USER_ROLES.NONE,
author_id: undefined,
auto_renew: true,
encryption: false,
encryption_password: undefined,
prompt: false,
});
const { id: user1 } = await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id1',
role: USER_ROLES.AUTHOR,
author_id: 'AUTHOR_ID1',
auto_renew: true,
encryption: true,
encryption_password: 'password',
prompt: true,
});
await makeTestUser(source, {
account_id: accountId,
external_id: 'external_id2',
role: USER_ROLES.AUTHOR,
author_id: 'AUTHOR_ID2',
auto_renew: true,
encryption: true,
encryption_password: 'password',
prompt: true,
});
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const context = makeContext(`uuidv4`, 'requestId');
await expect(
service.updateUser(
context,
external_id,
user1,
USER_ROLES.AUTHOR,
'AUTHOR_ID2',
false,
false,
true,
undefined,
true,
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010302'), HttpStatus.BAD_REQUEST),
);
});
});
describe('UsersService.updateAcceptedVersion', () => {
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が行われるため注意
logger: new TestLogger('none'),
logging: true,
});
return await s.initialize();
})();
}
});
beforeEach(async () => {
if (source) {
await truncateAllTable(source);
}
});
afterAll(async () => {
await source?.destroy();
source = null;
});
it('同意済み利用規約バージョンを更新できる(第五)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { admin } = await makeTestAccount(source, {
tier: 5,
});
const context = makeContext(uuidv4(), 'requestId');
const service = module.get<UsersService>(UsersService);
await service.updateAcceptedVersion(
context,
admin.external_id,
'v2.0',
'v2.0',
);
const user = await getUser(source, admin.id);
expect(user?.accepted_eula_version).toBe('v2.0');
});
it('同意済み利用規約バージョンを更新できる(第一~第四)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { admin } = await makeTestAccount(source, {
tier: 4,
});
const context = makeContext(uuidv4(), 'requestId');
const service = module.get<UsersService>(UsersService);
await service.updateAcceptedVersion(
context,
admin.external_id,
'v2.0',
'v2.0',
'v3.0',
);
const user = await getUser(source, admin.id);
expect(user?.accepted_eula_version).toBe('v2.0');
expect(user?.accepted_dpa_version).toBe('v3.0');
});
it('パラメータが不在のときエラーとなる(第一~第四)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { admin } = await makeTestAccount(source, {
tier: 4,
});
const context = makeContext(uuidv4(), 'requestId');
const service = module.get<UsersService>(UsersService);
await expect(
service.updateAcceptedVersion(
context,
admin.external_id,
'v2.0',
'v2.0',
undefined,
),
).rejects.toEqual(
new HttpException(makeErrorResponse('E010001'), HttpStatus.BAD_REQUEST),
);
});
});
describe('UsersService.getUserName', () => {
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が行われるため注意
logger: new TestLogger('none'),
logging: true,
});
return await s.initialize();
})();
}
});
beforeEach(async () => {
if (source) {
await truncateAllTable(source);
}
});
afterAll(async () => {
await source?.destroy();
source = null;
});
it('ユーザーが存在しない場合は、ユーザー未存在エラー', async () => {
if (!source) fail();
try {
const module = await makeTestingModule(source);
if (!module) fail();
const context = makeContext(uuidv4(), 'requestId');
const service = module.get<UsersService>(UsersService);
await service.getUserName(context, 'external_id');
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010204'));
} else {
fail();
}
}
});
});
describe('UsersService.getRelations', () => {
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が行われるため注意
logger: new TestLogger('none'),
logging: true,
});
return await s.initialize();
})();
}
});
beforeEach(async () => {
if (source) {
await truncateAllTable(source);
}
});
afterAll(async () => {
await source?.destroy();
source = null;
});
it('ユーザー関連情報を取得できるAuthor', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account } = await makeTestAccount(source, {
tier: 5,
});
const { id: user1, external_id } = await makeTestUser(source, {
account_id: account.id,
role: USER_ROLES.AUTHOR,
author_id: 'AUTHOR_1',
encryption: true,
encryption_password: 'password',
prompt: true,
});
const { id: user2 } = await makeTestUser(source, {
account_id: account.id,
role: USER_ROLES.AUTHOR,
author_id: 'AUTHOR_2',
});
await makeTestUser(source, {
account_id: account.id,
role: USER_ROLES.AUTHOR,
author_id: 'AUTHOR_3',
email_verified: false,
});
const worktype1 = await createWorktype(
source,
account.id,
'worktypeB',
undefined,
true,
);
await createOptionItems(source, worktype1.id);
const worktype2 = await createWorktype(source, account.id, 'worktypeC');
await createOptionItems(source, worktype2.id);
const worktype3 = await createWorktype(source, account.id, 'worktypeA');
await createOptionItems(source, worktype3.id);
await createWorkflow(source, account.id, user1, worktype1.id);
await createWorkflow(source, account.id, user1, worktype2.id);
await createWorkflow(source, account.id, user1, worktype3.id);
await createWorkflow(source, account.id, user1);
await createWorkflow(source, account.id, user2, worktype1.id);
// 作成したデータを確認
{
const workflows = await getWorkflows(source, account.id);
workflows.sort((a, b) => a.id - b.id);
expect(workflows.length).toBe(5);
expect(workflows[0].worktype_id).toBe(worktype1.id);
expect(workflows[0].author_id).toBe(user1);
expect(workflows[1].worktype_id).toBe(worktype2.id);
expect(workflows[1].author_id).toBe(user1);
expect(workflows[2].worktype_id).toBe(worktype3.id);
expect(workflows[2].author_id).toBe(user1);
expect(workflows[3].worktype_id).toBe(null);
expect(workflows[3].author_id).toBe(user1);
expect(workflows[4].worktype_id).toBe(worktype1.id);
expect(workflows[4].author_id).toBe(user2);
}
const context = makeContext(external_id, 'requestId');
const service = module.get<UsersService>(UsersService);
const relations = await service.getRelations(context, external_id);
// レスポンスを確認
{
expect(relations.authorId).toBe('AUTHOR_1');
expect(relations.authorIdList.length).toBe(2);
expect(relations.authorIdList[0]).toBe('AUTHOR_1');
expect(relations.authorIdList[1]).toBe('AUTHOR_2');
const workTypeList = relations.workTypeList;
expect(relations.workTypeList.length).toBe(3);
// Workflowの作成順ではなくcustom_worktype_idの昇順で取得するためWorkTypeListの先頭はworktype3
expect(workTypeList[0].workTypeId).toBe(worktype3.custom_worktype_id);
expect(workTypeList[0].optionItemList.length).toBe(10);
expect(workTypeList[0].optionItemList[0].label).toBe('');
expect(workTypeList[0].optionItemList[0].initialValueType).toBe(2);
expect(workTypeList[0].optionItemList[0].defaultValue).toBe('');
expect(workTypeList[1].workTypeId).toBe(worktype1.custom_worktype_id);
expect(workTypeList[1].optionItemList.length).toBe(10);
expect(workTypeList[2].workTypeId).toBe(worktype2.custom_worktype_id);
expect(workTypeList[2].optionItemList.length).toBe(10);
expect(relations.isEncrypted).toBe(true);
expect(relations.encryptionPassword).toBe('password');
expect(relations.activeWorktype).toBe(worktype1.custom_worktype_id);
expect(relations.audioFormat).toBe(USER_AUDIO_FORMAT);
expect(relations.prompt).toBe(true);
}
});
it('ユーザー関連情報を取得できるAuthor以外', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account } = await makeTestAccount(source, {
tier: 5,
});
const { external_id } = await makeTestUser(source, {
account_id: account.id,
role: USER_ROLES.TYPIST,
encryption: false,
prompt: false,
});
const { id: user2 } = await makeTestUser(source, {
account_id: account.id,
role: USER_ROLES.AUTHOR,
author_id: 'AUTHOR_2',
});
const worktype1 = await createWorktype(source, account.id, 'worktype1');
await createOptionItems(source, worktype1.id);
await createWorkflow(source, account.id, user2, worktype1.id);
// 作成したデータを確認
{
const workflows = await getWorkflows(source, account.id);
expect(workflows.length).toBe(1);
expect(workflows[0].worktype_id).toBe(worktype1.id);
expect(workflows[0].author_id).toBe(user2);
}
const context = makeContext(external_id, 'requestId');
const service = module.get<UsersService>(UsersService);
const relations = await service.getRelations(context, external_id);
// レスポンスを確認
{
expect(relations.authorId).toBe(undefined);
expect(relations.authorIdList.length).toBe(1);
expect(relations.authorIdList[0]).toBe('AUTHOR_2');
expect(relations.workTypeList.length).toBe(0);
expect(relations.isEncrypted).toBe(false);
expect(relations.encryptionPassword).toBe(undefined);
expect(relations.activeWorktype).toBe('');
expect(relations.audioFormat).toBe(USER_AUDIO_FORMAT);
expect(relations.prompt).toBe(false);
}
});
it('ユーザーが存在しない場合は、ユーザー未存在エラー', async () => {
if (!source) fail();
try {
const module = await makeTestingModule(source);
if (!module) fail();
const context = makeContext(uuidv4(), 'requestId');
const service = module.get<UsersService>(UsersService);
await service.getRelations(context, 'external_id');
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010204'));
} else {
fail();
}
}
});
});
describe('UsersService.deleteUser', () => {
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が行われるため注意
logger: new TestLogger('none'),
logging: true,
});
return await s.initialize();
})();
}
});
beforeEach(async () => {
if (source) {
await truncateAllTable(source);
}
});
afterAll(async () => {
await source?.destroy();
source = null;
});
it('ユーザーを削除できる(Author)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source, {
tier: 5,
});
const { id: user1, external_id } = await makeTestUser(source, {
account_id: account.id,
role: USER_ROLES.AUTHOR,
author_id: 'AUTHOR_1',
});
const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`, 'requestId');
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
{
id: external_id,
displayName: 'user1',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user1@example.com',
},
],
},
];
},
getUser: async () => {
return {
id: admin.external_id,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
// 現在日付を作成
const now = new Date();
await service.deleteUser(context, user1, now);
// ユーザーが削除されたことを確認
{
const user = await getUser(source, user1);
expect(user).toBeNull();
// ユーザアーカイブが作成されたことを確認
const userArchive = await getUserArchive(source);
expect(userArchive[0].external_id).toBe(external_id);
}
});
it('ユーザーを削除できる(Typist)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source, {
tier: 5,
});
const { id: user1, external_id } = await makeTestUser(source, {
account_id: account.id,
role: USER_ROLES.TYPIST,
});
const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`, 'requestId');
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
{
id: external_id,
displayName: 'user1',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user1@example.com',
},
],
},
];
},
getUser: async () => {
return {
id: admin.external_id,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
// 現在日付を作成
const now = new Date();
await service.deleteUser(context, user1, now);
// ユーザーが削除されたことを確認
{
const user = await getUser(source, user1);
expect(user).toBeNull();
// ユーザアーカイブが作成されたことを確認
const userArchive = await getUserArchive(source);
expect(userArchive[0].external_id).toBe(external_id);
}
});
it('存在しないユーザは削除できない', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source, {
tier: 5,
});
const { external_id } = await makeTestUser(source, {
account_id: account.id,
role: USER_ROLES.AUTHOR,
});
const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`, 'requestId');
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
{
id: external_id,
displayName: 'user1',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user1@example.com',
},
],
},
];
},
getUser: async () => {
return {
id: admin.external_id,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
// 現在日付を作成
const now = new Date();
try {
await service.deleteUser(context, 100, now);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E014001'));
} else {
fail();
}
}
});
it('管理者ユーザは削除できない', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source, {
tier: 5,
});
const { external_id } = await makeTestUser(source, {
account_id: account.id,
role: USER_ROLES.AUTHOR,
});
const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`, 'requestId');
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
{
id: external_id,
displayName: 'user1',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user1@example.com',
},
],
},
];
},
getUser: async () => {
return {
id: admin.external_id,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
// 現在日付を作成
const now = new Date();
try {
await service.deleteUser(context, admin.id, now);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E014002'));
} else {
fail();
}
}
});
it('WorkFlowに割り当てられているユーザ(Author)は削除できない', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source, {
tier: 5,
});
const { id: user1, external_id } = await makeTestUser(source, {
account_id: account.id,
role: USER_ROLES.AUTHOR,
});
const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`, 'requestId');
const worktype1 = await createWorktype(
source,
account.id,
'worktype1',
undefined,
true,
);
await createOptionItems(source, worktype1.id);
await createWorkflow(source, account.id, user1, worktype1.id);
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
{
id: external_id,
displayName: 'user1',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user1@example.com',
},
],
},
];
},
getUser: async () => {
return {
id: admin.external_id,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
try {
// 現在日付を作成
const now = new Date();
await service.deleteUser(context, user1, now);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E014003'));
} else {
fail();
}
}
});
it('WorkFlowに割り当てられているユーザ(Typist)は削除できない', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source, {
tier: 5,
});
const { id: user1, external_id } = await makeTestUser(source, {
account_id: account.id,
role: USER_ROLES.AUTHOR,
});
const { id: user2, external_id: external_id2 } = await makeTestUser(
source,
{
account_id: account.id,
role: USER_ROLES.TYPIST,
},
);
const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`, 'requestId');
const worktype1 = await createWorktype(
source,
account.id,
'worktype1',
undefined,
true,
);
await createOptionItems(source, worktype1.id);
const workflow1 = await createWorkflow(
source,
account.id,
user1,
worktype1.id,
);
await createWorkflowTypist(source, workflow1.id, user2);
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
{
id: external_id,
displayName: 'user1',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user1@example.com',
},
],
},
{
id: external_id2,
displayName: 'user2',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user2@example.com',
},
],
},
];
},
getUser: async () => {
return {
id: admin.external_id,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
try {
// 現在日付を作成
const now = new Date();
await service.deleteUser(context, user2, now);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E014004'));
} else {
fail();
}
}
});
it('ユーザグループに所属しているユーザは削除できない', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source, {
tier: 5,
});
const { id: user1, external_id } = await makeTestUser(source, {
account_id: account.id,
role: USER_ROLES.AUTHOR,
});
const { id: user2, external_id: external_id2 } = await makeTestUser(
source,
{
account_id: account.id,
role: USER_ROLES.TYPIST,
},
);
const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`, 'requestId');
// ユーザグループを作成
const userGroup = await createUserGroup(source, account.id, 'userGroup', [
user1,
user2,
]);
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
{
id: external_id,
displayName: 'user1',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user1@example.com',
},
],
},
{
id: external_id2,
displayName: 'user2',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user2@example.com',
},
],
},
];
},
getUser: async () => {
return {
id: admin.external_id,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
try {
// 現在日付を作成
const now = new Date();
await service.deleteUser(context, user2, now);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E014005'));
} else {
fail();
}
}
});
it('削除対象ユーザー(Author)のAuthorIDが設定されているタスクがある場合、削除できない(statusがInprogress)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source, {
tier: 5,
});
const { id: user1, external_id } = await makeTestUser(source, {
account_id: account.id,
role: USER_ROLES.AUTHOR,
author_id: 'AUTHOR',
});
const { id: user2, external_id: external_id2 } = await makeTestUser(
source,
{
account_id: account.id,
role: USER_ROLES.TYPIST,
},
);
const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`, 'requestId');
// タスクを作成
await createTask(
source,
account.id,
'task-url',
'filename',
TASK_STATUS.IN_PROGRESS,
user2,
'AUTHOR',
admin.id, // 作成者がadmin
);
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
{
id: external_id,
displayName: 'user1',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user1@example.com',
},
],
},
{
id: external_id2,
displayName: 'user2',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user2@example.com',
},
],
},
];
},
getUser: async () => {
return {
id: admin.external_id,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
try {
// 現在日付を作成
const now = new Date();
await service.deleteUser(context, user1, now);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E014006'));
} else {
fail();
}
}
});
it('削除対象ユーザー(Author)のAuthorIDが設定されているタスクがある場合、削除できない(statusがFinished)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source, {
tier: 5,
});
const { id: user1, external_id } = await makeTestUser(source, {
account_id: account.id,
role: USER_ROLES.AUTHOR,
author_id: 'AUTHOR',
});
const { id: user2, external_id: external_id2 } = await makeTestUser(
source,
{
account_id: account.id,
role: USER_ROLES.TYPIST,
},
);
const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`, 'requestId');
// タスクを作成
await createTask(
source,
account.id,
'task-url',
'filename',
TASK_STATUS.FINISHED,
user2,
'AUTHOR',
admin.id, // 作成者がadmin
);
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
{
id: external_id,
displayName: 'user1',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user1@example.com',
},
],
},
{
id: external_id2,
displayName: 'user2',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user2@example.com',
},
],
},
];
},
getUser: async () => {
return {
id: admin.external_id,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
try {
// 現在日付を作成
const now = new Date();
await service.deleteUser(context, user1, now);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E014006'));
} else {
fail();
}
}
});
it('削除対象ユーザー(Author)のAuthorIDが設定されているタスクがある場合、削除できない(statusがBackup)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source, {
tier: 5,
});
const { id: user1, external_id } = await makeTestUser(source, {
account_id: account.id,
role: USER_ROLES.AUTHOR,
author_id: 'AUTHOR',
});
const { id: user2, external_id: external_id2 } = await makeTestUser(
source,
{
account_id: account.id,
role: USER_ROLES.TYPIST,
},
);
const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`, 'requestId');
// タスクを作成
await createTask(
source,
account.id,
'task-url',
'filename',
TASK_STATUS.BACKUP,
user2,
'AUTHOR',
admin.id, // 作成者がadmin
);
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
{
id: external_id,
displayName: 'user1',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user1@example.com',
},
],
},
{
id: external_id2,
displayName: 'user2',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user2@example.com',
},
],
},
];
},
getUser: async () => {
return {
id: admin.external_id,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
try {
// 現在日付を作成
const now = new Date();
await service.deleteUser(context, user1, now);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E014006'));
} else {
fail();
}
}
});
it('削除対象ユーザー(Author)が有効なタスクをまだ持っている場合、削除できない(statusがInprogress)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source, {
tier: 5,
});
const { id: user1, external_id } = await makeTestUser(source, {
account_id: account.id,
role: USER_ROLES.AUTHOR,
author_id: 'AUTHOR',
});
const { id: user2, external_id: external_id2 } = await makeTestUser(
source,
{
account_id: account.id,
role: USER_ROLES.TYPIST,
},
);
const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`, 'requestId');
// タスクを作成
await createTask(
source,
account.id,
'task-url',
'filename',
TASK_STATUS.IN_PROGRESS,
user2,
'AUTHOR',
user1,
);
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
{
id: external_id,
displayName: 'user1',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user1@example.com',
},
],
},
{
id: external_id2,
displayName: 'user2',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user2@example.com',
},
],
},
];
},
getUser: async () => {
return {
id: admin.external_id,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
try {
// 現在日付を作成
const now = new Date();
await service.deleteUser(context, user1, now);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E014006'));
} else {
fail();
}
}
});
it('削除対象ユーザー(Author)が有効なタスクをまだ持っている場合、削除できない(statusがFinished)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source, {
tier: 5,
});
const { id: user1, external_id } = await makeTestUser(source, {
account_id: account.id,
role: USER_ROLES.AUTHOR,
author_id: 'AUTHOR',
});
const { id: user2, external_id: external_id2 } = await makeTestUser(
source,
{
account_id: account.id,
role: USER_ROLES.TYPIST,
},
);
const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`, 'requestId');
// タスクを作成
await createTask(
source,
account.id,
'task-url',
'filename',
TASK_STATUS.FINISHED,
user2,
'AUTHOR',
user1,
);
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
{
id: external_id,
displayName: 'user1',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user1@example.com',
},
],
},
{
id: external_id2,
displayName: 'user2',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user2@example.com',
},
],
},
];
},
getUser: async () => {
return {
id: admin.external_id,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
try {
// 現在日付を作成
const now = new Date();
await service.deleteUser(context, user1, now);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E014006'));
} else {
fail();
}
}
});
it('削除対象ユーザー(Author)が有効なタスクをまだ持っている場合、削除できない(statusがBackup)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source, {
tier: 5,
});
const { id: user1, external_id } = await makeTestUser(source, {
account_id: account.id,
role: USER_ROLES.AUTHOR,
author_id: 'AUTHOR',
});
const { id: user2, external_id: external_id2 } = await makeTestUser(
source,
{
account_id: account.id,
role: USER_ROLES.TYPIST,
},
);
const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`, 'requestId');
// タスクを作成
await createTask(
source,
account.id,
'task-url',
'filename',
TASK_STATUS.BACKUP,
user2,
'AUTHOR',
user1,
);
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
{
id: external_id,
displayName: 'user1',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user1@example.com',
},
],
},
{
id: external_id2,
displayName: 'user2',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user2@example.com',
},
],
},
];
},
getUser: async () => {
return {
id: admin.external_id,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
try {
// 現在日付を作成
const now = new Date();
await service.deleteUser(context, user1, now);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E014006'));
} else {
fail();
}
}
});
it('削除対象ユーザー(Typist)タスクのチェックアウト権限まだ持っている場合、削除できない', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source, {
tier: 5,
});
const { id: user1, external_id } = await makeTestUser(source, {
account_id: account.id,
role: USER_ROLES.AUTHOR,
author_id: 'AUTHOR',
});
const { id: user2, external_id: external_id2 } = await makeTestUser(
source,
{
account_id: account.id,
role: USER_ROLES.TYPIST,
},
);
const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`, 'requestId');
// CheckoutPermissionを作成
await createCheckoutPermissions(source, 100, user2);
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
{
id: external_id,
displayName: 'user1',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user1@example.com',
},
],
},
{
id: external_id2,
displayName: 'user2',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user2@example.com',
},
],
},
];
},
getUser: async () => {
return {
id: admin.external_id,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
try {
// 現在日付を作成
const now = new Date();
await service.deleteUser(context, user2, now);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E014009'));
} else {
fail();
}
}
});
it('削除対象ユーザー(Typist)が文字起こし担当のタスクがまだ持っている場合、削除できない(statusがFinished)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source, {
tier: 5,
});
const { id: user1, external_id } = await makeTestUser(source, {
account_id: account.id,
role: USER_ROLES.AUTHOR,
author_id: 'AUTHOR',
});
const { id: user2, external_id: external_id2 } = await makeTestUser(
source,
{
account_id: account.id,
role: USER_ROLES.TYPIST,
},
);
const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`, 'requestId');
// user2が文字起こし担当のタスクを作成
await createTask(
source,
account.id,
'task-url',
'filename',
TASK_STATUS.FINISHED,
user2,
'AUTHOR',
user1,
);
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
{
id: external_id,
displayName: 'user1',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user1@example.com',
},
],
},
{
id: external_id2,
displayName: 'user2',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user2@example.com',
},
],
},
];
},
getUser: async () => {
return {
id: admin.external_id,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
try {
// 現在日付を作成
const now = new Date();
await service.deleteUser(context, user2, now);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E014009'));
} else {
fail();
}
}
});
it('削除対象ユーザー(Typist)が文字起こし担当のタスクがまだ持っている場合、削除できない(statusがBackup)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source, {
tier: 5,
});
const { id: user1, external_id } = await makeTestUser(source, {
account_id: account.id,
role: USER_ROLES.AUTHOR,
author_id: 'AUTHOR',
});
const { id: user2, external_id: external_id2 } = await makeTestUser(
source,
{
account_id: account.id,
role: USER_ROLES.TYPIST,
},
);
const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`, 'requestId');
// user2が文字起こし担当のタスクを作成
await createTask(
source,
account.id,
'task-url',
'filename',
TASK_STATUS.BACKUP,
user2,
'AUTHOR',
user1,
);
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
{
id: external_id,
displayName: 'user1',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user1@example.com',
},
],
},
{
id: external_id2,
displayName: 'user2',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user2@example.com',
},
],
},
];
},
getUser: async () => {
return {
id: admin.external_id,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
try {
// 現在日付を作成
const now = new Date();
await service.deleteUser(context, user2, now);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E014009'));
} else {
fail();
}
}
});
it('削除対象ユーザーが有効なライセンスをまだ持っている場合、削除できない', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account, admin } = await makeTestAccount(source, {
tier: 5,
});
const { id: user1, external_id } = await makeTestUser(source, {
account_id: account.id,
role: USER_ROLES.AUTHOR,
author_id: 'AUTHOR',
});
const { id: user2, external_id: external_id2 } = await makeTestUser(
source,
{
account_id: account.id,
role: USER_ROLES.TYPIST,
},
);
const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`, 'requestId');
// 明日まで有効なライセンスを作成して紐づける
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
await createLicense(source, account.id, user2, tomorrow);
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
{
id: external_id,
displayName: 'user1',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user1@example.com',
},
],
},
{
id: external_id2,
displayName: 'user2',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'user2@example.com',
},
],
},
];
},
getUser: async () => {
return {
id: admin.external_id,
displayName: 'admin',
};
},
});
overrideSendgridService(service, {});
try {
// 現在日付を作成
const now = new Date();
await service.deleteUser(context, user2, now);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E014007'));
} else {
fail();
}
}
});
});
describe('UsersService.multipleImports', () => {
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が行われるため注意
logger: new TestLogger('none'),
logging: true,
});
return await s.initialize();
})();
}
});
beforeEach(async () => {
if (source) {
await truncateAllTable(source);
}
});
afterAll(async () => {
await source?.destroy();
source = null;
});
it('ユーザー一括登録ができる', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account: dealer } = await makeTestAccount(source, {
company_name: 'dealerCompany',
tier: 4,
});
const { account, admin } = await makeTestAccount(source, {
tier: 5,
company_name: 'company',
parent_account_id: dealer.id,
});
const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`, 'requestId');
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
];
},
});
overrideSendgridService(service, {});
overrideBlobstorageService(service, {
uploadImportsBlob: async () => {},
});
// メール送信関数が呼ばれたかどうかで判定を行う。実際のメール送信は行わない。
const spy = jest
.spyOn(service['sendgridService'], 'sendMailWithU120')
.mockImplementation();
const now = new Date();
const date = `${now.getFullYear()}.${now.getMonth() + 1}.${now.getDate()}`;
const filename = 'fileName.csv';
const users = [
{
name: 'name1',
email: 'mail1@example.com',
role: 1,
authorId: 'HOGE1',
autoRenew: 0,
notification: 0,
encryption: 0,
encryptionPassword: 'string',
prompt: 0,
},
{
name: 'name2',
email: 'mail2@example.com',
role: 2,
autoRenew: 0,
notification: 0,
},
];
await service.multipleImports(context, admin.external_id, filename, users);
// メール送信メソッドが呼ばれているか確認
expect(spy).toHaveBeenCalledWith(
context,
['admin@example.com'],
account.company_name,
dealer.company_name,
date,
filename,
);
});
it('Blobアップロードに失敗した場合はエラーとなること', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account: dealer } = await makeTestAccount(source, {
company_name: 'dealerCompany',
tier: 4,
});
const { account, admin } = await makeTestAccount(source, {
tier: 5,
company_name: 'company',
parent_account_id: dealer.id,
});
const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`, 'requestId');
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
];
},
});
overrideSendgridService(service, {});
overrideBlobstorageService(service, {
uploadImportsBlob: async () => {
throw new Error('error');
},
});
const now = new Date();
const date = `${now.getFullYear()}.${now.getMonth() + 1}.${now.getDate()}`;
const filename = 'fileName.csv';
const users = [
{
name: 'name1',
email: 'mail1@example.com',
role: 1,
authorId: 'HOGE1',
autoRenew: 0,
notification: 0,
encryption: 0,
encryptionPassword: 'string',
prompt: 0,
},
{
name: 'name2',
email: 'mail2@example.com',
role: 2,
autoRenew: 0,
notification: 0,
},
];
try {
await service.multipleImports(
context,
admin.external_id,
filename,
users,
);
fail();
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
} else {
fail();
}
}
});
});
describe('UsersService.multipleImportsComplate', () => {
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が行われるため注意
logger: new TestLogger('none'),
logging: true,
});
return await s.initialize();
})();
}
});
beforeEach(async () => {
if (source) {
await truncateAllTable(source);
}
});
afterAll(async () => {
await source?.destroy();
source = null;
});
it('ユーザー一括登録完了メールを送信できる(成功)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account: dealer } = await makeTestAccount(source, {
company_name: 'dealerCompany',
tier: 4,
});
const { account, admin } = await makeTestAccount(source, {
tier: 5,
company_name: 'company',
parent_account_id: dealer.id,
});
const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`, 'requestId');
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
];
},
});
overrideSendgridService(service, {});
// メール送信関数が呼ばれたかどうかで判定を行う。実際のメール送信は行わない。
const spy = jest
.spyOn(service['sendgridService'], 'sendMailWithU121')
.mockImplementation();
const requestTime = Math.floor(new Date(2024, 2, 3).getTime() / 1000);
const filename = `U_20240303_000000_${admin.account_id}_${admin.id}.csv`;
const errors: MultipleImportErrors[] = [];
// ユーザー一括登録完了
await service.multipleImportsComplate(
context,
account.id,
filename,
requestTime,
errors,
);
// ADB2Cユーザー削除メソッドが呼ばれているか確認
expect(spy).toHaveBeenCalledWith(
context,
['admin@example.com'],
account.company_name,
dealer.company_name,
'2024.3.3',
filename,
);
});
it('ユーザー一括登録完了メールを送信できる(失敗)', async () => {
if (!source) fail();
const module = await makeTestingModule(source);
if (!module) fail();
const { account: dealer } = await makeTestAccount(source, {
company_name: 'dealerCompany',
tier: 4,
});
const { account, admin } = await makeTestAccount(source, {
tier: 5,
company_name: 'company',
parent_account_id: dealer.id,
});
const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`, 'requestId');
overrideAdB2cService(service, {
getUsers: async () => {
return [
{
id: admin.external_id,
displayName: 'admin',
identities: [
{
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
issuer: 'issuer',
issuerAssignedId: 'admin@example.com',
},
],
},
];
},
});
overrideSendgridService(service, {});
// メール送信関数が呼ばれたかどうかで判定を行う。実際のメール送信は行わない。
const spy = jest
.spyOn(service['sendgridService'], 'sendMailWithU122')
.mockImplementation();
const requestTime = Math.floor(new Date(2024, 2, 3).getTime() / 1000);
const filename = `U_20240303_000000_${admin.account_id}_${admin.id}`;
const errors: MultipleImportErrors[] = [
{
name: 'user1',
line: 1,
errorCode: 'E010301',
},
{
name: 'user2',
line: 2,
errorCode: 'E010302',
},
{
name: 'user2',
line: 3,
errorCode: 'E010302',
},
{
name: 'user3',
line: 4,
errorCode: 'E009999',
},
];
// ユーザー一括登録完了
await service.multipleImportsComplate(
context,
account.id,
filename,
requestTime,
errors,
);
// ADB2Cユーザー削除メソッドが呼ばれているか確認
expect(spy).toHaveBeenCalledWith(
context,
['admin@example.com'],
account.company_name,
dealer.company_name,
[1],
[2, 3],
[4],
);
});
});