import { HttpException, HttpStatus } from '@nestjs/common'; import { AccessToken } from '../../common/token'; import { makeErrorResponse } from '../../common/error/makeErrorResponse'; import { makeDefaultAdB2cMockValue, makeDefaultConfigValue, makeDefaultSendGridlValue, makeDefaultSortCriteriaRepositoryMockValue, makeDefaultUsersRepositoryMockValue, makeUsersServiceMock, } from './test/users.service.mock'; import { EmailAlreadyVerifiedError } from '../../repositories/users/errors/types'; import { createLicense, createUserGroup, getLicenses, makeTestingModuleWithAdb2c, } from './test/utility'; import { DataSource } from 'typeorm'; import { UsersService } from './users.service'; import { LICENSE_ALLOCATED_STATUS, LICENSE_EXPIRATION_THRESHOLD_DAYS, LICENSE_TYPE, USER_AUDIO_FORMAT, USER_LICENSE_STATUS, USER_ROLES, } from '../../constants'; import { makeTestingModule } from '../../common/test/modules'; import { Context, makeContext } from '../../common/log'; import { overrideAdB2cService, 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, getUserFromExternalId, getUsers, makeTestAccount, makeTestSimpleAccount, makeTestUser, } from '../../common/test/utility'; import { v4 as uuidv4 } from 'uuid'; import { createOptionItems, createWorktype } from '../accounts/test/utility'; import { createWorkflow, getWorkflows } from '../workflows/test/utility'; describe('UsersService.confirmUser', () => { let source: DataSource | null = null; beforeEach(async () => { source = new DataSource({ type: 'sqlite', database: ':memory:', entities: [__dirname + '/../../**/*.entity{.ts,.js}'], synchronize: true, // trueにすると自動的にmigrationが行われるため注意 }); return source.initialize(); }); afterEach(async () => { if (!source) return; 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); overrideSendgridService(service, { sendMailWithU101: async () => { return; }, }); // 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, }); }, 600000); it('トークンの形式が不正な場合、形式不正エラーとなる。', async () => { if (!source) fail(); const module = await makeTestingModule(source); if (!module) fail(); const token = 'invalid.id.token'; const service = module.get(UsersService); overrideSendgridService(service, { sendMailWithU101: async () => { return; }, }); 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); overrideSendgridService(service, { sendMailWithU101: async () => { return; }, }); 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); overrideSendgridService(service, { sendMailWithU101: async () => { return; }, }); 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', () => { it('ユーザーが発行されたパスワードでログインできるようにする', async () => { const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue(); usersRepositoryMockValue.findUserById = { id: 1, external_id: 'TEST9999', account_id: 1, role: 'None', accepted_eula_version: 'string', accepted_privacy_notice_version: 'string', accepted_dpa_version: 'string', email_verified: false, created_by: 'string;', created_at: new Date(), updated_by: 'string;', updated_at: new Date(), auto_renew: true, license_alert: true, notification: true, encryption: false, prompt: false, account: null, author_id: null, deleted_at: null, encryption_password: null, license: null, userGroupMembers: null, }; const licensesRepositoryMockValue = null; const adb2cParam = makeDefaultAdB2cMockValue(); const configMockValue = makeDefaultConfigValue(); const sortCriteriaRepositoryMockValue = makeDefaultSortCriteriaRepositoryMockValue(); const sendGridMockValue = makeDefaultSendGridlValue(); const service = await makeUsersServiceMock( usersRepositoryMockValue, licensesRepositoryMockValue, adb2cParam, sendGridMockValue, configMockValue, sortCriteriaRepositoryMockValue, ); const token = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw'; expect( await service.confirmUserAndInitPassword( makeContext('trackingId', 'requestId'), token, ), ).toEqual(undefined); }); it('トークンの形式が不正な場合、形式不正エラーとなる。(メール認証API)', async () => { const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue(); usersRepositoryMockValue.findUserById = { id: 1, external_id: 'TEST9999', account_id: 1, role: 'None', accepted_eula_version: 'string', accepted_privacy_notice_version: 'string', accepted_dpa_version: 'string', email_verified: false, created_by: 'string;', created_at: new Date(), updated_by: 'string;', updated_at: new Date(), auto_renew: true, license_alert: true, notification: true, encryption: false, prompt: false, account: null, author_id: null, deleted_at: null, encryption_password: null, license: null, userGroupMembers: null, }; 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 token = 'invalid.id.token'; await expect( service.confirmUserAndInitPassword( makeContext('trackingId', 'requestId'), token, ), ).rejects.toEqual( new HttpException(makeErrorResponse('E000101'), HttpStatus.BAD_REQUEST), ); }); it('ユーザが既に認証済みだった場合、認証済みユーザエラーとなる。(メール認証API)', async () => { const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue(); usersRepositoryMockValue.findUserById = { id: 1, external_id: 'TEST9999', account_id: 1, role: 'None', accepted_eula_version: 'string', accepted_privacy_notice_version: 'string', accepted_dpa_version: 'string', email_verified: true, created_by: 'string;', created_at: new Date(), updated_by: 'string;', updated_at: new Date(), auto_renew: true, license_alert: true, notification: true, encryption: false, prompt: false, account: null, author_id: null, deleted_at: null, encryption_password: null, license: null, userGroupMembers: null, }; const licensesRepositoryMockValue = null; const adb2cParam = makeDefaultAdB2cMockValue(); const sendGridMockValue = makeDefaultSendGridlValue(); const configMockValue = makeDefaultConfigValue(); const sortCriteriaRepositoryMockValue = makeDefaultSortCriteriaRepositoryMockValue(); usersRepositoryMockValue.updateUserVerified = new EmailAlreadyVerifiedError( `Email already verified user`, ); const service = await makeUsersServiceMock( usersRepositoryMockValue, licensesRepositoryMockValue, adb2cParam, sendGridMockValue, configMockValue, sortCriteriaRepositoryMockValue, ); const token = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw'; await expect( service.confirmUserAndInitPassword( makeContext('trackingId', 'requestId'), token, ), ).rejects.toEqual( new HttpException(makeErrorResponse('E010202'), HttpStatus.BAD_REQUEST), ); }); it('DBネットワークエラーとなる場合、エラーとなる。(メール認証API)', async () => { const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue(); usersRepositoryMockValue.findUserById = { id: 1, external_id: 'TEST9999', account_id: 1, role: 'None', accepted_eula_version: 'string', accepted_privacy_notice_version: 'string', accepted_dpa_version: 'string', email_verified: false, created_by: 'string;', created_at: new Date(), updated_by: 'string;', updated_at: new Date(), auto_renew: true, license_alert: true, notification: true, encryption: false, prompt: false, account: null, author_id: null, deleted_at: null, encryption_password: null, license: null, userGroupMembers: null, }; const licensesRepositoryMockValue = null; const adb2cParam = makeDefaultAdB2cMockValue(); const sendGridMockValue = makeDefaultSendGridlValue(); usersRepositoryMockValue.updateUserVerified = new Error('DB error'); const configMockValue = makeDefaultConfigValue(); const sortCriteriaRepositoryMockValue = makeDefaultSortCriteriaRepositoryMockValue(); const service = await makeUsersServiceMock( usersRepositoryMockValue, licensesRepositoryMockValue, adb2cParam, sendGridMockValue, configMockValue, sortCriteriaRepositoryMockValue, ); const token = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw'; await expect( service.confirmUserAndInitPassword( makeContext('trackingId', 'requestId'), token, ), ).rejects.toEqual( new HttpException( makeErrorResponse('E009999'), HttpStatus.INTERNAL_SERVER_ERROR, ), ); }); }); describe('UsersService.createUser', () => { let source: DataSource | null = null; beforeEach(async () => { source = new DataSource({ type: 'sqlite', database: ':memory:', logging: false, entities: [__dirname + '/../../**/*.entity{.ts,.js}'], synchronize: true, // trueにすると自動的にmigrationが行われるため注意 }); return source.initialize(); }); afterEach(async () => { if (!source) return; 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); 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', }; }, }); overrideSendgridService(service, { sendMail: async () => { return; }, createMailContentFromEmailConfirmForNormalUser: async () => { return { html: '', text: '', subject: '' }; }, }); expect( await service.createUser( makeContext('trackingId', 'requestId'), adminExternalId, name, role, email, autoRenew, licenseAlert, 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?.license_alert).toEqual(licenseAlert); 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); }); it('管理者権限のあるアクセストークンを使用して、新規ユーザが追加される(role:Author; 暗号化あり)', async () => { if (!source) fail(); const module = await makeTestingModule(source); if (!module) fail(); const service = module.get(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, { sendMail: async () => { return; }, createMailContentFromEmailConfirmForNormalUser: async () => { return { html: '', text: '', subject: '' }; }, }); expect( await service.createUser( makeContext('trackingId', 'requestId'), adminExternalId, name, role, email, autoRenew, licenseAlert, 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?.license_alert).toEqual(licenseAlert); 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); 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, { sendMail: async () => { return; }, createMailContentFromEmailConfirmForNormalUser: async () => { return { html: '', text: '', subject: '' }; }, }); expect( await service.createUser( makeContext('trackingId', 'requestId'), adminExternalId, name, role, email, autoRenew, licenseAlert, 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?.license_alert).toEqual(licenseAlert); 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); 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, { sendMail: async () => { return; }, createMailContentFromEmailConfirmForNormalUser: async () => { return { html: '', text: '', subject: '' }; }, }); expect( await service.createUser( makeContext('trackingId', 'requestId'), adminExternalId, name, role, email, autoRenew, licenseAlert, 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?.license_alert).toEqual(licenseAlert); 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); const b2cService = module.get(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, { sendMail: async () => { return; }, createMailContentFromEmailConfirmForNormalUser: async () => { return { html: '', text: '', subject: '' }; }, }); // DBエラーを発生させる overrideUsersRepositoryService(service, { createNormalUser: async () => { throw new Error('DB error'); }, }); try { await service.createUser( makeContext('trackingId', 'requestId'), adminExternalId, name, role, email, autoRenew, licenseAlert, 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); const b2cService = module.get(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, { sendMail: async () => { return; }, createMailContentFromEmailConfirmForNormalUser: async () => { return { html: '', text: '', subject: '' }; }, }); // DBエラーを発生させる overrideUsersRepositoryService(service, { createNormalUser: async () => { throw new Error('DB error'); }, }); try { await service.createUser( makeContext('trackingId', 'requestId'), adminExternalId, name, role, email, autoRenew, licenseAlert, 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); 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, { sendMail: async () => { return; }, createMailContentFromEmailConfirmForNormalUser: async () => { return { html: '', text: '', subject: '' }; }, }); try { await service.createUser( makeContext('trackingId', 'requestId'), adminExternalId, name, role, email, autoRenew, licenseAlert, 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); 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, { sendMail: async () => { return; }, createMailContentFromEmailConfirmForNormalUser: async () => { return { html: '', text: '', subject: '' }; }, }); try { await service.createUser( makeContext('trackingId', 'requestId'), adminExternalId, name, role, email, autoRenew, licenseAlert, 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); 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, { sendMail: async () => { return; }, createMailContentFromEmailConfirmForNormalUser: async () => { return { html: '', text: '', subject: '' }; }, }); expect( await service.createUser( makeContext('trackingId', 'requestId'), adminExternalId, name, role, email_1, autoRenew, licenseAlert, 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, licenseAlert, 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); const b2cService = module.get(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, { sendMail: async () => { return; }, createMailContentFromEmailConfirmForNormalUser: async () => { return { html: '', text: '', subject: '' }; }, }); // AuthorIDのUNIQUE制約エラーを発生させる overrideUsersRepositoryService(service, { createNormalUser: async () => { throw { code: 'ER_DUP_ENTRY' }; }, }); try { await service.createUser( makeContext('trackingId', 'requestId'), adminExternalId, name, role, email, autoRenew, licenseAlert, 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); const b2cService = module.get(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, { sendMail: async () => { throw new Error(); }, createMailContentFromEmailConfirmForNormalUser: async () => { return { html: '', text: '', subject: '' }; }, }); try { await service.createUser( makeContext('trackingId', 'requestId'), adminExternalId, name, role, email, autoRenew, licenseAlert, 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); const b2cService = module.get(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(); }, createMailContentFromEmailConfirmForNormalUser: async () => { return { html: '', text: '', subject: '' }; }, }); overrideUsersRepositoryService(service, { deleteNormalUser: async () => { throw new Error(); }, }); try { await service.createUser( makeContext('trackingId', 'requestId'), adminExternalId, name, role, email, autoRenew, licenseAlert, 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; beforeEach(async () => { source = new DataSource({ type: 'sqlite', database: ':memory:', logging: false, entities: [__dirname + '/../../**/*.entity{.ts,.js}'], synchronize: true, // trueにすると自動的にmigrationが行われるため注意 }); return source.initialize(); }); afterEach(async () => { if (!source) return; await source.destroy(); source = null; }); it('ユーザーの一覧を取得できる(ライセンス未割当)', async () => { const adb2cParam = makeDefaultAdB2cMockValue(); if (!source) fail(); const module = await makeTestingModuleWithAdb2c(source, adb2cParam); if (!module) fail(); const { id: accountId } = await makeTestSimpleAccount(source); 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, }); const { id: typistUserId } = await makeTestUser(source, { account_id: accountId, external_id: 'external_id2', role: 'typist', author_id: undefined, auto_renew: true, encryption: false, encryption_password: undefined, prompt: false, }); await createUserGroup(source, accountId, 'group1', [typistUserId]); const { id: noneUserId } = await makeTestUser(source, { 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); const expectedUsers = [ { id: authorUserId, name: 'test1', role: 'author', authorId: 'AUTHOR_ID', typistGroupName: [], email: 'test1@mail.com', emailVerified: true, autoRenew: true, licenseAlert: true, notification: true, encryption: false, prompt: false, expiration: undefined, remaining: undefined, licenseStatus: USER_LICENSE_STATUS.NO_LICENSE, }, { id: typistUserId, name: 'test2', role: 'typist', authorId: undefined, typistGroupName: ['group1'], email: 'test2@mail.com', emailVerified: true, autoRenew: true, licenseAlert: true, notification: true, encryption: false, prompt: false, expiration: undefined, remaining: undefined, licenseStatus: USER_LICENSE_STATUS.NO_LICENSE, }, { id: noneUserId, name: 'test3', role: 'none', authorId: undefined, typistGroupName: [], email: 'test3@mail.com', emailVerified: true, autoRenew: true, licenseAlert: true, notification: true, encryption: false, prompt: false, expiration: undefined, remaining: undefined, licenseStatus: USER_LICENSE_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); const expectedUsers = [ { id: user1, name: 'test1', role: 'author', authorId: 'AUTHOR_ID1', typistGroupName: [], email: 'test1@mail.com', emailVerified: true, autoRenew: true, licenseAlert: true, notification: true, encryption: false, prompt: false, expiration: `${date1.getFullYear()}/${ date1.getMonth() + 1 }/${date1.getDate()}`, remaining: LICENSE_EXPIRATION_THRESHOLD_DAYS + 1, licenseStatus: USER_LICENSE_STATUS.NORMAL, }, { id: user2, name: 'test2', role: 'author', authorId: 'AUTHOR_ID2', typistGroupName: [], email: 'test2@mail.com', emailVerified: true, autoRenew: true, licenseAlert: true, notification: true, encryption: false, prompt: false, expiration: `${date2.getFullYear()}/${ date2.getMonth() + 1 }/${date2.getDate()}`, remaining: LICENSE_EXPIRATION_THRESHOLD_DAYS, licenseStatus: USER_LICENSE_STATUS.RENEW, }, { id: user3, name: 'test3', role: 'author', authorId: 'AUTHOR_ID3', typistGroupName: [], email: 'test3@mail.com', emailVerified: true, autoRenew: false, licenseAlert: true, notification: true, encryption: false, prompt: false, expiration: `${date3.getFullYear()}/${ date3.getMonth() + 1 }/${date3.getDate()}`, remaining: LICENSE_EXPIRATION_THRESHOLD_DAYS - 1, licenseStatus: USER_LICENSE_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); 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); 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; beforeEach(async () => { source = new DataSource({ type: 'sqlite', database: ':memory:', logging: false, entities: [__dirname + '/../../**/*.entity{.ts,.js}'], synchronize: true, // trueにすると自動的にmigrationが行われるため注意 }); return source.initialize(); }); afterEach(async () => { if (!source) return; await source.destroy(); source = null; }); 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); overrideSendgridService(service, {}); const context = makeContext(`uuidv4`, 'requestId'); expect( await service.updateUser( context, external_id, user1, USER_ROLES.NONE, undefined, false, 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?.license_alert).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); overrideSendgridService(service, {}); const context = makeContext(`uuidv4`, 'requestId'); expect( await service.updateUser( context, external_id, user1, USER_ROLES.TYPIST, undefined, false, 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?.license_alert).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); overrideSendgridService(service, {}); const context = makeContext(`uuidv4`, 'requestId'); expect( await service.updateUser( context, external_id, user1, USER_ROLES.AUTHOR, 'AUTHOR_ID', false, 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?.license_alert).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); overrideSendgridService(service, {}); const context = makeContext(`uuidv4`, 'requestId'); expect( await service.updateUser( context, external_id, user1, USER_ROLES.TYPIST, undefined, false, 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?.license_alert).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); overrideSendgridService(service, {}); const context = makeContext(`uuidv4`, 'requestId'); expect( await service.updateUser( context, external_id, user1, USER_ROLES.AUTHOR, 'AUTHOR_ID', false, 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?.license_alert).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); overrideSendgridService(service, {}); const context = makeContext(`uuidv4`, 'requestId'); await expect( service.updateUser( context, external_id, user1, USER_ROLES.NONE, undefined, false, 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); overrideSendgridService(service, {}); const context = makeContext(`uuidv4`, 'requestId'); expect( await service.updateUser( context, external_id, user1, USER_ROLES.AUTHOR, 'AUTHOR_ID', false, 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?.license_alert).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); overrideSendgridService(service, {}); const context = makeContext(`uuidv4`, 'requestId'); expect( await service.updateUser( context, external_id, user1, USER_ROLES.AUTHOR, 'AUTHOR_ID', false, 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?.license_alert).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); overrideSendgridService(service, {}); const context = makeContext(`uuidv4`, 'requestId'); await expect( service.updateUser( context, external_id, user1, USER_ROLES.AUTHOR, 'AUTHOR_ID', false, 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); overrideSendgridService(service, {}); const context = makeContext(`uuidv4`, 'requestId'); await expect( service.updateUser( context, external_id, user1, USER_ROLES.AUTHOR, 'AUTHOR_ID2', false, false, false, true, undefined, true, ), ).rejects.toEqual( new HttpException(makeErrorResponse('E010302'), HttpStatus.BAD_REQUEST), ); }); }); describe('UsersService.updateAcceptedVersion', () => { let source: DataSource | null = null; beforeEach(async () => { source = new DataSource({ type: 'sqlite', database: ':memory:', logging: false, entities: [__dirname + '/../../**/*.entity{.ts,.js}'], synchronize: true, // trueにすると自動的にmigrationが行われるため注意 }); return source.initialize(); }); afterEach(async () => { if (!source) return; 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); 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); 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); 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; beforeEach(async () => { source = new DataSource({ type: 'sqlite', database: ':memory:', logging: false, entities: [__dirname + '/../../**/*.entity{.ts,.js}'], synchronize: true, }); return source.initialize(); }); afterEach(async () => { if (!source) return; 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); 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; beforeEach(async () => { source = new DataSource({ type: 'sqlite', database: ':memory:', logging: false, entities: [__dirname + '/../../**/*.entity{.ts,.js}'], synchronize: true, }); return source.initialize(); }); afterEach(async () => { if (!source) return; 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, 'worktype1', undefined, true, ); await createOptionItems(source, worktype1.id); const worktype2 = await createWorktype(source, account.id, 'worktype2'); await createOptionItems(source, worktype2.id); await createWorkflow(source, account.id, user1, worktype1.id); await createWorkflow(source, account.id, user1, worktype2.id); await createWorkflow(source, account.id, user1); await createWorkflow(source, account.id, user2, worktype1.id); // 作成したデータを確認 { const workflows = await getWorkflows(source, account.id); expect(workflows.length).toBe(4); 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(null); expect(workflows[2].author_id).toBe(user1); expect(workflows[3].worktype_id).toBe(worktype1.id); expect(workflows[3].author_id).toBe(user2); } const context = makeContext(external_id, 'requestId'); const service = module.get(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(2); expect(workTypeList[0].workTypeId).toBe(worktype1.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(worktype2.custom_worktype_id); expect(workTypeList[1].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); 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); 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(); } } }); });