## 概要 [Task2461: API実装(TypistGroup取得API)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2461) - TypistGroup取得APIとテストを実装しました。 ## レビューポイント - DBからの取得ロジックに問題はないか - テストケースは十分か ## UIの変更 - なし ## 動作確認状況 - ローカルで確認
2779 lines
89 KiB
TypeScript
2779 lines
89 KiB
TypeScript
import { HttpException, HttpStatus } from '@nestjs/common';
|
||
import { makeErrorResponse } from '../../common/error/makeErrorResponse';
|
||
import {
|
||
makeAccountsServiceMock,
|
||
makeBlobStorageServiceMockValue,
|
||
makeDefaultAccountsRepositoryMockValue,
|
||
makeDefaultAdB2cMockValue,
|
||
makeDefaultLicensesRepositoryMockValue,
|
||
makeDefaultSendGridlValue,
|
||
makeDefaultUserGroupsRepositoryMockValue,
|
||
makeDefaultUsersRepositoryMockValue,
|
||
} from './test/accounts.service.mock';
|
||
import { makeDefaultConfigValue } from '../users/test/users.service.mock';
|
||
import {
|
||
createLicense,
|
||
createLicenseOrder,
|
||
createLicenseSetExpiryDateAndStatus,
|
||
getSortCriteria,
|
||
getTypistGroup,
|
||
getTypistGroupMember,
|
||
createTypistGroup,
|
||
} from './test/utility';
|
||
import { DataSource } from 'typeorm';
|
||
import { makeTestingModule } from '../../common/test/modules';
|
||
import {
|
||
makeTestAccount,
|
||
getAccount,
|
||
getAccounts,
|
||
getUserFromExternalId,
|
||
getUsers,
|
||
makeTestUser,
|
||
} from '../../common/test/utility';
|
||
import { AccountsService } from './accounts.service';
|
||
import { Context, makeContext } from '../../common/log';
|
||
import { TIERS, USER_ROLES } from '../../constants';
|
||
import { License } from '../../repositories/licenses/entity/license.entity';
|
||
import {
|
||
overrideAccountsRepositoryService,
|
||
overrideAdB2cService,
|
||
overrideBlobstorageService,
|
||
overrideSendgridService,
|
||
} from '../../common/test/overrides';
|
||
import { AdB2cService } from '../../gateways/adb2c/adb2c.service';
|
||
import { BlobstorageService } from '../../gateways/blobstorage/blobstorage.service';
|
||
import { UserGroupsRepositoryService } from '../../repositories/user_groups/user_groups.repository.service';
|
||
|
||
describe('createAccount', () => {
|
||
let source: DataSource = 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 () => {
|
||
await source.destroy();
|
||
source = null;
|
||
});
|
||
|
||
it('アカウントを作成できる', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
|
||
const externalId = 'test_external_id';
|
||
const companyName = 'test_company_name';
|
||
const country = 'US';
|
||
const dealerAccountId = 1;
|
||
const email = 'dummy@example.com';
|
||
const password = 'dummy_password';
|
||
const username = 'dummy_username';
|
||
const role = 'none';
|
||
const acceptedTermsVersion = '1.0.0';
|
||
|
||
overrideAdB2cService(service, {
|
||
createUser: async () => {
|
||
return { sub: externalId };
|
||
},
|
||
});
|
||
|
||
overrideSendgridService(service, {
|
||
sendMail: async () => {
|
||
return;
|
||
},
|
||
createMailContentFromEmailConfirm: async () => {
|
||
return { html: '', text: '', subject: '' };
|
||
},
|
||
});
|
||
overrideBlobstorageService(service, {
|
||
createContainer: async () => {
|
||
return;
|
||
},
|
||
});
|
||
|
||
const { accountId, externalUserId, userId } = await service.createAccount(
|
||
makeContext('uuid'),
|
||
companyName,
|
||
country,
|
||
dealerAccountId,
|
||
email,
|
||
password,
|
||
username,
|
||
role,
|
||
acceptedTermsVersion,
|
||
);
|
||
// 作成したアカウントのIDが返ってくるか確認
|
||
expect(accountId).toBe(1);
|
||
expect(externalUserId).toBe(externalId);
|
||
expect(userId).toBe(1);
|
||
|
||
// DB内が想定通りになっているか確認
|
||
const account = await getAccount(source, accountId);
|
||
const user = await getUserFromExternalId(source, externalUserId);
|
||
expect(account.company_name).toBe(companyName);
|
||
expect(account.country).toBe(country);
|
||
expect(account.parent_account_id).toBe(dealerAccountId);
|
||
expect(account.tier).toBe(TIERS.TIER5);
|
||
expect(account.primary_admin_user_id).toBe(user.id);
|
||
expect(account.secondary_admin_user_id).toBe(null);
|
||
expect(user.accepted_terms_version).toBe(acceptedTermsVersion);
|
||
expect(user.account_id).toBe(accountId);
|
||
expect(user.role).toBe(role);
|
||
});
|
||
|
||
it('アカウントを作成がAzure AD B2Cへの通信失敗によって失敗すると500エラーが発生する', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
|
||
overrideAdB2cService(service, {
|
||
createUser: async () => {
|
||
throw new Error();
|
||
},
|
||
});
|
||
|
||
overrideSendgridService(service, {
|
||
sendMail: async () => {
|
||
return;
|
||
},
|
||
createMailContentFromEmailConfirm: async () => {
|
||
return { html: '', text: '', subject: '' };
|
||
},
|
||
});
|
||
|
||
const companyName = 'test_company_name';
|
||
const country = 'US';
|
||
const dealerAccountId = 1;
|
||
const email = 'dummy@example.com';
|
||
const password = 'dummy_password';
|
||
const username = 'dummy_username';
|
||
const role = 'admin none';
|
||
const acceptedTermsVersion = '1.0.0';
|
||
|
||
overrideAdB2cService(service, {
|
||
createUser: async () => {
|
||
throw new Error();
|
||
},
|
||
});
|
||
overrideSendgridService(service, {});
|
||
overrideBlobstorageService(service, {});
|
||
|
||
try {
|
||
await service.createAccount(
|
||
makeContext('uuid'),
|
||
companyName,
|
||
country,
|
||
dealerAccountId,
|
||
email,
|
||
password,
|
||
username,
|
||
role,
|
||
acceptedTermsVersion,
|
||
);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toBe(HttpStatus.INTERNAL_SERVER_ERROR);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
|
||
// DB内が想定通りになっているか確認
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(0);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(0);
|
||
});
|
||
|
||
it('アカウントを作成がメールアドレス重複によって失敗すると400エラーが発生する', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
|
||
overrideAdB2cService(service, {
|
||
createUser: async () => {
|
||
// EmailのConflictエラーを返す
|
||
return { reason: 'email', message: 'dummy' };
|
||
},
|
||
});
|
||
|
||
overrideSendgridService(service, {
|
||
sendMail: async () => {
|
||
return;
|
||
},
|
||
createMailContentFromEmailConfirm: async () => {
|
||
return { html: '', text: '', subject: '' };
|
||
},
|
||
});
|
||
|
||
const companyName = 'test_company_name';
|
||
const country = 'US';
|
||
const dealerAccountId = 1;
|
||
const email = 'dummy@example.com';
|
||
const password = 'dummy_password';
|
||
const username = 'dummy_username';
|
||
const role = 'admin none';
|
||
const acceptedTermsVersion = '1.0.0';
|
||
|
||
overrideAdB2cService(service, {
|
||
createUser: async () => {
|
||
// EmailのConflictエラーを返す
|
||
return { reason: 'email', message: 'dummy' };
|
||
},
|
||
});
|
||
overrideSendgridService(service, {});
|
||
overrideBlobstorageService(service, {});
|
||
|
||
try {
|
||
await service.createAccount(
|
||
makeContext('uuid'),
|
||
companyName,
|
||
country,
|
||
dealerAccountId,
|
||
email,
|
||
password,
|
||
username,
|
||
role,
|
||
acceptedTermsVersion,
|
||
);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toBe(HttpStatus.BAD_REQUEST);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E010301'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
|
||
// DB内が想定通りになっているか確認
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(0);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(0);
|
||
});
|
||
it('アカウントを作成がDBへの通信失敗によって500エラーが発生した場合、リカバリ処理としてADB2Cユーザーを削除され、500エラーが返却される', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const b2cService = module.get<AdB2cService>(AdB2cService);
|
||
const externalId = 'test_external_id';
|
||
const companyName = 'test_company_name';
|
||
const country = 'US';
|
||
const dealerAccountId = 1;
|
||
const email = 'dummy@example.com';
|
||
const password = 'dummy_password';
|
||
const username = 'dummy_username';
|
||
const role = 'none';
|
||
const acceptedTermsVersion = '1.0.0';
|
||
|
||
overrideAdB2cService(service, {
|
||
createUser: async () => {
|
||
return { sub: externalId };
|
||
},
|
||
deleteUser: jest.fn(),
|
||
});
|
||
overrideSendgridService(service, {});
|
||
|
||
overrideAccountsRepositoryService(service, {
|
||
createAccount: async () => {
|
||
throw new Error();
|
||
},
|
||
});
|
||
|
||
try {
|
||
await service.createAccount(
|
||
makeContext('uuid'),
|
||
companyName,
|
||
country,
|
||
dealerAccountId,
|
||
email,
|
||
password,
|
||
username,
|
||
role,
|
||
acceptedTermsVersion,
|
||
);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toBe(HttpStatus.INTERNAL_SERVER_ERROR);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
// DB内が想定通りになっているか確認
|
||
// DBのデータ作成で失敗しているので、DB内は空
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(0);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(0);
|
||
const sortCriteria = await getSortCriteria(source);
|
||
expect(sortCriteria.length).toBe(0);
|
||
// ADB2Cユーザー削除メソッドが呼ばれているか確認
|
||
expect(b2cService.deleteUser).toBeCalledWith(
|
||
externalId,
|
||
makeContext('uuid'),
|
||
);
|
||
});
|
||
it('アカウントを作成がDBへの通信失敗によって500エラーが発生した場合、リカバリ処理が実行されるが、ADB2Cユーザー削除で失敗した場合、500エラーが返却される', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const b2cService = module.get<AdB2cService>(AdB2cService);
|
||
const externalId = 'test_external_id';
|
||
const companyName = 'test_company_name';
|
||
const country = 'US';
|
||
const dealerAccountId = 1;
|
||
const email = 'dummy@dummy.dummy';
|
||
const password = 'dummy_password';
|
||
const username = 'dummy_username';
|
||
const role = 'none';
|
||
const acceptedTermsVersion = '1.0.0';
|
||
|
||
overrideAdB2cService(service, {
|
||
createUser: async () => {
|
||
return { sub: externalId };
|
||
},
|
||
deleteUser: jest.fn().mockRejectedValue(new Error()),
|
||
});
|
||
overrideSendgridService(service, {});
|
||
|
||
overrideAccountsRepositoryService(service, {
|
||
createAccount: async () => {
|
||
throw new Error();
|
||
},
|
||
});
|
||
|
||
try {
|
||
await service.createAccount(
|
||
makeContext('uuid'),
|
||
companyName,
|
||
country,
|
||
dealerAccountId,
|
||
email,
|
||
password,
|
||
username,
|
||
role,
|
||
acceptedTermsVersion,
|
||
);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toBe(HttpStatus.INTERNAL_SERVER_ERROR);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
// DB内が想定通りになっているか確認
|
||
// DBのデータ作成で失敗しているので、DB内は空
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(0);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(0);
|
||
const sortCriteria = await getSortCriteria(source);
|
||
expect(sortCriteria.length).toBe(0);
|
||
// ADB2Cユーザー削除メソッドが呼ばれているか確認
|
||
expect(b2cService.deleteUser).toBeCalledWith(
|
||
externalId,
|
||
makeContext('uuid'),
|
||
);
|
||
});
|
||
|
||
it('アカウントを作成がBlobStorageへの通信失敗によって500エラーが発生した場合、リカバリ処理としてADB2C,DB上のデータが削除され、500エラーが返却される', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const b2cService = module.get<AdB2cService>(AdB2cService);
|
||
b2cService.deleteUser = jest.fn(); // リカバリ処理の確認のため、deleteUserをモック化
|
||
const externalId = 'test_external_id';
|
||
const companyName = 'test_company_name';
|
||
const country = 'US';
|
||
const dealerAccountId = 1;
|
||
const email = 'dummy@dummy.dummy';
|
||
const password = 'dummy_password';
|
||
const username = 'dummy_username';
|
||
const role = 'none';
|
||
const acceptedTermsVersion = '1.0.0';
|
||
|
||
overrideAdB2cService(service, {
|
||
createUser: async () => {
|
||
return { sub: externalId };
|
||
},
|
||
deleteUser: async () => {
|
||
return;
|
||
},
|
||
});
|
||
overrideSendgridService(service, {});
|
||
overrideBlobstorageService(service, {
|
||
createContainer: async () => {
|
||
throw new Error();
|
||
},
|
||
});
|
||
|
||
try {
|
||
await service.createAccount(
|
||
makeContext('uuid'),
|
||
companyName,
|
||
country,
|
||
dealerAccountId,
|
||
email,
|
||
password,
|
||
username,
|
||
role,
|
||
acceptedTermsVersion,
|
||
);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toBe(HttpStatus.INTERNAL_SERVER_ERROR);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
// DB内が想定通りになっているか確認
|
||
// リカバリ処理が走っているため、アカウント・ユーザーは削除されている
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(0);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(0);
|
||
const sortCriteria = await getSortCriteria(source);
|
||
expect(sortCriteria.length).toBe(0);
|
||
// ADB2Cユーザー削除メソッドが呼ばれているか確認
|
||
expect(b2cService.deleteUser).toBeCalledWith(
|
||
externalId,
|
||
makeContext('uuid'),
|
||
);
|
||
});
|
||
|
||
it('アカウントを作成がBlobStorageへの通信失敗によって500エラーが発生した場合、リカバリ処理が実行されるが、そのリカバリ処理に失敗した場合、500エラーが返却される', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const b2cService = module.get<AdB2cService>(AdB2cService);
|
||
const externalId = 'test_external_id';
|
||
const companyName = 'test_company_name';
|
||
const country = 'US';
|
||
const dealerAccountId = 1;
|
||
const email = 'dummy@dummy.dummy';
|
||
const password = 'dummy_password';
|
||
const username = 'dummy_username';
|
||
const role = 'none';
|
||
const acceptedTermsVersion = '1.0.0';
|
||
|
||
overrideAdB2cService(service, {
|
||
createUser: async () => {
|
||
return { sub: externalId };
|
||
},
|
||
deleteUser: jest.fn().mockRejectedValue(new Error()),
|
||
});
|
||
overrideSendgridService(service, {});
|
||
overrideBlobstorageService(service, {
|
||
createContainer: async () => {
|
||
throw new Error();
|
||
},
|
||
});
|
||
overrideAccountsRepositoryService(service, {
|
||
deleteAccount: async () => {
|
||
throw new Error();
|
||
},
|
||
});
|
||
|
||
try {
|
||
await service.createAccount(
|
||
makeContext('uuid'),
|
||
companyName,
|
||
country,
|
||
dealerAccountId,
|
||
email,
|
||
password,
|
||
username,
|
||
role,
|
||
acceptedTermsVersion,
|
||
);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toBe(HttpStatus.INTERNAL_SERVER_ERROR);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
// DB内が想定通りになっているか確認
|
||
// DB上のデータのリカバリ処理に失敗したため、DB上のデータは削除されない
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(1);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(1);
|
||
const sortCriteria = await getSortCriteria(source);
|
||
expect(sortCriteria.length).toBe(1);
|
||
// ADB2Cユーザー削除メソッドが呼ばれているか確認
|
||
expect(b2cService.deleteUser).toBeCalledWith(
|
||
externalId,
|
||
makeContext('uuid'),
|
||
);
|
||
});
|
||
|
||
it('アカウントを作成がSendGridへの通信失敗によって500エラーが発生した場合、リカバリ処理としてADB2C,DB上のデータとBlobストレージのコンテナが削除され、500エラーが返却される', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const b2cService = module.get<AdB2cService>(AdB2cService);
|
||
const blobstorageService =
|
||
module.get<BlobstorageService>(BlobstorageService);
|
||
const externalId = 'test_external_id';
|
||
const companyName = 'test_company_name';
|
||
const country = 'US';
|
||
const dealerAccountId = 1;
|
||
const email = 'dummy@dummy.dummy';
|
||
const password = 'dummy_password';
|
||
const username = 'dummy_username';
|
||
const role = 'none';
|
||
const acceptedTermsVersion = '1.0.0';
|
||
|
||
overrideAdB2cService(service, {
|
||
createUser: async (
|
||
_context: Context,
|
||
_email: string,
|
||
_password: string,
|
||
_username: string,
|
||
) => {
|
||
// ユーザー作成時に指定したパラメータが正しく渡されていることを確認
|
||
expect(email).toEqual(_email);
|
||
expect(username).toEqual(_username);
|
||
|
||
return { sub: externalId };
|
||
},
|
||
deleteUser: jest.fn(),
|
||
});
|
||
overrideSendgridService(service, {
|
||
sendMail: async () => {
|
||
throw new Error();
|
||
},
|
||
createMailContentFromEmailConfirm: async () => {
|
||
return {
|
||
html: 'dummy_html',
|
||
subject: 'dummy_subject',
|
||
text: 'dummy_text',
|
||
};
|
||
},
|
||
});
|
||
overrideBlobstorageService(service, {
|
||
createContainer: async () => {
|
||
return;
|
||
},
|
||
deleteContainer: jest.fn(),
|
||
});
|
||
overrideAccountsRepositoryService(service, {});
|
||
|
||
try {
|
||
await service.createAccount(
|
||
makeContext('uuid'),
|
||
companyName,
|
||
country,
|
||
dealerAccountId,
|
||
email,
|
||
password,
|
||
username,
|
||
role,
|
||
acceptedTermsVersion,
|
||
);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toBe(HttpStatus.INTERNAL_SERVER_ERROR);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
// DB内が想定通りになっているか確認
|
||
// リカバリ処理によってADB2C,DB上のデータとBlobストレージのコンテナが削除される
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(0);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(0);
|
||
const sortCriteria = await getSortCriteria(source);
|
||
expect(sortCriteria.length).toBe(0);
|
||
// ADB2Cユーザー削除メソッドが呼ばれているか確認
|
||
expect(b2cService.deleteUser).toBeCalledWith(
|
||
externalId,
|
||
makeContext('uuid'),
|
||
);
|
||
// Blobストレージのコンテナ削除メソッドが呼ばれているか確認
|
||
expect(blobstorageService.deleteContainer).toBeCalledWith(
|
||
makeContext('uuid'),
|
||
1, //新規作成したアカウントのID
|
||
country,
|
||
);
|
||
});
|
||
|
||
it('アカウントを作成がSendGridへの通信失敗によって500エラーが発生した場合、リカバリ処理が実行されるが、そのリカバリ処理に失敗した場合、500エラーが返却される', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const b2cService = module.get<AdB2cService>(AdB2cService);
|
||
const blobstorageService =
|
||
module.get<BlobstorageService>(BlobstorageService);
|
||
const externalId = 'test_external_id';
|
||
const companyName = 'test_company_name';
|
||
const country = 'US';
|
||
const dealerAccountId = 1;
|
||
const email = 'dummy@dummy.dummy';
|
||
const password = 'dummy_password';
|
||
const username = 'dummy_username';
|
||
const role = 'none';
|
||
const acceptedTermsVersion = '1.0.0';
|
||
|
||
overrideAdB2cService(service, {
|
||
createUser: async () => {
|
||
return { sub: externalId };
|
||
},
|
||
deleteUser: jest.fn().mockRejectedValue(new Error()),
|
||
});
|
||
overrideSendgridService(service, {
|
||
sendMail: async () => {
|
||
throw new Error();
|
||
},
|
||
createMailContentFromEmailConfirm: async () => {
|
||
return {
|
||
html: 'dummy_html',
|
||
subject: 'dummy_subject',
|
||
text: 'dummy_text',
|
||
};
|
||
},
|
||
});
|
||
overrideBlobstorageService(service, {
|
||
createContainer: async () => {
|
||
return;
|
||
},
|
||
deleteContainer: jest
|
||
.fn()
|
||
.mockRejectedValue(new Error('BlobStorage Error')),
|
||
});
|
||
overrideAccountsRepositoryService(service, {
|
||
deleteAccount: async () => {
|
||
throw new Error();
|
||
},
|
||
});
|
||
|
||
try {
|
||
await service.createAccount(
|
||
makeContext('uuid'),
|
||
companyName,
|
||
country,
|
||
dealerAccountId,
|
||
email,
|
||
password,
|
||
username,
|
||
role,
|
||
acceptedTermsVersion,
|
||
);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toBe(HttpStatus.INTERNAL_SERVER_ERROR);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
// DB内が想定通りになっているか確認
|
||
// リカバリ処理によってADB2C,DB上のデータとBlobストレージのコンテナが削除されない
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(1);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(1);
|
||
const sortCriteria = await getSortCriteria(source);
|
||
expect(sortCriteria.length).toBe(1);
|
||
// ADB2Cユーザー削除メソッドが呼ばれているか確認
|
||
expect(b2cService.deleteUser).toBeCalledWith(
|
||
externalId,
|
||
makeContext('uuid'),
|
||
);
|
||
// Blobストレージのコンテナ削除メソッドが呼ばれているか確認
|
||
expect(blobstorageService.deleteContainer).toBeCalledWith(
|
||
makeContext('uuid'),
|
||
1, //新規作成したアカウントのID
|
||
country,
|
||
);
|
||
});
|
||
});
|
||
|
||
describe('createPartnerAccount', () => {
|
||
let source: DataSource = 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 () => {
|
||
await source.destroy();
|
||
source = null;
|
||
});
|
||
|
||
it('パートナーを追加できる', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const adminExternalId = 'ADMIN0001';
|
||
|
||
// 第一階層のアカウントを作成
|
||
const { account: parent } = await makeTestAccount(
|
||
source,
|
||
{ tier: 1 },
|
||
{ external_id: adminExternalId },
|
||
);
|
||
|
||
const context = makeContext('uuid');
|
||
const companyName = 'test_company_name';
|
||
const country = 'US';
|
||
const email = 'partner@example.com';
|
||
const adminName = 'partner_admin';
|
||
const pertnerExternalId = 'PARTNER0001';
|
||
|
||
overrideAdB2cService(service, {
|
||
createUser: async () => {
|
||
return { sub: pertnerExternalId };
|
||
},
|
||
});
|
||
|
||
overrideSendgridService(service, {
|
||
createMailContentFromEmailConfirmForNormalUser: async () => {
|
||
return { html: '', text: '', subject: '' };
|
||
},
|
||
sendMail: async () => {
|
||
return;
|
||
},
|
||
});
|
||
|
||
overrideBlobstorageService(service, {
|
||
createContainer: async () => {
|
||
return;
|
||
},
|
||
});
|
||
|
||
// DB上に用意されたデータが想定通りであるか確認
|
||
{
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(1);
|
||
}
|
||
|
||
const { accountId } = await service.createPartnerAccount(
|
||
context,
|
||
companyName,
|
||
country,
|
||
email,
|
||
adminName,
|
||
adminExternalId,
|
||
parent.tier,
|
||
);
|
||
|
||
// DB上に作成されたデータが想定通りであるか確認
|
||
{
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(2);
|
||
|
||
const createdUser = await getUserFromExternalId(
|
||
source,
|
||
pertnerExternalId,
|
||
);
|
||
const createdAccount = await getAccount(source, accountId);
|
||
expect(createdAccount.company_name).toBe(companyName);
|
||
expect(createdAccount.country).toBe(country);
|
||
expect(createdAccount.parent_account_id).toBe(parent.id);
|
||
expect(createdAccount.tier).toBe(2);
|
||
expect(createdAccount.primary_admin_user_id).toBe(createdUser.id);
|
||
expect(createdAccount.secondary_admin_user_id).toBe(null);
|
||
}
|
||
});
|
||
|
||
it('Azure AD B2Cへの接続に失敗した結果アカウントの追加に失敗した場合、エラーとなる(500エラー)', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const adminExternalId = 'ADMIN0001';
|
||
|
||
// 第一階層のアカウントを作成
|
||
const { account: parent } = await makeTestAccount(
|
||
source,
|
||
{ tier: 1 },
|
||
{ external_id: adminExternalId },
|
||
);
|
||
|
||
const context = makeContext('uuid');
|
||
const companyName = 'test_company_name';
|
||
const country = 'US';
|
||
const email = 'partner@example.com';
|
||
const adminName = 'partner_admin';
|
||
|
||
overrideAdB2cService(service, {
|
||
createUser: async () => {
|
||
throw new Error();
|
||
},
|
||
});
|
||
|
||
overrideSendgridService(service, {
|
||
createMailContentFromEmailConfirmForNormalUser: async () => {
|
||
return { html: '', text: '', subject: '' };
|
||
},
|
||
sendMail: async () => {
|
||
return;
|
||
},
|
||
});
|
||
|
||
overrideBlobstorageService(service, {
|
||
createContainer: async () => {
|
||
return;
|
||
},
|
||
});
|
||
|
||
// DB上に用意されたデータが想定通りであるか確認
|
||
{
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(1);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(1);
|
||
}
|
||
|
||
try {
|
||
await service.createPartnerAccount(
|
||
context,
|
||
companyName,
|
||
country,
|
||
email,
|
||
adminName,
|
||
adminExternalId,
|
||
parent.tier,
|
||
);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toBe(HttpStatus.INTERNAL_SERVER_ERROR);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
|
||
// DB上に作成されたデータが想定通りであるか確認
|
||
{
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(1);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(1);
|
||
}
|
||
});
|
||
|
||
it('DBへの通信失敗によって500エラーが発生した場合、リカバリ処理としてADB2Cユーザーを削除され、500エラーが返却される', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const b2cService = module.get<AdB2cService>(AdB2cService);
|
||
const adminExternalId = 'ADMIN0001';
|
||
|
||
// 第一階層のアカウントを作成
|
||
const { account: parent } = await makeTestAccount(
|
||
source,
|
||
{ tier: 1 },
|
||
{ external_id: adminExternalId },
|
||
);
|
||
|
||
const context = makeContext('uuid');
|
||
const companyName = 'test_company_name';
|
||
const country = 'US';
|
||
const email = 'partner@example.com';
|
||
const adminName = 'partner_admin';
|
||
const partnerExternalId = 'partner_external_id';
|
||
|
||
overrideAdB2cService(service, {
|
||
createUser: async () => {
|
||
return { sub: partnerExternalId };
|
||
},
|
||
deleteUser: jest.fn(),
|
||
});
|
||
|
||
overrideSendgridService(service, {
|
||
createMailContentFromEmailConfirmForNormalUser: async () => {
|
||
return { html: '', text: '', subject: '' };
|
||
},
|
||
sendMail: async () => {
|
||
return;
|
||
},
|
||
});
|
||
overrideAccountsRepositoryService(service, {
|
||
createAccount: async () => {
|
||
throw new Error('DB Error');
|
||
},
|
||
});
|
||
|
||
overrideBlobstorageService(service, {
|
||
createContainer: async () => {
|
||
return;
|
||
},
|
||
});
|
||
|
||
// DB上に用意されたデータが想定通りであるか確認
|
||
{
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(1);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(1);
|
||
}
|
||
|
||
try {
|
||
await service.createPartnerAccount(
|
||
context,
|
||
companyName,
|
||
country,
|
||
email,
|
||
adminName,
|
||
adminExternalId,
|
||
parent.tier,
|
||
);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toBe(HttpStatus.INTERNAL_SERVER_ERROR);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
|
||
// DB上に作成されたデータが想定通りであるか確認
|
||
{
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(1);
|
||
expect(accounts[0].tier).toBe(1);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(1);
|
||
expect(users[0].external_id).toBe(adminExternalId);
|
||
// ADB2Cユーザー削除メソッドが呼ばれているか確認
|
||
expect(b2cService.deleteUser).toBeCalledWith(partnerExternalId, context);
|
||
}
|
||
});
|
||
|
||
it('DBへの通信失敗によって500エラーが発生した場合、リカバリ処理が実行されるが、ADB2Cユーザー削除で失敗した場合、500エラーが返却される', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const b2cService = module.get<AdB2cService>(AdB2cService);
|
||
const adminExternalId = 'ADMIN0001';
|
||
|
||
// 第一階層のアカウントを作成
|
||
const { account: parent } = await makeTestAccount(
|
||
source,
|
||
{ tier: 1 },
|
||
{ external_id: adminExternalId },
|
||
);
|
||
|
||
const context = makeContext('uuid');
|
||
const companyName = 'test_company_name';
|
||
const country = 'US';
|
||
const email = 'partner@example.com';
|
||
const adminName = 'partner_admin';
|
||
const partnerExternalId = 'partner_external_id';
|
||
|
||
overrideAdB2cService(service, {
|
||
createUser: async () => {
|
||
return { sub: partnerExternalId };
|
||
},
|
||
deleteUser: jest.fn().mockRejectedValue(new Error('ADB2C Error')),
|
||
});
|
||
|
||
overrideSendgridService(service, {
|
||
createMailContentFromEmailConfirmForNormalUser: async () => {
|
||
return { html: '', text: '', subject: '' };
|
||
},
|
||
sendMail: async () => {
|
||
return;
|
||
},
|
||
});
|
||
overrideAccountsRepositoryService(service, {
|
||
createAccount: async () => {
|
||
throw new Error('DB Error');
|
||
},
|
||
});
|
||
|
||
overrideBlobstorageService(service, {
|
||
createContainer: async () => {
|
||
return;
|
||
},
|
||
});
|
||
|
||
// DB上に用意されたデータが想定通りであるか確認
|
||
{
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(1);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(1);
|
||
}
|
||
|
||
try {
|
||
await service.createPartnerAccount(
|
||
context,
|
||
companyName,
|
||
country,
|
||
email,
|
||
adminName,
|
||
adminExternalId,
|
||
parent.tier,
|
||
);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toBe(HttpStatus.INTERNAL_SERVER_ERROR);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
|
||
// DB上に作成されたデータが想定通りであるか確認
|
||
{
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(1);
|
||
expect(accounts[0].tier).toBe(1);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(1);
|
||
expect(users[0].external_id).toBe(adminExternalId);
|
||
// ADB2Cユーザー削除メソッドが呼ばれているか確認
|
||
expect(b2cService.deleteUser).toBeCalledWith(partnerExternalId, context);
|
||
}
|
||
});
|
||
|
||
it('BlobStorageへの通信失敗が原因でアカウントの追加に失敗した場合、リカバリ処理としてADB2C,DB上のデータが削除され、500エラーが返却される', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const b2cService = module.get<AdB2cService>(AdB2cService);
|
||
|
||
const parentExternalId = 'parent_external_id';
|
||
|
||
// 第一階層のアカウントを作成
|
||
const { account: parent } = await makeTestAccount(
|
||
source,
|
||
{ tier: 1 },
|
||
{ external_id: parentExternalId },
|
||
);
|
||
|
||
const context = makeContext(parentExternalId);
|
||
const partnerExternalId = 'partner_external_id';
|
||
const companyName = 'partner_company_name';
|
||
const country = 'US';
|
||
const email = 'partner@example.com';
|
||
const username = 'partner_username';
|
||
|
||
overrideAdB2cService(service, {
|
||
createUser: async () => {
|
||
return { sub: partnerExternalId };
|
||
},
|
||
deleteUser: jest.fn(),
|
||
});
|
||
|
||
overrideSendgridService(service, {
|
||
sendMail: async () => {
|
||
return;
|
||
},
|
||
createMailContentFromEmailConfirmForNormalUser: async () => {
|
||
return { html: '', text: '', subject: '' };
|
||
},
|
||
});
|
||
|
||
overrideBlobstorageService(service, {
|
||
createContainer: async () => {
|
||
throw new Error();
|
||
},
|
||
});
|
||
|
||
// DB上に用意されたデータが想定通りであるか確認
|
||
{
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(1);
|
||
}
|
||
|
||
try {
|
||
await service.createPartnerAccount(
|
||
context,
|
||
companyName,
|
||
country,
|
||
email,
|
||
username,
|
||
parentExternalId,
|
||
TIERS.TIER1,
|
||
);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toBe(HttpStatus.INTERNAL_SERVER_ERROR);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
|
||
{
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(1);
|
||
expect(accounts[0].tier).toBe(parent.tier);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(1);
|
||
expect(users[0].external_id).toBe(parentExternalId);
|
||
// ADB2Cユーザー削除メソッドが呼ばれているか確認
|
||
expect(b2cService.deleteUser).toBeCalledWith(partnerExternalId, context);
|
||
}
|
||
});
|
||
|
||
it('BlobStorageへの通信失敗が原因でアカウントの追加に失敗した場合、リカバリ処理が実行されるが、そのリカバリ処理に失敗した場合、500エラーが返却される', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const b2cService = module.get<AdB2cService>(AdB2cService);
|
||
|
||
const parentExternalId = 'parent_external_id';
|
||
|
||
// 第一階層のアカウントを作成
|
||
const { account: parent } = await makeTestAccount(
|
||
source,
|
||
{ tier: 1 },
|
||
{ external_id: parentExternalId },
|
||
);
|
||
|
||
const context = makeContext(parentExternalId);
|
||
const partnerExternalId = 'partner_external_id';
|
||
const companyName = 'partner_company_name';
|
||
const country = 'US';
|
||
const email = 'partner@example.com';
|
||
const username = 'partner_username';
|
||
|
||
overrideAdB2cService(service, {
|
||
createUser: async () => {
|
||
return { sub: partnerExternalId };
|
||
},
|
||
deleteUser: jest.fn().mockRejectedValue(new Error('ADB2C Error')),
|
||
});
|
||
|
||
overrideSendgridService(service, {
|
||
sendMail: async () => {
|
||
return;
|
||
},
|
||
createMailContentFromEmailConfirmForNormalUser: async () => {
|
||
return { html: '', text: '', subject: '' };
|
||
},
|
||
});
|
||
|
||
overrideAccountsRepositoryService(service, {
|
||
deleteAccount: jest.fn().mockRejectedValue(new Error('DB Error')),
|
||
});
|
||
|
||
overrideBlobstorageService(service, {
|
||
createContainer: async () => {
|
||
throw new Error();
|
||
},
|
||
});
|
||
|
||
// DB上に用意されたデータが想定通りであるか確認
|
||
{
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(1);
|
||
}
|
||
|
||
try {
|
||
await service.createPartnerAccount(
|
||
context,
|
||
companyName,
|
||
country,
|
||
email,
|
||
username,
|
||
parentExternalId,
|
||
TIERS.TIER1,
|
||
);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toBe(HttpStatus.INTERNAL_SERVER_ERROR);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
|
||
{
|
||
// DB上に作成されたデータが想定通りであるか確認
|
||
// リカバリ処理が失敗した場合、DB上のデータは削除されない
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(2);
|
||
expect(accounts[0].tier).toBe(parent.tier);
|
||
expect(accounts[1].tier).toBe(parent.tier + 1);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(2);
|
||
expect(users[0].external_id).toBe(parentExternalId);
|
||
expect(users[1].external_id).toBe(partnerExternalId);
|
||
// ADB2Cユーザー削除メソッドが呼ばれているか確認
|
||
expect(b2cService.deleteUser).toBeCalledWith(partnerExternalId, context);
|
||
}
|
||
});
|
||
|
||
it('SendGridへの通信失敗によって500エラーが発生した場合、リカバリ処理としてADB2C,DB上のデータ,コンテナが削除され、500エラーが返却される', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const b2cService = module.get<AdB2cService>(AdB2cService);
|
||
const blobstorageService =
|
||
module.get<BlobstorageService>(BlobstorageService);
|
||
|
||
const parentExternalId = 'parent_external_id';
|
||
|
||
// 第一階層のアカウントを作成
|
||
const { account: parent } = await makeTestAccount(
|
||
source,
|
||
{ tier: 1 },
|
||
{ external_id: parentExternalId },
|
||
);
|
||
|
||
const context = makeContext(parentExternalId);
|
||
const partnerExternalId = 'partner_external_id';
|
||
const companyName = 'partner_company_name';
|
||
const country = 'US';
|
||
const email = 'partner@example.com';
|
||
const username = 'partner_username';
|
||
|
||
overrideAdB2cService(service, {
|
||
createUser: async () => {
|
||
return { sub: partnerExternalId };
|
||
},
|
||
deleteUser: jest.fn(),
|
||
});
|
||
|
||
overrideSendgridService(service, {
|
||
sendMail: async () => {
|
||
throw new Error();
|
||
},
|
||
createMailContentFromEmailConfirmForNormalUser: async () => {
|
||
return { html: '', text: '', subject: '' };
|
||
},
|
||
});
|
||
|
||
overrideBlobstorageService(service, {
|
||
createContainer: async () => {
|
||
return;
|
||
},
|
||
deleteContainer: jest.fn(),
|
||
});
|
||
|
||
// DB上に用意されたデータが想定通りであるか確認
|
||
{
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(1);
|
||
}
|
||
|
||
try {
|
||
await service.createPartnerAccount(
|
||
context,
|
||
companyName,
|
||
country,
|
||
email,
|
||
username,
|
||
parentExternalId,
|
||
TIERS.TIER1,
|
||
);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toBe(HttpStatus.INTERNAL_SERVER_ERROR);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
|
||
{
|
||
// DB上に作成されたデータが想定通りであるか確認
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(1);
|
||
expect(accounts[0].tier).toBe(parent.tier);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(1);
|
||
expect(users[0].external_id).toBe(parentExternalId);
|
||
// ADB2Cユーザー削除メソッドが呼ばれているか確認
|
||
expect(b2cService.deleteUser).toBeCalledWith(partnerExternalId, context);
|
||
// コンテナ削除メソッドが呼ばれているか確認
|
||
expect(blobstorageService.deleteContainer).toBeCalledWith(
|
||
context,
|
||
2, //新規作成したパートナーのアカウントID
|
||
country,
|
||
);
|
||
}
|
||
});
|
||
|
||
it('SendGridへの通信失敗によって500エラーが発生した場合、リカバリ処理が実行されるが、そのリカバリ処理に失敗した場合、500エラーが返却される', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const b2cService = module.get<AdB2cService>(AdB2cService);
|
||
const blobstorageService =
|
||
module.get<BlobstorageService>(BlobstorageService);
|
||
|
||
const parentExternalId = 'parent_external_id';
|
||
|
||
// 第一階層のアカウントを作成
|
||
const { account: parent } = await makeTestAccount(
|
||
source,
|
||
{ tier: 1 },
|
||
{ external_id: parentExternalId },
|
||
);
|
||
|
||
const context = makeContext(parentExternalId);
|
||
const partnerExternalId = 'partner_external_id';
|
||
const companyName = 'partner_company_name';
|
||
const country = 'US';
|
||
const email = 'partner@example.com';
|
||
const username = 'partner_username';
|
||
|
||
overrideAdB2cService(service, {
|
||
createUser: async () => {
|
||
return { sub: partnerExternalId };
|
||
},
|
||
deleteUser: jest.fn().mockRejectedValue(new Error('ADB2C Error')),
|
||
});
|
||
|
||
overrideSendgridService(service, {
|
||
sendMail: async () => {
|
||
throw new Error();
|
||
},
|
||
createMailContentFromEmailConfirmForNormalUser: async () => {
|
||
return { html: '', text: '', subject: '' };
|
||
},
|
||
});
|
||
|
||
overrideAccountsRepositoryService(service, {
|
||
deleteAccount: jest.fn().mockRejectedValue(new Error('DB Error')),
|
||
});
|
||
|
||
overrideBlobstorageService(service, {
|
||
createContainer: async () => {
|
||
return;
|
||
},
|
||
deleteContainer: jest.fn().mockRejectedValue(new Error('Blob Error')),
|
||
});
|
||
|
||
// DB上に用意されたデータが想定通りであるか確認
|
||
{
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(1);
|
||
}
|
||
|
||
try {
|
||
await service.createPartnerAccount(
|
||
context,
|
||
companyName,
|
||
country,
|
||
email,
|
||
username,
|
||
parentExternalId,
|
||
TIERS.TIER1,
|
||
);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toBe(HttpStatus.INTERNAL_SERVER_ERROR);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
|
||
{
|
||
// DB上に作成されたデータが想定通りであるか確認
|
||
// リカバリ処理が失敗したため、DB上のデータは削除されていない
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(2);
|
||
expect(accounts[0].tier).toBe(parent.tier);
|
||
expect(accounts[1].tier).toBe(parent.tier + 1);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(2);
|
||
expect(users[0].external_id).toBe(parentExternalId);
|
||
expect(users[1].external_id).toBe(partnerExternalId);
|
||
// ADB2Cユーザー削除メソッドが呼ばれているか確認
|
||
expect(b2cService.deleteUser).toBeCalledWith(partnerExternalId, context);
|
||
// コンテナ削除メソッドが呼ばれているか確認
|
||
expect(blobstorageService.deleteContainer).toBeCalledWith(
|
||
context,
|
||
2, //新規作成したパートナーのアカウントID
|
||
country,
|
||
);
|
||
}
|
||
});
|
||
|
||
it('既に登録済みのメールアドレスが原因でアカウントの追加に失敗した場合、エラーとなる(400エラー)', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const adminExternalId = 'ADMIN0001';
|
||
|
||
// 第一階層のアカウントを作成
|
||
const { account: parent } = await makeTestAccount(
|
||
source,
|
||
{ tier: 1 },
|
||
{ external_id: adminExternalId },
|
||
);
|
||
|
||
const context = makeContext('uuid');
|
||
const companyName = 'test_company_name';
|
||
const country = 'US';
|
||
const email = 'partner@example.com';
|
||
const adminName = 'partner_admin';
|
||
|
||
overrideAdB2cService(service, {
|
||
createUser: async () => {
|
||
// Conflictエラーを返す
|
||
return { reason: 'email', message: 'dummy' };
|
||
},
|
||
});
|
||
|
||
overrideSendgridService(service, {
|
||
createMailContentFromEmailConfirmForNormalUser: async () => {
|
||
return { html: '', text: '', subject: '' };
|
||
},
|
||
sendMail: async () => {
|
||
return;
|
||
},
|
||
});
|
||
|
||
overrideBlobstorageService(service, {
|
||
createContainer: async () => {
|
||
return;
|
||
},
|
||
});
|
||
|
||
// DB上に用意されたデータが想定通りであるか確認
|
||
{
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(1);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(1);
|
||
}
|
||
|
||
try {
|
||
await service.createPartnerAccount(
|
||
context,
|
||
companyName,
|
||
country,
|
||
email,
|
||
adminName,
|
||
adminExternalId,
|
||
parent.tier,
|
||
);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toBe(HttpStatus.BAD_REQUEST);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E010301'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
|
||
// DB上に作成されたデータが想定通りであるか確認
|
||
{
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(1);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(1);
|
||
}
|
||
});
|
||
});
|
||
|
||
describe('AccountsService', () => {
|
||
it('アカウントに紐づくライセンス情報を取得する', async () => {
|
||
const accountId = 1;
|
||
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
|
||
const userGroupsRepositoryMockValue =
|
||
makeDefaultUserGroupsRepositoryMockValue();
|
||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||
const accountsRepositoryMockValue =
|
||
makeDefaultAccountsRepositoryMockValue();
|
||
const configMockValue = makeDefaultConfigValue();
|
||
const sendGridMockValue = makeDefaultSendGridlValue();
|
||
const blobStorageMockValue = makeBlobStorageServiceMockValue();
|
||
const licensesRepositoryMockValue =
|
||
makeDefaultLicensesRepositoryMockValue();
|
||
const service = await makeAccountsServiceMock(
|
||
accountsRepositoryMockValue,
|
||
usersRepositoryMockValue,
|
||
userGroupsRepositoryMockValue,
|
||
adb2cParam,
|
||
configMockValue,
|
||
sendGridMockValue,
|
||
blobStorageMockValue,
|
||
licensesRepositoryMockValue,
|
||
);
|
||
expect(await service.getLicenseSummary(accountId)).toEqual(
|
||
expectedAccountLisenceCounts,
|
||
);
|
||
});
|
||
|
||
it('ライセンス情報が取得できない場合、エラーとなる', async () => {
|
||
const accountId = 1;
|
||
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
|
||
const userGroupsRepositoryMockValue =
|
||
makeDefaultUserGroupsRepositoryMockValue();
|
||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||
const accountsRepositoryMockValue =
|
||
makeDefaultAccountsRepositoryMockValue();
|
||
accountsRepositoryMockValue.getLicenseSummaryInfo = null;
|
||
const configMockValue = makeDefaultConfigValue();
|
||
const sendGridMockValue = makeDefaultSendGridlValue();
|
||
const blobStorageMockValue = makeBlobStorageServiceMockValue();
|
||
const licensesRepositoryMockValue =
|
||
makeDefaultLicensesRepositoryMockValue();
|
||
const service = await makeAccountsServiceMock(
|
||
accountsRepositoryMockValue,
|
||
usersRepositoryMockValue,
|
||
userGroupsRepositoryMockValue,
|
||
adb2cParam,
|
||
configMockValue,
|
||
sendGridMockValue,
|
||
blobStorageMockValue,
|
||
licensesRepositoryMockValue,
|
||
);
|
||
await expect(service.getLicenseSummary(accountId)).rejects.toEqual(
|
||
new HttpException(
|
||
makeErrorResponse('E009999'),
|
||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||
),
|
||
);
|
||
});
|
||
|
||
it('アカウントに紐づくタイピストユーザーを取得できる', async () => {
|
||
const externalId = 'externalId';
|
||
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
|
||
const userGroupsRepositoryMockValue =
|
||
makeDefaultUserGroupsRepositoryMockValue();
|
||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||
const accountsRepositoryMockValue =
|
||
makeDefaultAccountsRepositoryMockValue();
|
||
const configMockValue = makeDefaultConfigValue();
|
||
const sendGridMockValue = makeDefaultSendGridlValue();
|
||
const blobStorageMockValue = makeBlobStorageServiceMockValue();
|
||
const licensesRepositoryMockValue =
|
||
makeDefaultLicensesRepositoryMockValue();
|
||
const service = await makeAccountsServiceMock(
|
||
accountsRepositoryMockValue,
|
||
usersRepositoryMockValue,
|
||
userGroupsRepositoryMockValue,
|
||
adb2cParam,
|
||
configMockValue,
|
||
sendGridMockValue,
|
||
blobStorageMockValue,
|
||
licensesRepositoryMockValue,
|
||
);
|
||
expect(await service.getTypists(externalId)).toEqual([
|
||
{ id: 1, name: 'Typist1' },
|
||
{ id: 2, name: 'Typist2' },
|
||
{ id: 3, name: 'Typist3' },
|
||
]);
|
||
});
|
||
it('ユーザー取得に失敗した場合、エラーとなる', async () => {
|
||
const externalId = 'externalId';
|
||
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
|
||
usersRepositoryMockValue.findTypistUsers = new Error();
|
||
const userGroupsRepositoryMockValue =
|
||
makeDefaultUserGroupsRepositoryMockValue();
|
||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||
const accountsRepositoryMockValue =
|
||
makeDefaultAccountsRepositoryMockValue();
|
||
const configMockValue = makeDefaultConfigValue();
|
||
const sendGridMockValue = makeDefaultSendGridlValue();
|
||
const blobStorageMockValue = makeBlobStorageServiceMockValue();
|
||
const licensesRepositoryMockValue =
|
||
makeDefaultLicensesRepositoryMockValue();
|
||
const service = await makeAccountsServiceMock(
|
||
accountsRepositoryMockValue,
|
||
usersRepositoryMockValue,
|
||
userGroupsRepositoryMockValue,
|
||
adb2cParam,
|
||
configMockValue,
|
||
sendGridMockValue,
|
||
blobStorageMockValue,
|
||
licensesRepositoryMockValue,
|
||
);
|
||
await expect(service.getTypists(externalId)).rejects.toEqual(
|
||
new HttpException(
|
||
makeErrorResponse('E009999'),
|
||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||
),
|
||
);
|
||
});
|
||
it('ADB2Cからのユーザーの取得に失敗した場合、エラーとなる', async () => {
|
||
const externalId = 'externalId';
|
||
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
|
||
const userGroupsRepositoryMockValue =
|
||
makeDefaultUserGroupsRepositoryMockValue();
|
||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||
adb2cParam.getUsers = new Error();
|
||
const accountsRepositoryMockValue =
|
||
makeDefaultAccountsRepositoryMockValue();
|
||
const configMockValue = makeDefaultConfigValue();
|
||
const sendGridMockValue = makeDefaultSendGridlValue();
|
||
const blobStorageMockValue = makeBlobStorageServiceMockValue();
|
||
const licensesRepositoryMockValue =
|
||
makeDefaultLicensesRepositoryMockValue();
|
||
const service = await makeAccountsServiceMock(
|
||
accountsRepositoryMockValue,
|
||
usersRepositoryMockValue,
|
||
userGroupsRepositoryMockValue,
|
||
adb2cParam,
|
||
configMockValue,
|
||
sendGridMockValue,
|
||
blobStorageMockValue,
|
||
licensesRepositoryMockValue,
|
||
);
|
||
await expect(service.getTypists(externalId)).rejects.toEqual(
|
||
new HttpException(
|
||
makeErrorResponse('E009999'),
|
||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||
),
|
||
);
|
||
});
|
||
|
||
it('アカウントに紐づくユーザーグループを取得できる', async () => {
|
||
const externalId = 'externalId';
|
||
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
|
||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||
const accountsRepositoryMockValue =
|
||
makeDefaultAccountsRepositoryMockValue();
|
||
const userGroupsRepositoryMockValue =
|
||
makeDefaultUserGroupsRepositoryMockValue();
|
||
const configMockValue = makeDefaultConfigValue();
|
||
const sendGridMockValue = makeDefaultSendGridlValue();
|
||
const blobStorageMockValue = makeBlobStorageServiceMockValue();
|
||
const licensesRepositoryMockValue =
|
||
makeDefaultLicensesRepositoryMockValue();
|
||
const service = await makeAccountsServiceMock(
|
||
accountsRepositoryMockValue,
|
||
usersRepositoryMockValue,
|
||
userGroupsRepositoryMockValue,
|
||
adb2cParam,
|
||
configMockValue,
|
||
sendGridMockValue,
|
||
blobStorageMockValue,
|
||
licensesRepositoryMockValue,
|
||
);
|
||
|
||
expect(await service.getTypistGroups(externalId)).toEqual([
|
||
{ id: 1, name: 'GroupA' },
|
||
{ id: 2, name: 'GroupB' },
|
||
]);
|
||
});
|
||
it('ユーザーの取得に失敗した場合、エラーとなること', async () => {
|
||
const externalId = 'externalId';
|
||
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
|
||
usersRepositoryMockValue.findUserByExternalId = new Error('DB failed');
|
||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||
const accountsRepositoryMockValue =
|
||
makeDefaultAccountsRepositoryMockValue();
|
||
const userGroupsRepositoryMockValue =
|
||
makeDefaultUserGroupsRepositoryMockValue();
|
||
const configMockValue = makeDefaultConfigValue();
|
||
const sendGridMockValue = makeDefaultSendGridlValue();
|
||
const blobStorageMockValue = makeBlobStorageServiceMockValue();
|
||
const licensesRepositoryMockValue =
|
||
makeDefaultLicensesRepositoryMockValue();
|
||
const service = await makeAccountsServiceMock(
|
||
accountsRepositoryMockValue,
|
||
usersRepositoryMockValue,
|
||
userGroupsRepositoryMockValue,
|
||
adb2cParam,
|
||
configMockValue,
|
||
sendGridMockValue,
|
||
blobStorageMockValue,
|
||
licensesRepositoryMockValue,
|
||
);
|
||
|
||
await expect(service.getTypistGroups(externalId)).rejects.toEqual(
|
||
new HttpException(
|
||
makeErrorResponse('E009999'),
|
||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||
),
|
||
);
|
||
});
|
||
it('ユーザーグループの取得に失敗した場合、エラーとなること', async () => {
|
||
const externalId = 'externalId';
|
||
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
|
||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||
const accountsRepositoryMockValue =
|
||
makeDefaultAccountsRepositoryMockValue();
|
||
const userGroupsRepositoryMockValue =
|
||
makeDefaultUserGroupsRepositoryMockValue();
|
||
userGroupsRepositoryMockValue.getUserGroups = new Error('DB failed');
|
||
const configMockValue = makeDefaultConfigValue();
|
||
const sendGridMockValue = makeDefaultSendGridlValue();
|
||
const blobStorageMockValue = makeBlobStorageServiceMockValue();
|
||
const licensesRepositoryMockValue =
|
||
makeDefaultLicensesRepositoryMockValue();
|
||
const service = await makeAccountsServiceMock(
|
||
accountsRepositoryMockValue,
|
||
usersRepositoryMockValue,
|
||
userGroupsRepositoryMockValue,
|
||
adb2cParam,
|
||
configMockValue,
|
||
sendGridMockValue,
|
||
blobStorageMockValue,
|
||
licensesRepositoryMockValue,
|
||
);
|
||
|
||
await expect(service.getTypistGroups(externalId)).rejects.toEqual(
|
||
new HttpException(
|
||
makeErrorResponse('E009999'),
|
||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||
),
|
||
);
|
||
});
|
||
});
|
||
|
||
const expectedAccountLisenceCounts = {
|
||
totalLicense: 1,
|
||
allocatedLicense: 2,
|
||
reusableLicense: 3,
|
||
freeLicense: 4,
|
||
expiringWithin14daysLicense: 5,
|
||
issueRequesting: 6,
|
||
numberOfRequesting: 7,
|
||
shortage: 0,
|
||
storageSize: 0,
|
||
usedSize: 0,
|
||
isStorageAvailable: false,
|
||
};
|
||
|
||
describe('getPartnerAccount', () => {
|
||
let source: DataSource = 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 () => {
|
||
await source.destroy();
|
||
source = null;
|
||
});
|
||
|
||
it('パラメータのアカウント自身と子アカウントに紐つくライセンス情報を取得する', async () => {
|
||
const module = await makeTestingModule(source);
|
||
|
||
// 親アカウントと子アカウント2つ作成
|
||
const { id: parentAccountId } = (
|
||
await makeTestAccount(source, {
|
||
parent_account_id: 0,
|
||
tier: 1,
|
||
company_name: 'PARENTCORP',
|
||
})
|
||
).account;
|
||
|
||
const { id: childAccountId1 } = (
|
||
await makeTestAccount(source, {
|
||
parent_account_id: parentAccountId,
|
||
tier: 2,
|
||
company_name: 'CHILDCORP1',
|
||
})
|
||
).account;
|
||
|
||
const { id: childAccountId2 } = (
|
||
await makeTestAccount(source, {
|
||
parent_account_id: parentAccountId,
|
||
tier: 2,
|
||
company_name: 'CHILDCORP2',
|
||
})
|
||
).account;
|
||
|
||
// 第二にリクエストを投げる用の第三を作成
|
||
const { id: childAccountId3 } = (
|
||
await makeTestAccount(source, {
|
||
parent_account_id: childAccountId1,
|
||
tier: 3,
|
||
company_name: 'CHILDCORP3',
|
||
})
|
||
).account;
|
||
const { id: childAccountId4 } = (
|
||
await makeTestAccount(source, {
|
||
parent_account_id: childAccountId2,
|
||
tier: 3,
|
||
company_name: 'CHILDCORP4',
|
||
})
|
||
).account;
|
||
|
||
// 所有ライセンスを追加(親:3、子1:1、子2:2)
|
||
await createLicense(source, parentAccountId);
|
||
await createLicense(source, parentAccountId);
|
||
await createLicense(source, parentAccountId);
|
||
|
||
await createLicense(source, childAccountId1);
|
||
|
||
await createLicense(source, childAccountId2);
|
||
await createLicense(source, childAccountId2);
|
||
|
||
// ライセンス注文を追加(子1→親:10ライセンス、子2→親:5ライセンス)
|
||
await createLicenseOrder(
|
||
source,
|
||
childAccountId1,
|
||
parentAccountId,
|
||
10,
|
||
'TEST222',
|
||
);
|
||
await createLicenseOrder(source, childAccountId2, parentAccountId, 5);
|
||
|
||
// ライセンス注文を追加(子3→子1:10ライセンス、子4→子2:10ライセンス)
|
||
await createLicenseOrder(source, childAccountId3, childAccountId1, 10);
|
||
await createLicenseOrder(source, childAccountId4, childAccountId2, 10);
|
||
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const accountId = parentAccountId;
|
||
const offset = 0;
|
||
const limit = 20;
|
||
|
||
const response = await service.getPartnerLicenses(limit, offset, accountId);
|
||
|
||
expect(response.total).toBe(2);
|
||
|
||
expect(response.ownPartnerLicense.companyName).toBe('PARENTCORP');
|
||
expect(response.ownPartnerLicense.tier).toBe(1);
|
||
expect(response.ownPartnerLicense.stockLicense).toBe(3);
|
||
expect(response.ownPartnerLicense.issuedRequested).toBe(15);
|
||
expect(response.ownPartnerLicense.shortage).toBe(12);
|
||
|
||
expect(response.childrenPartnerLicenses[0].companyName).toBe('CHILDCORP1');
|
||
expect(response.childrenPartnerLicenses[0].tier).toBe(2);
|
||
expect(response.childrenPartnerLicenses[0].stockLicense).toBe(1);
|
||
expect(response.childrenPartnerLicenses[0].issueRequesting).toBe(10);
|
||
expect(response.childrenPartnerLicenses[0].shortage).toBe(9);
|
||
|
||
expect(response.childrenPartnerLicenses[1].companyName).toBe('CHILDCORP2');
|
||
expect(response.childrenPartnerLicenses[1].tier).toBe(2);
|
||
expect(response.childrenPartnerLicenses[1].stockLicense).toBe(2);
|
||
expect(response.childrenPartnerLicenses[1].shortage).toBe(8);
|
||
});
|
||
});
|
||
|
||
describe('getPartnerAccount', () => {
|
||
let source: DataSource = 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 () => {
|
||
await source.destroy();
|
||
source = null;
|
||
});
|
||
|
||
it('パラメータのアカウント自身と子アカウントに紐つくライセンス情報を取得する(第五のshortage確認)', async () => {
|
||
const module = await makeTestingModule(source);
|
||
|
||
// 親アカウントと子アカウント2つ作成
|
||
const { id: parentAccountId } = (
|
||
await makeTestAccount(source, {
|
||
parent_account_id: 0,
|
||
tier: 4,
|
||
company_name: 'PARENTCORP',
|
||
})
|
||
).account;
|
||
const { id: childAccountId1 } = (
|
||
await makeTestAccount(source, {
|
||
parent_account_id: parentAccountId,
|
||
tier: 5,
|
||
company_name: 'CHILDCORP1',
|
||
})
|
||
).account;
|
||
const { id: childAccountId2 } = (
|
||
await makeTestAccount(source, {
|
||
parent_account_id: parentAccountId,
|
||
tier: 5,
|
||
company_name: 'CHILDCORP2',
|
||
})
|
||
).account;
|
||
const { id: childAccountId3 } = (
|
||
await makeTestAccount(source, {
|
||
parent_account_id: parentAccountId,
|
||
tier: 5,
|
||
company_name: 'CHILDCORP3',
|
||
})
|
||
).account;
|
||
|
||
// 有効期限が14日後のライセンスを追加(5ライセンス)
|
||
const expiryDate = new Date();
|
||
expiryDate.setDate(expiryDate.getDate() + 14);
|
||
expiryDate.setHours(23, 59, 59, 999);
|
||
for (let i = 0; i < 5; i++) {
|
||
await createLicenseSetExpiryDateAndStatus(
|
||
source,
|
||
childAccountId1,
|
||
expiryDate,
|
||
'Allocated',
|
||
);
|
||
await createLicenseSetExpiryDateAndStatus(
|
||
source,
|
||
childAccountId2,
|
||
expiryDate,
|
||
'Allocated',
|
||
);
|
||
}
|
||
|
||
// 有効期限が15日後のライセンスを追加
|
||
expiryDate.setDate(expiryDate.getDate() + 15);
|
||
expiryDate.setHours(23, 59, 59, 999);
|
||
await createLicenseSetExpiryDateAndStatus(
|
||
source,
|
||
childAccountId3,
|
||
expiryDate,
|
||
'Allocated',
|
||
);
|
||
|
||
// 有効期限が迫っていないライセンスを追加(子1:各ステータスのライセンスを1つずつ、計4つ)
|
||
const status = ['Unallocated', 'Allocated', 'Reusable', 'Deleted'];
|
||
status.forEach(async (element) => {
|
||
await createLicenseSetExpiryDateAndStatus(
|
||
source,
|
||
childAccountId1,
|
||
new Date(2500, 1, 1, 23, 59, 59),
|
||
element,
|
||
);
|
||
});
|
||
|
||
// 有効期限が迫っていないライセンスを追加(子2:Unallocatedを10件)
|
||
for (let i = 0; i < 10; i++) {
|
||
await createLicenseSetExpiryDateAndStatus(
|
||
source,
|
||
childAccountId2,
|
||
new Date(2500, 1, 1, 23, 59, 59),
|
||
'Unallocated',
|
||
);
|
||
}
|
||
|
||
// 有効期限未設定のライセンスを1件追加(子1)
|
||
await createLicense(source, childAccountId1);
|
||
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const accountId = parentAccountId;
|
||
const offset = 0;
|
||
const limit = 20;
|
||
|
||
const response = await service.getPartnerLicenses(limit, offset, accountId);
|
||
|
||
// 有効期限間近(5件)+ 有効期限間近でない(3件)'Unallocated', 'Allocated', 'Reusable'+ 有効期限未設定(1件) → 9件
|
||
expect(response.childrenPartnerLicenses[0].stockLicense).toBe(9);
|
||
// 有効期限間近(5件) - {有効期限間近でない未割当(2件)'Unallocated', 'Reusable'+ 有効期限未設定(1件)} → 2件
|
||
expect(response.childrenPartnerLicenses[0].shortage).toBe(2);
|
||
|
||
// 有効期限間近(5件)+ 有効期限間近でない(10件) → 15件
|
||
expect(response.childrenPartnerLicenses[1].stockLicense).toBe(15);
|
||
// 有効期限間近(5件)- (有効期限間近でない未割当(10件)'Unallocated' + 有効期限未設定(1件)) → -5件 → 0件
|
||
expect(response.childrenPartnerLicenses[1].shortage).toBe(0);
|
||
|
||
expect(response.childrenPartnerLicenses[2].stockLicense).toBe(1);
|
||
// 有効期限が15日後のものはshortageにカウントされない
|
||
expect(response.childrenPartnerLicenses[2].shortage).toBe(0);
|
||
});
|
||
});
|
||
|
||
describe('getOrderHistories', () => {
|
||
let source: DataSource = 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 () => {
|
||
await source.destroy();
|
||
source = null;
|
||
});
|
||
|
||
it('指定したアカウントIDの注文履歴情報を取得できる', async () => {
|
||
const module = await makeTestingModule(source);
|
||
|
||
const targetAccountId = 10;
|
||
const targetParentAccountId = 14;
|
||
const now = new Date(); // 現在の時刻を取得
|
||
|
||
// 注文履歴情報の作成
|
||
await createLicenseOrder(
|
||
source,
|
||
targetAccountId,
|
||
targetParentAccountId,
|
||
10,
|
||
'TEST001',
|
||
new Date(now.getTime() + 60 * 60 * 1000),
|
||
);
|
||
await createLicenseOrder(
|
||
source,
|
||
targetAccountId,
|
||
targetParentAccountId,
|
||
10,
|
||
'TEST002',
|
||
new Date(now.getTime() + 60 * 60 * 1000 * 2),
|
||
);
|
||
await createLicenseOrder(
|
||
source,
|
||
targetAccountId,
|
||
targetParentAccountId,
|
||
10,
|
||
'TEST003',
|
||
new Date(now.getTime() + 60 * 60 * 1000 * 3),
|
||
);
|
||
await createLicenseOrder(
|
||
source,
|
||
targetAccountId,
|
||
targetParentAccountId,
|
||
10,
|
||
'TEST004',
|
||
new Date(now.getTime() + 60 * 60 * 1000 * 4),
|
||
);
|
||
await createLicenseOrder(
|
||
source,
|
||
targetAccountId,
|
||
targetParentAccountId,
|
||
10,
|
||
'TEST005',
|
||
new Date(now.getTime() + 60 * 60 * 1000 * 5),
|
||
);
|
||
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const accountId = targetAccountId;
|
||
const offset = 1;
|
||
const limit = 2;
|
||
|
||
const response = await service.getOrderHistories(limit, offset, accountId);
|
||
|
||
expect(response.total).toBe(5);
|
||
|
||
expect(response.orderHistories[0].poNumber).toBe('TEST004');
|
||
expect(response.orderHistories[1].poNumber).toBe('TEST003');
|
||
});
|
||
it('注文履歴情報の取得に失敗した場合、エラーとなる', async () => {
|
||
const limit = 0;
|
||
const offset = 0;
|
||
const accountId = 0;
|
||
const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue();
|
||
usersRepositoryMockValue.findTypistUsers = new Error();
|
||
const userGroupsRepositoryMockValue =
|
||
makeDefaultUserGroupsRepositoryMockValue();
|
||
const adb2cParam = makeDefaultAdB2cMockValue();
|
||
const accountsRepositoryMockValue =
|
||
makeDefaultAccountsRepositoryMockValue();
|
||
const configMockValue = makeDefaultConfigValue();
|
||
const sendGridMockValue = makeDefaultSendGridlValue();
|
||
const blobStorageMockValue = makeBlobStorageServiceMockValue();
|
||
const licensesRepositoryMockValue =
|
||
makeDefaultLicensesRepositoryMockValue();
|
||
licensesRepositoryMockValue.getLicenseOrderHistoryInfo = new Error(
|
||
'DB failed',
|
||
);
|
||
const service = await makeAccountsServiceMock(
|
||
accountsRepositoryMockValue,
|
||
usersRepositoryMockValue,
|
||
userGroupsRepositoryMockValue,
|
||
adb2cParam,
|
||
configMockValue,
|
||
sendGridMockValue,
|
||
blobStorageMockValue,
|
||
licensesRepositoryMockValue,
|
||
);
|
||
await expect(
|
||
service.getOrderHistories(limit, offset, accountId),
|
||
).rejects.toEqual(
|
||
new HttpException(
|
||
makeErrorResponse('E009999'),
|
||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||
),
|
||
);
|
||
});
|
||
});
|
||
|
||
describe('issueLicense', () => {
|
||
let source: DataSource = 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 () => {
|
||
await source.destroy();
|
||
source = null;
|
||
});
|
||
|
||
it('指定した注文を発行済みにする', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const now = new Date();
|
||
// 親と子アカウントを作成する
|
||
const { id: parentAccountId } = (
|
||
await makeTestAccount(source, {
|
||
parent_account_id: 0,
|
||
tier: 2,
|
||
company_name: 'PARENTCORP',
|
||
})
|
||
).account;
|
||
const { id: childAccountId } = (
|
||
await makeTestAccount(source, {
|
||
parent_account_id: parentAccountId,
|
||
tier: 3,
|
||
company_name: 'CHILDCORP1',
|
||
})
|
||
).account;
|
||
// 親と子のユーザーを作成する
|
||
const { external_id: externalId } = await makeTestUser(source, {
|
||
account_id: parentAccountId,
|
||
external_id: 'userId-parent',
|
||
role: 'admin',
|
||
});
|
||
|
||
// 親のライセンスを作成する(3個)
|
||
await createLicense(source, parentAccountId);
|
||
await createLicense(source, parentAccountId);
|
||
await createLicense(source, parentAccountId);
|
||
// 子から親への注文を作成する(2個)
|
||
await createLicenseOrder(
|
||
source,
|
||
childAccountId,
|
||
parentAccountId,
|
||
2,
|
||
'TEST001',
|
||
new Date(now.getTime() + 60 * 60 * 1000),
|
||
);
|
||
|
||
const context = makeContext('userId-parent');
|
||
|
||
// 注文を発行済みにする
|
||
await service.issueLicense(
|
||
context,
|
||
childAccountId,
|
||
externalId,
|
||
2,
|
||
'TEST001',
|
||
);
|
||
|
||
const issuedLicenses = await source.getRepository(License).find({
|
||
where: {
|
||
account_id: childAccountId,
|
||
status: 'Unallocated',
|
||
type: 'NORMAL',
|
||
},
|
||
});
|
||
expect(issuedLicenses.length).toEqual(2);
|
||
});
|
||
it('既に注文が発行済みの場合、エラーとなる', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const now = new Date();
|
||
// 親と子アカウントを作成する
|
||
const { id: parentAccountId } = (
|
||
await makeTestAccount(source, {
|
||
parent_account_id: 0,
|
||
tier: 2,
|
||
company_name: 'PARENTCORP',
|
||
})
|
||
).account;
|
||
const { id: childAccountId } = (
|
||
await makeTestAccount(source, {
|
||
parent_account_id: parentAccountId,
|
||
tier: 3,
|
||
company_name: 'CHILDCORP1',
|
||
})
|
||
).account;
|
||
// 親と子のユーザーを作成する
|
||
const { external_id: externalId } = await makeTestUser(source, {
|
||
account_id: parentAccountId,
|
||
external_id: 'userId-parent',
|
||
role: 'admin',
|
||
});
|
||
// 親のライセンスを作成する(3個)
|
||
await createLicense(source, parentAccountId);
|
||
await createLicense(source, parentAccountId);
|
||
await createLicense(source, parentAccountId);
|
||
// 子から親への注文を作成する(2個)
|
||
await createLicenseOrder(
|
||
source,
|
||
childAccountId,
|
||
parentAccountId,
|
||
2,
|
||
'TEST001',
|
||
new Date(now.getTime() + 60 * 60 * 1000),
|
||
);
|
||
|
||
const context = makeContext('userId-parent');
|
||
|
||
// 注文を発行済みにする
|
||
await service.issueLicense(
|
||
context,
|
||
childAccountId,
|
||
externalId,
|
||
2,
|
||
'TEST001',
|
||
);
|
||
|
||
//再度同じ処理を行う
|
||
await expect(
|
||
service.issueLicense(context, childAccountId, externalId, 2, 'TEST001'),
|
||
).rejects.toEqual(
|
||
new HttpException(makeErrorResponse('E010803'), HttpStatus.BAD_REQUEST),
|
||
);
|
||
});
|
||
it('ライセンスが不足している場合、エラーとなる', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const now = new Date();
|
||
// 親と子アカウントを作成する
|
||
const { id: parentAccountId } = (
|
||
await makeTestAccount(source, {
|
||
parent_account_id: 0,
|
||
tier: 2,
|
||
company_name: 'PARENTCORP',
|
||
})
|
||
).account;
|
||
const { id: childAccountId } = (
|
||
await makeTestAccount(source, {
|
||
parent_account_id: parentAccountId,
|
||
tier: 3,
|
||
company_name: 'CHILDCORP1',
|
||
})
|
||
).account;
|
||
// 親と子のユーザーを作成する
|
||
const { external_id: externalId } = await makeTestUser(source, {
|
||
account_id: parentAccountId,
|
||
external_id: 'userId-parent',
|
||
role: 'admin',
|
||
});
|
||
|
||
// 親のライセンスを作成する(3個)
|
||
await createLicense(source, parentAccountId);
|
||
await createLicense(source, parentAccountId);
|
||
await createLicense(source, parentAccountId);
|
||
// 子から親への注文を作成する(4個)
|
||
await createLicenseOrder(
|
||
source,
|
||
childAccountId,
|
||
parentAccountId,
|
||
4,
|
||
'TEST001',
|
||
new Date(now.getTime() + 60 * 60 * 1000),
|
||
);
|
||
|
||
const context = makeContext('userId-parent');
|
||
|
||
// 注文を発行済みにする
|
||
await expect(
|
||
service.issueLicense(context, childAccountId, externalId, 2, 'TEST001'),
|
||
).rejects.toEqual(
|
||
new HttpException(makeErrorResponse('E010804'), HttpStatus.BAD_REQUEST),
|
||
);
|
||
});
|
||
});
|
||
|
||
describe('getDealers', () => {
|
||
let source: DataSource = 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 () => {
|
||
await source.destroy();
|
||
source = null;
|
||
});
|
||
it('Dealerを取得できる', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const { id: accountId_1 } = (
|
||
await makeTestAccount(source, {
|
||
parent_account_id: 1,
|
||
tier: TIERS.TIER4,
|
||
country: 'JP',
|
||
company_name: 'DEALER_1',
|
||
})
|
||
).account;
|
||
const { id: accountId_2 } = (
|
||
await makeTestAccount(source, {
|
||
parent_account_id: 2,
|
||
tier: TIERS.TIER4,
|
||
country: 'JP',
|
||
company_name: 'DEALER_2',
|
||
})
|
||
).account;
|
||
const { id: accountId_3 } = (
|
||
await makeTestAccount(source, {
|
||
parent_account_id: 3,
|
||
tier: TIERS.TIER4,
|
||
country: 'JP',
|
||
company_name: 'DEALER_3',
|
||
})
|
||
).account;
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
|
||
expect(await service.getDealers()).toEqual({
|
||
dealers: [
|
||
{
|
||
country: 'JP',
|
||
id: accountId_1,
|
||
name: 'DEALER_1',
|
||
},
|
||
{
|
||
country: 'JP',
|
||
id: accountId_2,
|
||
name: 'DEALER_2',
|
||
},
|
||
{
|
||
country: 'JP',
|
||
id: accountId_3,
|
||
name: 'DEALER_3',
|
||
},
|
||
],
|
||
});
|
||
});
|
||
it('0件でもDealerを取得できる', async () => {
|
||
const module = await makeTestingModule(source);
|
||
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
|
||
expect(await service.getDealers()).toEqual({
|
||
dealers: [],
|
||
});
|
||
});
|
||
});
|
||
|
||
describe('createTypistGroup', () => {
|
||
let source: DataSource = 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 () => {
|
||
await source.destroy();
|
||
source = null;
|
||
});
|
||
it('TypistGroupを作成できる', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const adminExternalId = 'admin-external-id';
|
||
// 第五階層のアカウント作成
|
||
const { id: accountId } = (
|
||
await makeTestAccount(
|
||
source,
|
||
{ tier: 5 },
|
||
{ external_id: adminExternalId },
|
||
)
|
||
).account;
|
||
// 作成したアカウントにユーザーを3名追加する
|
||
const typiptUserExternalIds = [
|
||
'typist-user-external-id1',
|
||
'typist-user-external-id2',
|
||
'typist-user-external-id3',
|
||
];
|
||
const userIds: number[] = [];
|
||
for (const typiptUserExternalId of typiptUserExternalIds) {
|
||
const { id: userId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: typiptUserExternalId,
|
||
role: 'typist',
|
||
});
|
||
userIds.push(userId);
|
||
}
|
||
//作成したデータを確認
|
||
{
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(1);
|
||
expect(accounts[0].id).toBe(accountId);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(4);
|
||
}
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const typistGroupName = 'typist-group-name';
|
||
const typistUserIds = userIds;
|
||
const context = makeContext(adminExternalId);
|
||
await service.createTypistGroup(
|
||
context,
|
||
adminExternalId,
|
||
typistGroupName,
|
||
typistUserIds,
|
||
);
|
||
//実行結果を確認
|
||
{
|
||
const typistGroups = await getTypistGroup(source, accountId);
|
||
expect(typistGroups.length).toBe(1);
|
||
expect(typistGroups[0].name).toBe(typistGroupName);
|
||
|
||
const typistGroupUsers = await getTypistGroupMember(
|
||
source,
|
||
typistGroups[0].id,
|
||
);
|
||
expect(typistGroupUsers.length).toBe(3);
|
||
expect(typistGroupUsers.map((user) => user.user_id)).toEqual(userIds);
|
||
}
|
||
});
|
||
|
||
it('typistIdsにRole:typist以外のユーザーが含まれていた場合、400エラーを返却する', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const adminExternalId = 'admin-external-id';
|
||
// 第五階層のアカウント作成
|
||
const { id: accountId } = (
|
||
await makeTestAccount(
|
||
source,
|
||
{ tier: 5 },
|
||
{ external_id: adminExternalId },
|
||
)
|
||
).account;
|
||
// 作成したアカウントにユーザーを3名追加する
|
||
const typiptUserExternalIds = [
|
||
'typist-user-external-id1',
|
||
'typist-user-external-id2',
|
||
'typist-user-external-id3',
|
||
];
|
||
const userIds: number[] = [];
|
||
for (const typiptUserExternalId of typiptUserExternalIds) {
|
||
const { id: userId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: typiptUserExternalId,
|
||
role:
|
||
typiptUserExternalId === 'typist-user-external-id3'
|
||
? 'none'
|
||
: 'typist', //typist-user-external-id3のみRole:none,
|
||
});
|
||
userIds.push(userId);
|
||
}
|
||
//作成したデータを確認
|
||
{
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(1);
|
||
expect(accounts[0].id).toBe(accountId);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(4);
|
||
expect(users.filter((user) => user.role === 'typist').length).toBe(2);
|
||
}
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const typistGroupName = 'typist-group-name';
|
||
const typistUserIds = userIds;
|
||
const context = makeContext(adminExternalId);
|
||
await expect(
|
||
service.createTypistGroup(
|
||
context,
|
||
adminExternalId,
|
||
typistGroupName,
|
||
typistUserIds,
|
||
),
|
||
).rejects.toEqual(
|
||
new HttpException(makeErrorResponse('E010204'), HttpStatus.BAD_REQUEST),
|
||
);
|
||
});
|
||
it('typistIdsに存在しないユーザーが含まれていた場合、400エラーを返却する', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const adminExternalId = 'admin-external-id';
|
||
// 第五階層のアカウント作成
|
||
const { id: accountId } = (
|
||
await makeTestAccount(
|
||
source,
|
||
{ tier: 5 },
|
||
{ external_id: adminExternalId },
|
||
)
|
||
).account;
|
||
// 作成したアカウントにユーザーを3名追加する
|
||
const typiptUserExternalIds = [
|
||
'typist-user-external-id1',
|
||
'typist-user-external-id2',
|
||
'typist-user-external-id3',
|
||
];
|
||
const userIds: number[] = [];
|
||
for (const typiptUserExternalId of typiptUserExternalIds) {
|
||
const { id: userId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: typiptUserExternalId,
|
||
role: 'typist',
|
||
});
|
||
userIds.push(userId);
|
||
}
|
||
//作成したデータを確認
|
||
{
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(1);
|
||
expect(accounts[0].id).toBe(accountId);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(4);
|
||
}
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const typistGroupName = 'typist-group-name';
|
||
const typistUserIds = [...userIds, 9999]; //存在しないユーザーIDを追加
|
||
const context = makeContext(adminExternalId);
|
||
await expect(
|
||
service.createTypistGroup(
|
||
context,
|
||
adminExternalId,
|
||
typistGroupName,
|
||
typistUserIds,
|
||
),
|
||
).rejects.toEqual(
|
||
new HttpException(makeErrorResponse('E010204'), HttpStatus.BAD_REQUEST),
|
||
);
|
||
});
|
||
it('DBアクセスに失敗した場合、500エラーを返却する', async () => {
|
||
const module = await makeTestingModule(source);
|
||
const adminExternalId = 'admin-external-id';
|
||
// 第五階層のアカウント作成
|
||
const { id: accountId } = (
|
||
await makeTestAccount(
|
||
source,
|
||
{ tier: 5 },
|
||
{ external_id: adminExternalId },
|
||
)
|
||
).account;
|
||
// 作成したアカウントにユーザーを3名追加する
|
||
const typiptUserExternalIds = [
|
||
'typist-user-external-id1',
|
||
'typist-user-external-id2',
|
||
'typist-user-external-id3',
|
||
];
|
||
const userIds: number[] = [];
|
||
for (const typiptUserExternalId of typiptUserExternalIds) {
|
||
const { id: userId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: typiptUserExternalId,
|
||
role: 'typist',
|
||
});
|
||
userIds.push(userId);
|
||
}
|
||
//作成したデータを確認
|
||
{
|
||
const accounts = await getAccounts(source);
|
||
expect(accounts.length).toBe(1);
|
||
expect(accounts[0].id).toBe(accountId);
|
||
const users = await getUsers(source);
|
||
expect(users.length).toBe(4);
|
||
}
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const typistGroupName = 'typist-group-name';
|
||
const typistUserIds = userIds;
|
||
const context = makeContext(adminExternalId);
|
||
//DBアクセスに失敗するようにする
|
||
const typistGroupService = module.get<UserGroupsRepositoryService>(
|
||
UserGroupsRepositoryService,
|
||
);
|
||
typistGroupService.createTypistGroup = jest
|
||
.fn()
|
||
.mockRejectedValue('DB failed');
|
||
|
||
await expect(
|
||
service.createTypistGroup(
|
||
context,
|
||
adminExternalId,
|
||
typistGroupName,
|
||
typistUserIds,
|
||
),
|
||
).rejects.toEqual(
|
||
new HttpException(
|
||
makeErrorResponse('E009999'),
|
||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||
),
|
||
);
|
||
});
|
||
});
|
||
|
||
describe('getTypistGroup', () => {
|
||
let source: DataSource = 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 () => {
|
||
await source.destroy();
|
||
source = null;
|
||
});
|
||
it('指定したIDのTypistGroupを取得できる', async () => {
|
||
const module = await makeTestingModule(source);
|
||
// 第五階層のアカウント作成
|
||
const { account, admin } = await makeTestAccount(source, { tier: 5 });
|
||
|
||
// 作成したアカウントにユーザーを3名追加する
|
||
const typiptUserExternalIds = [
|
||
'typist-user-external-id1',
|
||
'typist-user-external-id2',
|
||
'typist-user-external-id3',
|
||
];
|
||
const userIds: number[] = [];
|
||
for (const typiptUserExternalId of typiptUserExternalIds) {
|
||
const { id: userId } = await makeTestUser(source, {
|
||
account_id: account.id,
|
||
external_id: typiptUserExternalId,
|
||
role: USER_ROLES.TYPIST,
|
||
});
|
||
userIds.push(userId);
|
||
}
|
||
|
||
// アカウントにタイピストグループを作成する
|
||
const typistGroupName = 'typist-group-name';
|
||
|
||
const { id: typistGroupId } = await createTypistGroup(
|
||
source,
|
||
account.id,
|
||
typistGroupName,
|
||
userIds,
|
||
);
|
||
|
||
//作成したデータを確認
|
||
{
|
||
const group = await getTypistGroup(source, account.id);
|
||
expect(group.length).toBe(1);
|
||
expect(group[0].name).toBe(typistGroupName);
|
||
const groupUsers = await getTypistGroupMember(source, group[0].id);
|
||
expect(groupUsers.length).toBe(3);
|
||
expect(groupUsers.map((user) => user.user_id)).toEqual(userIds);
|
||
}
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const context = makeContext(admin.external_id);
|
||
const typistGroup = await service.getTypistGroup(
|
||
context,
|
||
admin.external_id,
|
||
typistGroupId,
|
||
);
|
||
//実行結果を確認
|
||
{
|
||
const typistGroups = await getTypistGroup(source, account.id);
|
||
expect(typistGroups.length).toBe(1);
|
||
expect(typistGroup.typistGroupName).toBe(typistGroupName);
|
||
expect(typistGroup.typistIds.length).toBe(3);
|
||
expect(typistGroup.typistIds).toEqual(userIds);
|
||
}
|
||
});
|
||
|
||
it('指定したタイピストグループIDのタイピストグループが存在しない場合、400エラーを返却する', async () => {
|
||
const module = await makeTestingModule(source);
|
||
// 第五階層のアカウント作成
|
||
const { account, admin } = await makeTestAccount(source, { tier: 5 });
|
||
// 作成したアカウントにユーザーを3名追加する
|
||
const typiptUserExternalIds = [
|
||
'typist-user-external-id1',
|
||
'typist-user-external-id2',
|
||
'typist-user-external-id3',
|
||
];
|
||
const userIds: number[] = [];
|
||
for (const typiptUserExternalId of typiptUserExternalIds) {
|
||
const { id: userId } = await makeTestUser(source, {
|
||
account_id: account.id,
|
||
external_id: typiptUserExternalId,
|
||
role: USER_ROLES.TYPIST,
|
||
});
|
||
userIds.push(userId);
|
||
}
|
||
|
||
// アカウントにタイピストグループを作成する
|
||
const typistGroupName = 'typist-group-name';
|
||
await createTypistGroup(source, account.id, typistGroupName, userIds);
|
||
|
||
//作成したデータを確認
|
||
{
|
||
const group = await getTypistGroup(source, account.id);
|
||
expect(group.length).toBe(1);
|
||
expect(group[0].name).toBe(typistGroupName);
|
||
const groupUsers = await getTypistGroupMember(source, group[0].id);
|
||
expect(groupUsers.length).toBe(3);
|
||
expect(groupUsers.map((user) => user.user_id)).toEqual(userIds);
|
||
}
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const context = makeContext(admin.external_id);
|
||
|
||
try {
|
||
await service.getTypistGroup(context, admin.external_id, 999);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E010908'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
});
|
||
|
||
it('DBアクセスに失敗した場合、500エラーを返却する', async () => {
|
||
const module = await makeTestingModule(source);
|
||
// 第五階層のアカウント作成
|
||
const { account, admin } = await makeTestAccount(source, { tier: 5 });
|
||
// 作成したアカウントにユーザーを3名追加する
|
||
const typiptUserExternalIds = [
|
||
'typist-user-external-id1',
|
||
'typist-user-external-id2',
|
||
'typist-user-external-id3',
|
||
];
|
||
const userIds: number[] = [];
|
||
for (const typiptUserExternalId of typiptUserExternalIds) {
|
||
const { id: userId } = await makeTestUser(source, {
|
||
account_id: account.id,
|
||
external_id: typiptUserExternalId,
|
||
role: USER_ROLES.TYPIST,
|
||
});
|
||
userIds.push(userId);
|
||
}
|
||
|
||
// アカウントにタイピストグループを作成する
|
||
const typistGroupName = 'typist-group-name';
|
||
|
||
const { id: typistGroupId } = await createTypistGroup(
|
||
source,
|
||
account.id,
|
||
typistGroupName,
|
||
userIds,
|
||
);
|
||
|
||
//作成したデータを確認
|
||
{
|
||
const group = await getTypistGroup(source, account.id);
|
||
expect(group.length).toBe(1);
|
||
expect(group[0].name).toBe(typistGroupName);
|
||
const groupUsers = await getTypistGroupMember(source, group[0].id);
|
||
expect(groupUsers.length).toBe(3);
|
||
expect(groupUsers.map((user) => user.user_id)).toEqual(userIds);
|
||
}
|
||
const service = module.get<AccountsService>(AccountsService);
|
||
const context = makeContext(admin.external_id);
|
||
|
||
//DBアクセスに失敗するようにする
|
||
const typistGroupService = module.get<UserGroupsRepositoryService>(
|
||
UserGroupsRepositoryService,
|
||
);
|
||
typistGroupService.getTypistGroup = jest
|
||
.fn()
|
||
.mockRejectedValue('DB failed');
|
||
|
||
try {
|
||
await service.getTypistGroup(context, admin.external_id, typistGroupId);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
});
|
||
});
|