2402 lines
70 KiB
TypeScript
2402 lines
70 KiB
TypeScript
import {
|
||
NewAllocatedLicenseExpirationDate,
|
||
NewTrialLicenseExpirationDate,
|
||
} from './types/types';
|
||
import { makeErrorResponse } from '../../common/error/makeErrorResponse';
|
||
import { HttpException, HttpStatus } from '@nestjs/common';
|
||
import { LicensesService } from './licenses.service';
|
||
import { makeTestingModule } from '../../common/test/modules';
|
||
import { DataSource } from 'typeorm';
|
||
import {
|
||
createCardLicense,
|
||
createLicense,
|
||
createCardLicenseIssue,
|
||
createLicenseAllocationHistory,
|
||
selectCardLicensesCount,
|
||
selectCardLicense,
|
||
selectLicense,
|
||
selectLicenseAllocationHistory,
|
||
createOrder,
|
||
selectOrderLicense,
|
||
selectIssuedLicensesAndLicenseOrders,
|
||
} from './test/utility';
|
||
import { UsersService } from '../users/users.service';
|
||
import { Context, makeContext } from '../../common/log';
|
||
import {
|
||
ADB2C_SIGN_IN_TYPE,
|
||
LICENSE_ALLOCATED_STATUS,
|
||
LICENSE_ISSUE_STATUS,
|
||
LICENSE_TYPE,
|
||
} from '../../constants';
|
||
import {
|
||
makeHierarchicalAccounts,
|
||
makeTestAccount,
|
||
makeTestSimpleAccount,
|
||
makeTestUser,
|
||
} from '../../common/test/utility';
|
||
import { LicensesRepositoryService } from '../../repositories/licenses/licenses.repository.service';
|
||
import {
|
||
overrideAdB2cService,
|
||
overrideSendgridService,
|
||
} from '../../common/test/overrides';
|
||
import { truncateAllTable } from '../../common/test/init';
|
||
import { TestLogger } from '../../common/test/logger';
|
||
import { SendGridService } from '../../gateways/sendgrid/sendgrid.service';
|
||
|
||
describe('ライセンス注文', () => {
|
||
let source: DataSource | null = null;
|
||
beforeAll(async () => {
|
||
if (source == null) {
|
||
source = await (async () => {
|
||
const s = new DataSource({
|
||
type: 'mysql',
|
||
host: 'test_mysql_db',
|
||
port: 3306,
|
||
username: 'user',
|
||
password: 'password',
|
||
database: 'odms',
|
||
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
|
||
synchronize: false, // trueにすると自動的にmigrationが行われるため注意
|
||
logger: new TestLogger('none'),
|
||
logging: true,
|
||
});
|
||
return await s.initialize();
|
||
})();
|
||
}
|
||
});
|
||
|
||
beforeEach(async () => {
|
||
if (source) {
|
||
await truncateAllTable(source);
|
||
}
|
||
});
|
||
|
||
afterAll(async () => {
|
||
await source?.destroy();
|
||
source = null;
|
||
});
|
||
|
||
it('ライセンス注文が完了する', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { id: accountId, parent_account_id: parentAccountId } =
|
||
await makeTestSimpleAccount(source, {
|
||
parent_account_id: 2,
|
||
});
|
||
const { external_id: externalId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'userId',
|
||
role: 'admin',
|
||
});
|
||
|
||
const poNumber = 'test1';
|
||
const orderCount = 100;
|
||
|
||
const service = module.get<LicensesService>(LicensesService);
|
||
|
||
const context = makeContext(`uuidv4`, 'requestId');
|
||
await service.licenseOrders(context, externalId, poNumber, orderCount);
|
||
const dbSelectResult = await selectOrderLicense(
|
||
source,
|
||
accountId,
|
||
poNumber,
|
||
);
|
||
|
||
expect(dbSelectResult.orderLicense?.po_number).toEqual(poNumber);
|
||
expect(dbSelectResult.orderLicense?.quantity).toEqual(orderCount);
|
||
expect(dbSelectResult.orderLicense?.from_account_id).toEqual(accountId);
|
||
expect(dbSelectResult.orderLicense?.to_account_id).toEqual(parentAccountId);
|
||
expect(dbSelectResult.orderLicense?.status).toEqual('Issue Requesting');
|
||
// ライセンス種別のデフォルト値が埋まっていること
|
||
expect(dbSelectResult.orderLicense?.type).toEqual(LICENSE_TYPE.NORMAL);
|
||
});
|
||
|
||
it('POナンバー重複時、エラーとなる', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { id: accountId } = await makeTestSimpleAccount(source, {
|
||
parent_account_id: 2,
|
||
});
|
||
const { external_id: externalId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'userId',
|
||
role: 'admin',
|
||
});
|
||
|
||
const poNumber = 'test1';
|
||
const orderCount = 100;
|
||
|
||
const service = module.get<LicensesService>(LicensesService);
|
||
|
||
const context = makeContext(`uuidv4`, 'requestId');
|
||
try {
|
||
await service.licenseOrders(context, externalId, poNumber, orderCount);
|
||
await service.licenseOrders(context, externalId, poNumber, orderCount);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E010401'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
});
|
||
|
||
it('ユーザID取得できなかった場合、エラーとなる', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { id: accountId } = await makeTestSimpleAccount(source, {
|
||
parent_account_id: 2,
|
||
});
|
||
const { external_id: externalId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'useId',
|
||
role: 'admin',
|
||
});
|
||
|
||
const poNumber = 'test1';
|
||
const orderCount = 100;
|
||
|
||
// 存在しないのユーザーIDを作成
|
||
const notExistUserId = 'notExistId';
|
||
|
||
const service = module.get<LicensesService>(LicensesService);
|
||
|
||
const context = makeContext(`uuidv4`, 'requestId');
|
||
|
||
try {
|
||
await service.licenseOrders(
|
||
context,
|
||
notExistUserId,
|
||
poNumber,
|
||
orderCount,
|
||
);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E010204'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
});
|
||
|
||
it('親ユーザID取得できなかった場合、エラーとなる', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { id: accountId } = await makeTestSimpleAccount(source, {
|
||
parent_account_id: undefined,
|
||
});
|
||
const { external_id: externalId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'userId',
|
||
role: 'admin',
|
||
});
|
||
|
||
const poNumber = 'test1';
|
||
const orderCount = 100;
|
||
|
||
const service = module.get<LicensesService>(LicensesService);
|
||
|
||
const context = makeContext(`uuidv4`, 'requestId');
|
||
try {
|
||
await service.licenseOrders(context, externalId, poNumber, orderCount);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E010501'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
});
|
||
});
|
||
|
||
describe('カードライセンス発行', () => {
|
||
let source: DataSource | null = null;
|
||
beforeAll(async () => {
|
||
if (source == null) {
|
||
source = await (async () => {
|
||
const s = new DataSource({
|
||
type: 'mysql',
|
||
host: 'test_mysql_db',
|
||
port: 3306,
|
||
username: 'user',
|
||
password: 'password',
|
||
database: 'odms',
|
||
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
|
||
synchronize: false, // trueにすると自動的にmigrationが行われるため注意
|
||
logger: new TestLogger('none'),
|
||
logging: true,
|
||
});
|
||
return await s.initialize();
|
||
})();
|
||
}
|
||
});
|
||
|
||
beforeEach(async () => {
|
||
if (source) {
|
||
await truncateAllTable(source);
|
||
}
|
||
});
|
||
|
||
afterAll(async () => {
|
||
await source?.destroy();
|
||
source = null;
|
||
});
|
||
|
||
it('カードライセンス発行が完了する(発行数が合っているか確認)', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { id: accountId } = await makeTestSimpleAccount(source);
|
||
const { external_id: externalId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'userId',
|
||
role: 'admin',
|
||
author_id: undefined,
|
||
});
|
||
|
||
const service = module.get<LicensesService>(LicensesService);
|
||
const issueCount = 500;
|
||
const context = makeContext(`uuidv4`, 'requestId');
|
||
await service.issueCardLicenseKeys(context, externalId, issueCount);
|
||
const dbSelectResult = await selectCardLicensesCount(source);
|
||
expect(dbSelectResult.count).toEqual(issueCount);
|
||
});
|
||
|
||
it('DBアクセスに失敗した場合、500エラーを返却する', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { id: accountId } = await makeTestSimpleAccount(source);
|
||
const { external_id: externalId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'userId',
|
||
role: 'admin',
|
||
author_id: undefined,
|
||
});
|
||
|
||
const service = module.get<LicensesService>(LicensesService);
|
||
const issueCount = 500;
|
||
const context = makeContext(`uuidv4`, 'requestId');
|
||
|
||
//DBアクセスに失敗するようにする
|
||
const licensesService = module.get<LicensesRepositoryService>(
|
||
LicensesRepositoryService,
|
||
);
|
||
licensesService.createCardLicenses = jest
|
||
.fn()
|
||
.mockRejectedValue('DB failed');
|
||
|
||
try {
|
||
await service.issueCardLicenseKeys(context, externalId, issueCount);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
});
|
||
});
|
||
|
||
describe('カードライセンスを取り込む', () => {
|
||
let source: DataSource | null = null;
|
||
beforeAll(async () => {
|
||
if (source == null) {
|
||
source = await (async () => {
|
||
const s = new DataSource({
|
||
type: 'mysql',
|
||
host: 'test_mysql_db',
|
||
port: 3306,
|
||
username: 'user',
|
||
password: 'password',
|
||
database: 'odms',
|
||
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
|
||
synchronize: false, // trueにすると自動的にmigrationが行われるため注意
|
||
logger: new TestLogger('none'),
|
||
logging: true,
|
||
});
|
||
return await s.initialize();
|
||
})();
|
||
}
|
||
});
|
||
|
||
beforeEach(async () => {
|
||
if (source) {
|
||
await truncateAllTable(source);
|
||
}
|
||
});
|
||
|
||
afterAll(async () => {
|
||
await source?.destroy();
|
||
source = null;
|
||
});
|
||
it('カードライセンス取り込みが完了する', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { id: accountId } = await makeTestSimpleAccount(source);
|
||
const { external_id: externalId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'userId',
|
||
role: 'admin',
|
||
author_id: undefined,
|
||
});
|
||
|
||
const cardLicenseKey = 'WZCETXC0Z9PQZ9GKRGGY';
|
||
const defaultAccountId = 150;
|
||
const license_id = 50;
|
||
const issueId = 100;
|
||
|
||
await createLicense(
|
||
source,
|
||
license_id,
|
||
null,
|
||
defaultAccountId,
|
||
LICENSE_TYPE.CARD,
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
await createCardLicense(source, license_id, issueId, cardLicenseKey);
|
||
await createCardLicenseIssue(source, issueId);
|
||
|
||
const service = module.get<LicensesService>(LicensesService);
|
||
const context = makeContext(`uuidv4`, 'requestId');
|
||
|
||
await service.activateCardLicenseKey(context, externalId, cardLicenseKey);
|
||
const dbSelectResultFromCardLicense = await selectCardLicense(
|
||
source,
|
||
cardLicenseKey,
|
||
);
|
||
const dbSelectResultFromLicense = await selectLicense(source, license_id);
|
||
expect(
|
||
dbSelectResultFromCardLicense?.cardLicense?.activated_at,
|
||
).toBeDefined();
|
||
expect(dbSelectResultFromLicense?.license?.account_id).toEqual(accountId);
|
||
});
|
||
|
||
it('取込可能なライセンスのみが取得できる', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
// 明日の日付を取得
|
||
// ミリ秒以下は切り捨てる
|
||
const tommorow = new Date();
|
||
tommorow.setDate(tommorow.getDate() + 1);
|
||
tommorow.setMilliseconds(0);
|
||
|
||
const { id: accountId } = await makeTestSimpleAccount(source);
|
||
const { external_id: externalId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'userId',
|
||
role: 'admin',
|
||
author_id: undefined,
|
||
});
|
||
|
||
// ライセンスを作成する
|
||
// 1件目
|
||
await createLicense(
|
||
source,
|
||
1,
|
||
new Date(tommorow.getTime() + 60 * 60 * 1000),
|
||
accountId,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
// 2件目、expiry_dateがnull(OneYear)
|
||
await createLicense(
|
||
source,
|
||
2,
|
||
null,
|
||
accountId,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
// 3件目、1件目と同じ有効期限
|
||
await createLicense(
|
||
source,
|
||
3,
|
||
new Date(tommorow.getTime() + 60 * 60 * 1000),
|
||
accountId,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
// 4件目、expiry_dateが一番遠いデータ
|
||
await createLicense(
|
||
source,
|
||
4,
|
||
new Date(tommorow.getTime() + 60 * 60 * 1000 * 2),
|
||
accountId,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
// 5件目、expiry_dateがnull(OneYear)
|
||
await createLicense(
|
||
source,
|
||
5,
|
||
null,
|
||
accountId,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
// 6件目、ライセンス状態が割当済
|
||
await createLicense(
|
||
source,
|
||
6,
|
||
new Date(tommorow.getTime() + 60 * 60 * 1000 * 2),
|
||
accountId,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.ALLOCATED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
// 7件目、ライセンス状態が削除済
|
||
await createLicense(
|
||
source,
|
||
7,
|
||
new Date(tommorow.getTime() + 60 * 60 * 1000 * 2),
|
||
accountId,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.DELETED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
// 8件目、別アカウントの未割当のライセンス
|
||
await createLicense(
|
||
source,
|
||
8,
|
||
new Date(tommorow.getTime() + 60 * 60 * 1000),
|
||
accountId + 1,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
// 9件目、有効期限切れのライセンス
|
||
await createLicense(
|
||
source,
|
||
9,
|
||
new Date(tommorow.getTime() - 60 * 60 * 1000 * 24),
|
||
accountId,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
const service = module.get<LicensesService>(LicensesService);
|
||
const context = makeContext('userId', 'requestId');
|
||
const response = await service.getAllocatableLicenses(context, externalId);
|
||
// 対象外のデータは取得していないことを確認する
|
||
expect(response.allocatableLicenses.length).toBe(5);
|
||
// ソートして取得されていることを確認する
|
||
// (expiry_dateがnullを最優先、次に有効期限が遠い順(同じ有効期限の場合はID昇順)
|
||
expect(response.allocatableLicenses[0].licenseId).toBe(2);
|
||
expect(response.allocatableLicenses[1].licenseId).toBe(5);
|
||
expect(response.allocatableLicenses[2].licenseId).toBe(4);
|
||
expect(response.allocatableLicenses[3].licenseId).toBe(1);
|
||
expect(response.allocatableLicenses[4].licenseId).toBe(3);
|
||
});
|
||
|
||
it('カードライセンス取り込みに失敗した場合、エラーになる(ライセンスが存在しないエラー)', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { id: accountId } = await makeTestSimpleAccount(source);
|
||
const { external_id: externalId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'userId',
|
||
role: 'admin',
|
||
author_id: undefined,
|
||
});
|
||
|
||
//存在しないライセンスキーを作成
|
||
const notExistCardLicenseKey = 'XXCETXC0Z9PQZ9GKRGGY';
|
||
|
||
const service = module.get<LicensesService>(LicensesService);
|
||
const context = makeContext(`uuidv4`, 'requestId');
|
||
|
||
try {
|
||
await service.activateCardLicenseKey(
|
||
context,
|
||
externalId,
|
||
notExistCardLicenseKey,
|
||
);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E010801'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
});
|
||
|
||
it('カードライセンス取り込みに失敗した場合、エラーになる(ライセンスが既に取り込まれているエラー)', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { id: accountId } = await makeTestSimpleAccount(source);
|
||
const { external_id: externalId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'userId',
|
||
role: 'admin',
|
||
author_id: undefined,
|
||
});
|
||
|
||
const cardLicenseKey = 'WZCETXC0Z9PQZ9GKRGGY';
|
||
const defaultAccountId = 150;
|
||
const license_id = 50;
|
||
const issueId = 100;
|
||
|
||
await createLicense(
|
||
source,
|
||
license_id,
|
||
null,
|
||
defaultAccountId,
|
||
LICENSE_TYPE.CARD,
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
await createCardLicense(source, license_id, issueId, cardLicenseKey);
|
||
await createCardLicenseIssue(source, issueId);
|
||
|
||
const service = module.get<LicensesService>(LicensesService);
|
||
const context = makeContext(`uuidv4`, 'requestId');
|
||
|
||
try {
|
||
await service.activateCardLicenseKey(context, externalId, cardLicenseKey);
|
||
await service.activateCardLicenseKey(context, externalId, cardLicenseKey);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toEqual(HttpStatus.BAD_REQUEST);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E010802'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
});
|
||
|
||
it('DBアクセスに失敗した場合、500エラーを返却する', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { id: accountId } = await makeTestSimpleAccount(source);
|
||
const { external_id: externalId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'userId',
|
||
role: 'admin',
|
||
author_id: undefined,
|
||
});
|
||
|
||
const service = module.get<LicensesService>(LicensesService);
|
||
const context = makeContext(`uuidv4`, 'requestId');
|
||
const cardLicenseKey = 'WZCETXC0Z9PQZ9GKRGGY';
|
||
|
||
//DBアクセスに失敗するようにする
|
||
const licensesService = module.get<LicensesRepositoryService>(
|
||
LicensesRepositoryService,
|
||
);
|
||
licensesService.activateCardLicense = jest
|
||
.fn()
|
||
.mockRejectedValue('DB failed');
|
||
try {
|
||
await service.activateCardLicenseKey(context, externalId, cardLicenseKey);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
});
|
||
});
|
||
|
||
describe('ライセンス割り当て', () => {
|
||
let source: DataSource | null = null;
|
||
beforeAll(async () => {
|
||
if (source == null) {
|
||
source = await (async () => {
|
||
const s = new DataSource({
|
||
type: 'mysql',
|
||
host: 'test_mysql_db',
|
||
port: 3306,
|
||
username: 'user',
|
||
password: 'password',
|
||
database: 'odms',
|
||
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
|
||
synchronize: false, // trueにすると自動的にmigrationが行われるため注意
|
||
logger: new TestLogger('none'),
|
||
logging: true,
|
||
});
|
||
return await s.initialize();
|
||
})();
|
||
}
|
||
});
|
||
|
||
beforeEach(async () => {
|
||
if (source) {
|
||
await truncateAllTable(source);
|
||
}
|
||
});
|
||
|
||
afterAll(async () => {
|
||
await source?.destroy();
|
||
source = null;
|
||
});
|
||
|
||
it('未割当のライセンスに対して、ライセンス割り当てが完了する', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { id: dealerId } = await makeTestSimpleAccount(source, {
|
||
company_name: 'DEALER_COMPANY',
|
||
tier: 4,
|
||
});
|
||
const { id: dealerAdminId } = await makeTestUser(source, {
|
||
account_id: dealerId,
|
||
external_id: 'userId_admin',
|
||
role: 'admin',
|
||
author_id: undefined,
|
||
});
|
||
|
||
const { id: accountId } = await makeTestSimpleAccount(source, {
|
||
parent_account_id: dealerId,
|
||
tier: 5,
|
||
});
|
||
const { id: userId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'userId',
|
||
role: 'admin',
|
||
author_id: undefined,
|
||
});
|
||
await createLicense(
|
||
source,
|
||
1,
|
||
null,
|
||
accountId,
|
||
LICENSE_TYPE.CARD,
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
await createLicenseAllocationHistory(
|
||
source,
|
||
1,
|
||
userId,
|
||
1,
|
||
accountId,
|
||
'NONE',
|
||
);
|
||
|
||
const service = module.get<UsersService>(UsersService);
|
||
let _subject = '';
|
||
let _url: string | undefined = '';
|
||
overrideAdB2cService(service, {
|
||
getUser: async (context, externalId) => {
|
||
return {
|
||
displayName: 'TEMP' + externalId,
|
||
id: externalId,
|
||
identities: [
|
||
{
|
||
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
|
||
issuer: 'xxxxxx',
|
||
issuerAssignedId: 'mail@example.com',
|
||
},
|
||
],
|
||
};
|
||
},
|
||
getUsers: async (context, externalIds) => {
|
||
return externalIds.map((x) => ({
|
||
displayName: 'admin',
|
||
id: x,
|
||
identities: [
|
||
{
|
||
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
|
||
issuer: 'xxxxxx',
|
||
issuerAssignedId: `mail+${x}@example.com`,
|
||
},
|
||
],
|
||
}));
|
||
},
|
||
});
|
||
|
||
overrideSendgridService(service, {
|
||
sendMail: async (
|
||
context: Context,
|
||
to: string[],
|
||
cc: string[],
|
||
from: string,
|
||
subject: string,
|
||
text: string,
|
||
html: string,
|
||
) => {
|
||
const urlPattern = /https?:\/\/[^\s]+/g;
|
||
const urls = text.match(urlPattern);
|
||
const url = urls?.pop();
|
||
|
||
_subject = subject;
|
||
_url = url;
|
||
},
|
||
});
|
||
|
||
const expiry_date = new NewAllocatedLicenseExpirationDate();
|
||
|
||
await service.allocateLicense(
|
||
makeContext('trackingId', 'requestId'),
|
||
userId,
|
||
1,
|
||
);
|
||
const resultLicense = await selectLicense(source, 1);
|
||
expect(resultLicense.license?.allocated_user_id).toBe(userId);
|
||
expect(resultLicense.license?.status).toBe(
|
||
LICENSE_ALLOCATED_STATUS.ALLOCATED,
|
||
);
|
||
expect(resultLicense.license?.expiry_date?.setMilliseconds(0)).toEqual(
|
||
expiry_date.setMilliseconds(0),
|
||
);
|
||
const licenseAllocationHistory = await selectLicenseAllocationHistory(
|
||
source,
|
||
userId,
|
||
1,
|
||
);
|
||
expect(licenseAllocationHistory.licenseAllocationHistory?.user_id).toBe(
|
||
userId,
|
||
);
|
||
expect(licenseAllocationHistory.licenseAllocationHistory?.license_id).toBe(
|
||
1,
|
||
);
|
||
expect(
|
||
licenseAllocationHistory.licenseAllocationHistory?.is_allocated,
|
||
).toBe(true);
|
||
expect(licenseAllocationHistory.licenseAllocationHistory?.account_id).toBe(
|
||
accountId,
|
||
);
|
||
|
||
expect(_subject).toBe('License Assigned Notification [U-108]');
|
||
expect(_url).toBe('http://localhost:8081/');
|
||
});
|
||
|
||
it('再割り当て可能なライセンスに対して、ライセンス割り当てが完了する', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { id: accountId } = await makeTestSimpleAccount(source);
|
||
const { id: userId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'userId',
|
||
role: 'admin',
|
||
author_id: undefined,
|
||
});
|
||
const date = new Date();
|
||
date.setDate(date.getDate() + 30);
|
||
date.setMilliseconds(0);
|
||
await createLicense(
|
||
source,
|
||
1,
|
||
date,
|
||
accountId,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.REUSABLE,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
await createLicenseAllocationHistory(
|
||
source,
|
||
1,
|
||
userId,
|
||
1,
|
||
accountId,
|
||
'NONE',
|
||
);
|
||
|
||
const service = module.get<UsersService>(UsersService);
|
||
overrideSendgridService(service, {});
|
||
|
||
await service.allocateLicense(
|
||
makeContext('trackingId', 'requestId'),
|
||
userId,
|
||
1,
|
||
);
|
||
const result = await selectLicense(source, 1);
|
||
expect(result.license?.allocated_user_id).toBe(userId);
|
||
expect(result.license?.status).toBe(LICENSE_ALLOCATED_STATUS.ALLOCATED);
|
||
expect(result.license?.expiry_date).toEqual(date);
|
||
const licenseAllocationHistory = await selectLicenseAllocationHistory(
|
||
source,
|
||
userId,
|
||
1,
|
||
);
|
||
expect(licenseAllocationHistory.licenseAllocationHistory?.user_id).toBe(
|
||
userId,
|
||
);
|
||
expect(licenseAllocationHistory.licenseAllocationHistory?.license_id).toBe(
|
||
1,
|
||
);
|
||
expect(
|
||
licenseAllocationHistory.licenseAllocationHistory?.is_allocated,
|
||
).toBe(true);
|
||
expect(licenseAllocationHistory.licenseAllocationHistory?.account_id).toBe(
|
||
accountId,
|
||
);
|
||
});
|
||
|
||
it('未割当のライセンスに対して、別のライセンスが割り当てられているユーザーの割り当てが完了する', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { id: accountId } = await makeTestSimpleAccount(source);
|
||
const { id: userId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'userId',
|
||
role: 'admin',
|
||
author_id: undefined,
|
||
});
|
||
const date = new Date();
|
||
date.setDate(date.getDate() + 30);
|
||
date.setMilliseconds(0);
|
||
|
||
await createLicense(
|
||
source,
|
||
1,
|
||
date,
|
||
accountId,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.ALLOCATED,
|
||
userId,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
await createLicense(
|
||
source,
|
||
2,
|
||
null,
|
||
accountId,
|
||
LICENSE_TYPE.CARD,
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
await createLicenseAllocationHistory(
|
||
source,
|
||
1,
|
||
userId,
|
||
1,
|
||
accountId,
|
||
'NONE',
|
||
);
|
||
|
||
const service = module.get<UsersService>(UsersService);
|
||
overrideSendgridService(service, {});
|
||
const expiry_date = new NewAllocatedLicenseExpirationDate();
|
||
|
||
await service.allocateLicense(
|
||
makeContext('trackingId', 'requestId'),
|
||
userId,
|
||
2,
|
||
);
|
||
|
||
// もともと割り当てられていたライセンスの状態確認
|
||
const result1 = await selectLicense(source, 1);
|
||
expect(result1.license?.allocated_user_id).toBe(null);
|
||
expect(result1.license?.status).toBe(LICENSE_ALLOCATED_STATUS.REUSABLE);
|
||
expect(result1.license?.expiry_date).toEqual(date);
|
||
const licenseAllocationHistory = await selectLicenseAllocationHistory(
|
||
source,
|
||
userId,
|
||
1,
|
||
);
|
||
expect(licenseAllocationHistory.licenseAllocationHistory?.user_id).toBe(
|
||
userId,
|
||
);
|
||
expect(licenseAllocationHistory.licenseAllocationHistory?.license_id).toBe(
|
||
1,
|
||
);
|
||
expect(
|
||
licenseAllocationHistory.licenseAllocationHistory?.is_allocated,
|
||
).toBe(false);
|
||
expect(licenseAllocationHistory.licenseAllocationHistory?.account_id).toBe(
|
||
accountId,
|
||
);
|
||
|
||
// 新たに割り当てたライセンスの状態確認
|
||
const result2 = await selectLicense(source, 2);
|
||
expect(result2.license?.allocated_user_id).toBe(userId);
|
||
expect(result2.license?.status).toBe(LICENSE_ALLOCATED_STATUS.ALLOCATED);
|
||
expect(result2.license?.expiry_date?.setMilliseconds(0)).toEqual(
|
||
expiry_date.setMilliseconds(0),
|
||
);
|
||
const newlicenseAllocationHistory = await selectLicenseAllocationHistory(
|
||
source,
|
||
userId,
|
||
2,
|
||
);
|
||
expect(newlicenseAllocationHistory.licenseAllocationHistory?.user_id).toBe(
|
||
userId,
|
||
);
|
||
expect(
|
||
newlicenseAllocationHistory.licenseAllocationHistory?.license_id,
|
||
).toBe(2);
|
||
expect(
|
||
newlicenseAllocationHistory.licenseAllocationHistory?.is_allocated,
|
||
).toBe(true);
|
||
expect(
|
||
newlicenseAllocationHistory.licenseAllocationHistory?.account_id,
|
||
).toBe(accountId);
|
||
});
|
||
|
||
it('割り当て時にライセンス履歴テーブルへの登録が完了する(元がNORMALのとき)', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { id: accountId } = await makeTestSimpleAccount(source);
|
||
const { id: userId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'userId',
|
||
role: 'admin',
|
||
author_id: undefined,
|
||
});
|
||
const date = new Date();
|
||
date.setDate(date.getDate() + 30);
|
||
date.setMilliseconds(0);
|
||
await createLicense(
|
||
source,
|
||
1,
|
||
date,
|
||
accountId,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.ALLOCATED,
|
||
userId,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
await createLicense(
|
||
source,
|
||
2,
|
||
null,
|
||
accountId,
|
||
LICENSE_TYPE.CARD,
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
await createLicenseAllocationHistory(
|
||
source,
|
||
1,
|
||
userId,
|
||
1,
|
||
accountId,
|
||
'NONE',
|
||
);
|
||
|
||
const service = module.get<UsersService>(UsersService);
|
||
overrideSendgridService(service, {});
|
||
await service.allocateLicense(
|
||
makeContext('trackingId', 'requestId'),
|
||
userId,
|
||
2,
|
||
);
|
||
|
||
const licenseAllocationHistory = await selectLicenseAllocationHistory(
|
||
source,
|
||
userId,
|
||
2,
|
||
);
|
||
expect(
|
||
licenseAllocationHistory.licenseAllocationHistory?.switch_from_type,
|
||
).toBe('NONE');
|
||
});
|
||
|
||
it('割り当て時にライセンス履歴テーブルへの登録が完了する(元がCARDのとき)', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { id: accountId } = await makeTestSimpleAccount(source);
|
||
const { id: userId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'userId',
|
||
role: 'admin',
|
||
author_id: undefined,
|
||
});
|
||
const date = new Date();
|
||
date.setDate(date.getDate() + 30);
|
||
date.setMilliseconds(0);
|
||
await createLicense(
|
||
source,
|
||
1,
|
||
date,
|
||
accountId,
|
||
LICENSE_TYPE.CARD,
|
||
LICENSE_ALLOCATED_STATUS.ALLOCATED,
|
||
userId,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
await createLicense(
|
||
source,
|
||
2,
|
||
null,
|
||
accountId,
|
||
LICENSE_TYPE.CARD,
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
await createLicenseAllocationHistory(
|
||
source,
|
||
1,
|
||
userId,
|
||
1,
|
||
accountId,
|
||
'CARD',
|
||
);
|
||
|
||
const service = module.get<UsersService>(UsersService);
|
||
overrideSendgridService(service, {});
|
||
await service.allocateLicense(
|
||
makeContext('trackingId', 'requestId'),
|
||
userId,
|
||
2,
|
||
);
|
||
|
||
const licenseAllocationHistory = await selectLicenseAllocationHistory(
|
||
source,
|
||
userId,
|
||
2,
|
||
);
|
||
expect(
|
||
licenseAllocationHistory.licenseAllocationHistory?.switch_from_type,
|
||
).toBe('CARD');
|
||
});
|
||
|
||
it('割り当て時にライセンス履歴テーブルへの登録が完了する(元がTRIALのとき)', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { id: accountId } = await makeTestSimpleAccount(source);
|
||
const { id: userId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'userId',
|
||
role: 'admin',
|
||
author_id: undefined,
|
||
});
|
||
const date = new Date();
|
||
date.setDate(date.getDate() + 30);
|
||
date.setMilliseconds(0);
|
||
await createLicense(
|
||
source,
|
||
1,
|
||
date,
|
||
accountId,
|
||
LICENSE_TYPE.TRIAL,
|
||
LICENSE_ALLOCATED_STATUS.ALLOCATED,
|
||
userId,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
await createLicense(
|
||
source,
|
||
2,
|
||
null,
|
||
accountId,
|
||
LICENSE_TYPE.CARD,
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
await createLicenseAllocationHistory(
|
||
source,
|
||
1,
|
||
userId,
|
||
1,
|
||
accountId,
|
||
'TRIAL',
|
||
);
|
||
|
||
const service = module.get<UsersService>(UsersService);
|
||
overrideSendgridService(service, {});
|
||
await service.allocateLicense(
|
||
makeContext('trackingId', 'requestId'),
|
||
userId,
|
||
2,
|
||
);
|
||
|
||
const licenseAllocationHistory = await selectLicenseAllocationHistory(
|
||
source,
|
||
userId,
|
||
2,
|
||
);
|
||
expect(
|
||
licenseAllocationHistory.licenseAllocationHistory?.switch_from_type,
|
||
).toBe('TRIAL');
|
||
});
|
||
|
||
it('有効期限が切れているライセンスを割り当てようとした場合、エラーになる', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { id: accountId } = await makeTestSimpleAccount(source);
|
||
const { id: userId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'userId',
|
||
role: 'admin',
|
||
author_id: undefined,
|
||
});
|
||
const date = new Date();
|
||
date.setDate(date.getDate() - 30);
|
||
date.setMilliseconds(0);
|
||
await createLicense(
|
||
source,
|
||
1,
|
||
date,
|
||
accountId,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.REUSABLE,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
|
||
const service = module.get<UsersService>(UsersService);
|
||
overrideSendgridService(service, {});
|
||
|
||
await expect(
|
||
service.allocateLicense(
|
||
makeContext('trackingId', 'requestId'),
|
||
userId,
|
||
1,
|
||
),
|
||
).rejects.toEqual(
|
||
new HttpException(makeErrorResponse('E010805'), HttpStatus.BAD_REQUEST),
|
||
);
|
||
});
|
||
|
||
it('割り当て不可なライセンスを割り当てようとした場合、エラーになる', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { id: accountId } = await makeTestSimpleAccount(source);
|
||
const { id: userId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'userId',
|
||
role: 'admin',
|
||
author_id: undefined,
|
||
});
|
||
const date = new Date();
|
||
date.setDate(date.getDate() + 30);
|
||
date.setMilliseconds(0);
|
||
await createLicense(
|
||
source,
|
||
1,
|
||
null,
|
||
accountId,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.ALLOCATED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
await createLicense(
|
||
source,
|
||
2,
|
||
null,
|
||
accountId,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.DELETED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
|
||
const service = module.get<UsersService>(UsersService);
|
||
overrideSendgridService(service, {});
|
||
|
||
await expect(
|
||
service.allocateLicense(
|
||
makeContext('trackingId', 'requestId'),
|
||
userId,
|
||
1,
|
||
),
|
||
).rejects.toEqual(
|
||
new HttpException(makeErrorResponse('E010806'), HttpStatus.BAD_REQUEST),
|
||
);
|
||
await expect(
|
||
service.allocateLicense(
|
||
makeContext('trackingId', 'requestId'),
|
||
userId,
|
||
2,
|
||
),
|
||
).rejects.toEqual(
|
||
new HttpException(makeErrorResponse('E010806'), HttpStatus.BAD_REQUEST),
|
||
);
|
||
});
|
||
});
|
||
|
||
describe('ライセンス割り当て解除', () => {
|
||
let source: DataSource | null = null;
|
||
beforeAll(async () => {
|
||
if (source == null) {
|
||
source = await (async () => {
|
||
const s = new DataSource({
|
||
type: 'mysql',
|
||
host: 'test_mysql_db',
|
||
port: 3306,
|
||
username: 'user',
|
||
password: 'password',
|
||
database: 'odms',
|
||
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
|
||
synchronize: false, // trueにすると自動的にmigrationが行われるため注意
|
||
logger: new TestLogger('none'),
|
||
logging: true,
|
||
});
|
||
return await s.initialize();
|
||
})();
|
||
}
|
||
});
|
||
|
||
beforeEach(async () => {
|
||
if (source) {
|
||
await truncateAllTable(source);
|
||
}
|
||
});
|
||
|
||
afterAll(async () => {
|
||
await source?.destroy();
|
||
source = null;
|
||
});
|
||
|
||
it('ライセンスの割り当て解除が完了する', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { id: accountId } = await makeTestSimpleAccount(source);
|
||
const { id: userId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'userId',
|
||
role: 'admin',
|
||
author_id: undefined,
|
||
});
|
||
const date = new Date();
|
||
date.setDate(date.getDate() + 30);
|
||
date.setMilliseconds(0);
|
||
await createLicense(
|
||
source,
|
||
1,
|
||
date,
|
||
accountId,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.ALLOCATED,
|
||
userId,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
await createLicenseAllocationHistory(
|
||
source,
|
||
1,
|
||
userId,
|
||
1,
|
||
accountId,
|
||
'NONE',
|
||
);
|
||
|
||
const service = module.get<UsersService>(UsersService);
|
||
overrideSendgridService(service, {});
|
||
await service.deallocateLicense(
|
||
makeContext('trackingId', 'requestId'),
|
||
userId,
|
||
);
|
||
|
||
// 割り当て解除したライセンスの状態確認
|
||
const deallocatedLicense = await selectLicense(source, 1);
|
||
expect(deallocatedLicense.license?.allocated_user_id).toBe(null);
|
||
expect(deallocatedLicense.license?.status).toBe(
|
||
LICENSE_ALLOCATED_STATUS.REUSABLE,
|
||
);
|
||
expect(deallocatedLicense.license?.expiry_date).toEqual(date);
|
||
|
||
// ライセンス履歴テーブルの状態確認
|
||
const licenseAllocationHistory = await selectLicenseAllocationHistory(
|
||
source,
|
||
userId,
|
||
1,
|
||
);
|
||
expect(licenseAllocationHistory.licenseAllocationHistory?.user_id).toBe(
|
||
userId,
|
||
);
|
||
expect(licenseAllocationHistory.licenseAllocationHistory?.license_id).toBe(
|
||
1,
|
||
);
|
||
expect(
|
||
licenseAllocationHistory.licenseAllocationHistory?.is_allocated,
|
||
).toBe(false);
|
||
expect(licenseAllocationHistory.licenseAllocationHistory?.account_id).toBe(
|
||
accountId,
|
||
);
|
||
expect(
|
||
licenseAllocationHistory.licenseAllocationHistory?.switch_from_type,
|
||
).toBe('NONE');
|
||
});
|
||
|
||
it('ライセンスが既に割り当て解除されていた場合、エラーとなる', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { id: accountId } = await makeTestSimpleAccount(source);
|
||
const { id: userId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'userId',
|
||
role: 'admin',
|
||
author_id: undefined,
|
||
});
|
||
await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'userId2',
|
||
role: 'admin',
|
||
author_id: undefined,
|
||
});
|
||
const date = new Date();
|
||
date.setDate(date.getDate() + 30);
|
||
date.setMilliseconds(0);
|
||
await createLicense(
|
||
source,
|
||
1,
|
||
date,
|
||
accountId,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.ALLOCATED,
|
||
2,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
await createLicense(
|
||
source,
|
||
2,
|
||
date,
|
||
accountId,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.REUSABLE,
|
||
userId,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
await createLicenseAllocationHistory(
|
||
source,
|
||
1,
|
||
userId,
|
||
1,
|
||
accountId,
|
||
'NONE',
|
||
);
|
||
|
||
const service = module.get<UsersService>(UsersService);
|
||
overrideSendgridService(service, {});
|
||
await expect(
|
||
service.deallocateLicense(makeContext('trackingId', 'requestId'), userId),
|
||
).rejects.toEqual(
|
||
new HttpException(makeErrorResponse('E010807'), HttpStatus.BAD_REQUEST),
|
||
);
|
||
});
|
||
});
|
||
|
||
describe('ライセンス注文キャンセル', () => {
|
||
let source: DataSource | null = null;
|
||
beforeAll(async () => {
|
||
if (source == null) {
|
||
source = await (async () => {
|
||
const s = new DataSource({
|
||
type: 'mysql',
|
||
host: 'test_mysql_db',
|
||
port: 3306,
|
||
username: 'user',
|
||
password: 'password',
|
||
database: 'odms',
|
||
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
|
||
synchronize: false, // trueにすると自動的にmigrationが行われるため注意
|
||
logger: new TestLogger('none'),
|
||
logging: true,
|
||
});
|
||
return await s.initialize();
|
||
})();
|
||
}
|
||
});
|
||
|
||
beforeEach(async () => {
|
||
if (source) {
|
||
await truncateAllTable(source);
|
||
}
|
||
});
|
||
|
||
afterAll(async () => {
|
||
await source?.destroy();
|
||
source = null;
|
||
});
|
||
|
||
it('ライセンス注文のキャンセルが完了する', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
const { tier2Accounts: tier2Accounts } = await makeHierarchicalAccounts(
|
||
source,
|
||
);
|
||
const poNumber = 'CANCEL_TEST';
|
||
await createOrder(
|
||
source,
|
||
poNumber,
|
||
tier2Accounts[0].account.id,
|
||
tier2Accounts[0].account.parent_account_id ?? 0,
|
||
null,
|
||
10,
|
||
'Issue Requesting',
|
||
);
|
||
// キャンセル済みの同名poNumoberが存在しても正常に動作することの確認用order
|
||
await createOrder(
|
||
source,
|
||
poNumber,
|
||
tier2Accounts[0].account.id,
|
||
tier2Accounts[0].account.parent_account_id ?? 0,
|
||
null,
|
||
10,
|
||
'Order Canceled',
|
||
);
|
||
|
||
const service = module.get<LicensesService>(LicensesService);
|
||
overrideSendgridService(service, {});
|
||
await service.cancelOrder(
|
||
makeContext('trackingId', 'requestId'),
|
||
tier2Accounts[0].users[0].external_id,
|
||
poNumber,
|
||
);
|
||
|
||
// 割り当て解除したライセンスの状態確認
|
||
const orderRecord = await selectOrderLicense(
|
||
source,
|
||
tier2Accounts[0].account.id,
|
||
poNumber,
|
||
);
|
||
expect(orderRecord.orderLicense?.canceled_at).toBeDefined();
|
||
expect(orderRecord.orderLicense?.status).toBe('Order Canceled');
|
||
});
|
||
|
||
it('ライセンスが既に発行済みの場合、エラーとなる', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
const { tier2Accounts: tier2Accounts } = await makeHierarchicalAccounts(
|
||
source,
|
||
);
|
||
const poNumber = 'CANCEL_TEST';
|
||
await createOrder(
|
||
source,
|
||
poNumber,
|
||
tier2Accounts[0].account.id,
|
||
tier2Accounts[0].account.parent_account_id ?? 0,
|
||
null,
|
||
10,
|
||
'Issued',
|
||
);
|
||
|
||
const service = module.get<LicensesService>(LicensesService);
|
||
overrideSendgridService(service, {});
|
||
await expect(
|
||
service.cancelOrder(
|
||
makeContext('trackingId', 'requestId'),
|
||
tier2Accounts[0].users[0].external_id,
|
||
poNumber,
|
||
),
|
||
).rejects.toEqual(
|
||
new HttpException(makeErrorResponse('E010808'), HttpStatus.BAD_REQUEST),
|
||
);
|
||
});
|
||
|
||
it('ライセンスが既にキャンセル済みの場合、エラーとなる', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { tier2Accounts: tier2Accounts } = await makeHierarchicalAccounts(
|
||
source,
|
||
);
|
||
const poNumber = 'CANCEL_TEST';
|
||
await createOrder(
|
||
source,
|
||
poNumber,
|
||
tier2Accounts[0].account.id,
|
||
tier2Accounts[0].account.parent_account_id ?? 0,
|
||
null,
|
||
10,
|
||
'Order Canceled',
|
||
);
|
||
|
||
const service = module.get<LicensesService>(LicensesService);
|
||
overrideSendgridService(service, {});
|
||
await expect(
|
||
service.cancelOrder(
|
||
makeContext('trackingId', 'requestId'),
|
||
tier2Accounts[0].users[0].external_id,
|
||
poNumber,
|
||
),
|
||
).rejects.toEqual(
|
||
new HttpException(makeErrorResponse('E010808'), HttpStatus.BAD_REQUEST),
|
||
);
|
||
});
|
||
});
|
||
|
||
describe('割り当て可能なライセンス取得', () => {
|
||
let source: DataSource | null = null;
|
||
beforeAll(async () => {
|
||
if (source == null) {
|
||
source = await (async () => {
|
||
const s = new DataSource({
|
||
type: 'mysql',
|
||
host: 'test_mysql_db',
|
||
port: 3306,
|
||
username: 'user',
|
||
password: 'password',
|
||
database: 'odms',
|
||
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
|
||
synchronize: false, // trueにすると自動的にmigrationが行われるため注意
|
||
logger: new TestLogger('none'),
|
||
logging: true,
|
||
});
|
||
return await s.initialize();
|
||
})();
|
||
}
|
||
});
|
||
|
||
beforeEach(async () => {
|
||
if (source) {
|
||
await truncateAllTable(source);
|
||
}
|
||
});
|
||
|
||
afterAll(async () => {
|
||
await source?.destroy();
|
||
source = null;
|
||
});
|
||
|
||
it('割り当て可能なライセンスを取得できる', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
const { account, admin } = await makeTestAccount(source, {
|
||
company_name: 'AAA',
|
||
tier: 5,
|
||
});
|
||
// ライセンスを作成
|
||
// 有効期限が当日のライセンスを1つ、有効期限が翌日のライセンスを1つ、有効期限が翌々日のライセンスを1つ作成
|
||
// ミリ秒以下は切り捨てる DBで扱っていないため
|
||
const today = new Date();
|
||
today.setMilliseconds(0);
|
||
const tomorrow = new Date();
|
||
tomorrow.setDate(tomorrow.getDate() + 1);
|
||
tomorrow.setMilliseconds(0);
|
||
const dayAfterTomorrow = new Date();
|
||
dayAfterTomorrow.setDate(dayAfterTomorrow.getDate() + 2);
|
||
dayAfterTomorrow.setMilliseconds(0);
|
||
await createLicense(
|
||
source,
|
||
1,
|
||
today,
|
||
account.id,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
await createLicense(
|
||
source,
|
||
2,
|
||
tomorrow,
|
||
account.id,
|
||
LICENSE_TYPE.CARD,
|
||
LICENSE_ALLOCATED_STATUS.REUSABLE,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
await createLicense(
|
||
source,
|
||
3,
|
||
dayAfterTomorrow,
|
||
account.id,
|
||
LICENSE_TYPE.TRIAL,
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
// ライセンス作成したデータを確認
|
||
{
|
||
const license1 = await selectLicense(source, 1);
|
||
expect(license1.license?.id).toBe(1);
|
||
expect(license1.license?.expiry_date).toEqual(today);
|
||
expect(license1.license?.allocated_user_id).toBe(null);
|
||
expect(license1.license?.status).toBe(
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
);
|
||
expect(license1.license?.account_id).toBe(account.id);
|
||
expect(license1.license?.type).toBe(LICENSE_TYPE.NORMAL);
|
||
const license2 = await selectLicense(source, 2);
|
||
expect(license2.license?.id).toBe(2);
|
||
expect(license2.license?.expiry_date).toEqual(tomorrow);
|
||
expect(license2.license?.allocated_user_id).toBe(null);
|
||
expect(license2.license?.status).toBe(LICENSE_ALLOCATED_STATUS.REUSABLE);
|
||
expect(license2.license?.account_id).toBe(account.id);
|
||
expect(license2.license?.type).toBe(LICENSE_TYPE.CARD);
|
||
const license3 = await selectLicense(source, 3);
|
||
expect(license3.license?.id).toBe(3);
|
||
expect(license3.license?.expiry_date).toEqual(dayAfterTomorrow);
|
||
expect(license3.license?.allocated_user_id).toBe(null);
|
||
expect(license3.license?.status).toBe(
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
);
|
||
expect(license3.license?.account_id).toBe(account.id);
|
||
expect(license3.license?.type).toBe(LICENSE_TYPE.TRIAL);
|
||
}
|
||
const service = module.get<LicensesService>(LicensesService);
|
||
const context = makeContext('trackingId', 'requestId');
|
||
const response = await service.getAllocatableLicenses(
|
||
context,
|
||
admin.external_id,
|
||
);
|
||
|
||
// 有効期限が当日のライセンスは取得されない
|
||
// 有効期限が長い順に取得される
|
||
expect(response.allocatableLicenses.length).toBe(2);
|
||
expect(response.allocatableLicenses[0].licenseId).toBe(3);
|
||
expect(response.allocatableLicenses[0].expiryDate).toEqual(
|
||
dayAfterTomorrow,
|
||
);
|
||
expect(response.allocatableLicenses[1].licenseId).toBe(2);
|
||
expect(response.allocatableLicenses[1].expiryDate).toEqual(tomorrow);
|
||
});
|
||
|
||
it('割り当て可能なライセンスが存在しない場合、空の配列を返却する', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { account, admin } = await makeTestAccount(source, {
|
||
company_name: 'AAA',
|
||
tier: 5,
|
||
});
|
||
// ライセンスを作成
|
||
// 有効期限が当日のライセンスを3つ、有効期限が昨日のライセンスを1つ作成
|
||
// ミリ秒以下は切り捨てる DBで扱っていないため
|
||
const today = new Date();
|
||
today.setMilliseconds(0);
|
||
const yesterday = new Date();
|
||
yesterday.setDate(yesterday.getDate() - 1);
|
||
yesterday.setMilliseconds(0);
|
||
for (let i = 1; i <= 3; i++) {
|
||
await createLicense(
|
||
source,
|
||
i,
|
||
today,
|
||
account.id,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
}
|
||
await createLicense(
|
||
source,
|
||
4,
|
||
yesterday,
|
||
account.id,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
// ライセンス作成したデータを確認
|
||
{
|
||
const license1 = await selectLicense(source, 1);
|
||
expect(license1.license?.id).toBe(1);
|
||
expect(license1.license?.expiry_date).toEqual(today);
|
||
expect(license1.license?.allocated_user_id).toBe(null);
|
||
expect(license1.license?.status).toBe(
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
);
|
||
expect(license1.license?.account_id).toBe(account.id);
|
||
expect(license1.license?.type).toBe(LICENSE_TYPE.NORMAL);
|
||
const license2 = await selectLicense(source, 2);
|
||
expect(license2.license?.id).toBe(2);
|
||
expect(license2.license?.expiry_date).toEqual(today);
|
||
expect(license2.license?.allocated_user_id).toBe(null);
|
||
expect(license2.license?.status).toBe(
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
);
|
||
expect(license2.license?.account_id).toBe(account.id);
|
||
expect(license2.license?.type).toBe(LICENSE_TYPE.NORMAL);
|
||
const license3 = await selectLicense(source, 3);
|
||
expect(license3.license?.id).toBe(3);
|
||
expect(license3.license?.expiry_date).toEqual(today);
|
||
expect(license3.license?.allocated_user_id).toBe(null);
|
||
expect(license3.license?.status).toBe(
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
);
|
||
expect(license3.license?.account_id).toBe(account.id);
|
||
expect(license3.license?.type).toBe(LICENSE_TYPE.NORMAL);
|
||
const license4 = await selectLicense(source, 4);
|
||
expect(license4.license?.id).toBe(4);
|
||
expect(license4.license?.expiry_date).toEqual(yesterday);
|
||
expect(license4.license?.allocated_user_id).toBe(null);
|
||
expect(license4.license?.status).toBe(
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
);
|
||
expect(license4.license?.account_id).toBe(account.id);
|
||
expect(license4.license?.type).toBe(LICENSE_TYPE.NORMAL);
|
||
}
|
||
const service = module.get<LicensesService>(LicensesService);
|
||
const context = makeContext('trackingId', 'requestId');
|
||
const response = await service.getAllocatableLicenses(
|
||
context,
|
||
admin.external_id,
|
||
);
|
||
// 有効期限が当日のライセンスは取得されない
|
||
// 有効期限が切れているライセンスは取得されない
|
||
expect(response.allocatableLicenses.length).toBe(0);
|
||
expect(response.allocatableLicenses).toEqual([]);
|
||
});
|
||
|
||
it('割り当て可能なライセンスを100件取得できる', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { account, admin } = await makeTestAccount(source, {
|
||
company_name: 'AAA',
|
||
tier: 5,
|
||
});
|
||
// ライセンスを作成
|
||
// 有効期限が30日後のライセンスを100件作成
|
||
// ミリ秒以下は切り捨てる DBで扱っていないため
|
||
const date = new Date();
|
||
date.setDate(date.getDate() + 30);
|
||
date.setMilliseconds(0);
|
||
for (let i = 1; i <= 100; i++) {
|
||
await createLicense(
|
||
source,
|
||
i,
|
||
date,
|
||
account.id,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
}
|
||
// ライセンス作成したデータを確認
|
||
for (let i = 1; i <= 100; i++) {
|
||
const license = await selectLicense(source, i);
|
||
expect(license.license?.id).toBe(i);
|
||
expect(license.license?.expiry_date).toEqual(date);
|
||
expect(license.license?.allocated_user_id).toBe(null);
|
||
expect(license.license?.status).toBe(
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
);
|
||
expect(license.license?.account_id).toBe(account.id);
|
||
expect(license.license?.type).toBe(LICENSE_TYPE.NORMAL);
|
||
}
|
||
const service = module.get<LicensesService>(LicensesService);
|
||
const context = makeContext('trackingId', 'requestId');
|
||
const response = await service.getAllocatableLicenses(
|
||
context,
|
||
admin.external_id,
|
||
);
|
||
// 100件取得できる
|
||
expect(response.allocatableLicenses.length).toBe(100);
|
||
});
|
||
it('既に割り当てられているライセンスは取得されない', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
const { account, admin } = await makeTestAccount(source, {
|
||
company_name: 'AAA',
|
||
tier: 5,
|
||
});
|
||
// ライセンスを作成
|
||
// ライセンスを5件作成(10日後から1日ずつ有効期限を設定)
|
||
// 有効期限が設定されていないライセンス(新規ライセンス)を1件作成
|
||
// 既に割り当てられているライセンスを1件作成
|
||
// ミリ秒以下は切り捨てる DBで扱っていないため
|
||
const date = new Date();
|
||
date.setMinutes(0);
|
||
date.setSeconds(0);
|
||
date.setDate(date.getDate() + 10);
|
||
date.setMilliseconds(0);
|
||
for (let i = 1; i <= 5; i++) {
|
||
await createLicense(
|
||
source,
|
||
i,
|
||
date,
|
||
account.id,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
admin.id,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
date.setDate(date.getDate() + 1);
|
||
}
|
||
// 新規ライセンス
|
||
await createLicense(
|
||
source,
|
||
6,
|
||
null,
|
||
account.id,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
null,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
// 既に割り当てられているライセンス
|
||
await createLicense(
|
||
source,
|
||
7,
|
||
date,
|
||
account.id,
|
||
LICENSE_TYPE.NORMAL,
|
||
LICENSE_ALLOCATED_STATUS.ALLOCATED,
|
||
admin.id,
|
||
null,
|
||
null,
|
||
null,
|
||
);
|
||
// ライセンス作成したデータを確認
|
||
{
|
||
const date = new Date();
|
||
date.setMinutes(0);
|
||
date.setSeconds(0);
|
||
date.setDate(date.getDate() + 10);
|
||
date.setMilliseconds(0);
|
||
for (let i = 1; i <= 5; i++) {
|
||
const license = await selectLicense(source, i);
|
||
expect(license.license?.id).toBe(i);
|
||
expect(license.license?.expiry_date).toEqual(date);
|
||
expect(license.license?.allocated_user_id).toBe(admin.id);
|
||
expect(license.license?.status).toBe(
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
);
|
||
expect(license.license?.account_id).toBe(account.id);
|
||
expect(license.license?.type).toBe(LICENSE_TYPE.NORMAL);
|
||
date.setDate(date.getDate() + 1);
|
||
}
|
||
const newLicense = await selectLicense(source, 6);
|
||
expect(newLicense.license?.id).toBe(6);
|
||
expect(newLicense.license?.expiry_date).toBe(null);
|
||
expect(newLicense.license?.allocated_user_id).toBe(null);
|
||
expect(newLicense.license?.status).toBe(
|
||
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
|
||
);
|
||
const allocatedLicense = await selectLicense(source, 7);
|
||
expect(allocatedLicense.license?.id).toBe(7);
|
||
expect(allocatedLicense.license?.expiry_date).toEqual(date);
|
||
expect(allocatedLicense.license?.allocated_user_id).toBe(admin.id);
|
||
expect(allocatedLicense.license?.status).toBe(
|
||
LICENSE_ALLOCATED_STATUS.ALLOCATED,
|
||
);
|
||
expect(allocatedLicense.license?.account_id).toBe(account.id);
|
||
expect(allocatedLicense.license?.type).toBe(LICENSE_TYPE.NORMAL);
|
||
}
|
||
|
||
const service = module.get<LicensesService>(LicensesService);
|
||
const context = makeContext('trackingId', 'requestId');
|
||
const response = await service.getAllocatableLicenses(
|
||
context,
|
||
admin.external_id,
|
||
);
|
||
// 既に割り当てられているライセンスは取得されない
|
||
// 新規ライセンスは取得される
|
||
// 有効期限が長い順に取得される
|
||
expect(response.allocatableLicenses.length).toBe(6);
|
||
expect(response.allocatableLicenses[0].licenseId).toBe(6);
|
||
expect(response.allocatableLicenses[0].expiryDate).toBe(undefined);
|
||
expect(response.allocatableLicenses[1].licenseId).toBe(5); // 有効期限が最も長い
|
||
expect(response.allocatableLicenses[2].licenseId).toBe(4);
|
||
expect(response.allocatableLicenses[3].licenseId).toBe(3);
|
||
expect(response.allocatableLicenses[4].licenseId).toBe(2);
|
||
expect(response.allocatableLicenses[5].licenseId).toBe(1);
|
||
});
|
||
});
|
||
|
||
describe('第五階層へのトライアルライセンス発行', () => {
|
||
let source: DataSource | null = null;
|
||
beforeAll(async () => {
|
||
if (source == null) {
|
||
source = await (async () => {
|
||
const s = new DataSource({
|
||
type: 'mysql',
|
||
host: 'test_mysql_db',
|
||
port: 3306,
|
||
username: 'user',
|
||
password: 'password',
|
||
database: 'odms',
|
||
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
|
||
synchronize: false, // trueにすると自動的にmigrationが行われるため注意
|
||
logger: new TestLogger('none'),
|
||
logging: true,
|
||
});
|
||
return await s.initialize();
|
||
})();
|
||
}
|
||
});
|
||
|
||
beforeEach(async () => {
|
||
if (source) {
|
||
await truncateAllTable(source);
|
||
}
|
||
});
|
||
|
||
afterAll(async () => {
|
||
await source?.destroy();
|
||
source = null;
|
||
});
|
||
|
||
it('第一階層が第五階層へのトライアルライセンス発行が完了する', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
// アカウントの階層構造を作成。
|
||
const { tier1Accounts, tier4Accounts } = await makeHierarchicalAccounts(
|
||
source,
|
||
);
|
||
const tier1AccountId = tier1Accounts[0].account.id;
|
||
const tier1ExternalId = tier1Accounts[0].users[0].external_id;
|
||
const tier4AccountId = tier4Accounts[0].account.id;
|
||
const { id: tier5AccountId } = await makeTestSimpleAccount(source, {
|
||
tier: 5,
|
||
parent_account_id: tier4AccountId,
|
||
});
|
||
|
||
await makeTestUser(source, {
|
||
account_id: tier5AccountId,
|
||
external_id: 'tier5UserId',
|
||
role: 'admin',
|
||
author_id: undefined,
|
||
});
|
||
|
||
const usersService = module.get<UsersService>(UsersService);
|
||
const licenseService = module.get<LicensesService>(LicensesService);
|
||
const sendGridService = module.get<SendGridService>(SendGridService);
|
||
|
||
// メール送信サービスのモックによって初期化される値たち
|
||
let _subject = '';
|
||
let _url: string | undefined = '';
|
||
let addressToTier5Admin = '';
|
||
let addressCcDealerList: string[] = [];
|
||
|
||
// ユーザー取得処理をモック化
|
||
overrideAdB2cService(usersService, {
|
||
getUsers: async (context, externalIds) => {
|
||
if (externalIds.includes('tier5UserId')) {
|
||
// 第五階層のユーザーの場合
|
||
return externalIds.map((x) => ({
|
||
displayName: `tier5Admin${x}`,
|
||
id: x,
|
||
identities: [
|
||
{
|
||
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
|
||
issuer: 'xxxxxx',
|
||
issuerAssignedId: `tier5Admin+${x}@example.com`,
|
||
},
|
||
],
|
||
}));
|
||
}
|
||
// 第五階層以外の場合
|
||
return externalIds.map((x) => ({
|
||
displayName: 'upperTieradmin',
|
||
id: x,
|
||
identities: [
|
||
{
|
||
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
|
||
issuer: 'xxxxxx',
|
||
issuerAssignedId: `upperTierAdmin+${x}@example.com`,
|
||
},
|
||
],
|
||
}));
|
||
},
|
||
});
|
||
|
||
// メール送信サービスをモック化
|
||
overrideSendgridService(licenseService, {
|
||
sendMail: jest.fn(
|
||
async (
|
||
context: Context,
|
||
to: string[],
|
||
cc: string[],
|
||
from: string,
|
||
subject: string,
|
||
text: string,
|
||
html: string,
|
||
) => {
|
||
const urlPattern = /https?:\/\/[^\s]+/g;
|
||
const urls = text.match(urlPattern);
|
||
const url = urls?.pop();
|
||
|
||
// 件名
|
||
_subject = subject;
|
||
// URL
|
||
_url = url;
|
||
// 第5階層の宛先
|
||
addressToTier5Admin = to[0];
|
||
// ディーラーの宛先
|
||
addressCcDealerList = cc;
|
||
},
|
||
),
|
||
});
|
||
|
||
const context = makeContext(`uuidv4`, 'requestId');
|
||
await licenseService.issueTrialLicense(
|
||
context,
|
||
tier1ExternalId,
|
||
tier5AccountId,
|
||
);
|
||
const dbSelectResult = await selectIssuedLicensesAndLicenseOrders(
|
||
source,
|
||
tier5AccountId,
|
||
tier1AccountId,
|
||
);
|
||
if (dbSelectResult === null) fail();
|
||
|
||
const { order, licenses } = dbSelectResult;
|
||
|
||
// 注文の確認
|
||
expect(order.from_account_id).toEqual(tier5AccountId);
|
||
expect(order.to_account_id).toEqual(tier1AccountId);
|
||
expect(order.po_number).toBeNull();
|
||
expect(order.type).toEqual(LICENSE_TYPE.TRIAL);
|
||
expect(order.status).toEqual(LICENSE_ISSUE_STATUS.ISSUED);
|
||
// 10個注文されている
|
||
expect(order.quantity).toEqual(10);
|
||
|
||
// ライセンスの確認
|
||
// 値のチェックは最初と最後の1つのみ
|
||
// 10個発行されている
|
||
expect(licenses.length).toEqual(10);
|
||
|
||
// 1レコード目
|
||
const firstLicense = licenses[0];
|
||
expect(firstLicense.account_id).toEqual(tier5AccountId);
|
||
expect(firstLicense.order_id).toEqual(order.id);
|
||
expect(firstLicense.type).toEqual(LICENSE_TYPE.TRIAL);
|
||
expect(firstLicense.status).toEqual(LICENSE_ALLOCATED_STATUS.UNALLOCATED);
|
||
expect(firstLicense.expiry_date).toEqual(
|
||
new NewTrialLicenseExpirationDate(),
|
||
);
|
||
|
||
// 10レコード目
|
||
const lastLicense = licenses.slice(-1)[0];
|
||
expect(lastLicense?.account_id).toEqual(tier5AccountId);
|
||
expect(lastLicense?.order_id).toEqual(order.id);
|
||
expect(lastLicense?.type).toEqual(LICENSE_TYPE.TRIAL);
|
||
expect(lastLicense?.status).toEqual(LICENSE_ALLOCATED_STATUS.UNALLOCATED);
|
||
expect(lastLicense?.expiry_date).toEqual(
|
||
new NewTrialLicenseExpirationDate(),
|
||
);
|
||
|
||
// メールが期待通り送信されていること
|
||
// 件名
|
||
expect(_subject).toBe('Issued Trial License Notification [U-125]');
|
||
// URL
|
||
expect(_url).toBe('http://localhost:8081/');
|
||
// 第五階層の宛先
|
||
expect(addressToTier5Admin).toBeTruthy();
|
||
// ディーラーの宛先(第一階層宛のみ)
|
||
expect(addressCcDealerList).toHaveLength(1);
|
||
// メール送信が呼ばれた回数を検査(第五階層と第一階層に同じメールを送信)
|
||
expect(sendGridService.sendMail).toBeCalledTimes(1);
|
||
});
|
||
it('第二階層が第五階層へのトライアルライセンス発行が完了する', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
// アカウントの階層構造を作成。
|
||
const { tier2Accounts, tier4Accounts } = await makeHierarchicalAccounts(
|
||
source,
|
||
);
|
||
const tier2AccountId = tier2Accounts[0].account.id;
|
||
const tier2ExternalId = tier2Accounts[0].users[0].external_id;
|
||
const tier4AccountId = tier4Accounts[0].account.id;
|
||
const { id: tier5AccountId } = await makeTestSimpleAccount(source, {
|
||
tier: 5,
|
||
parent_account_id: tier4AccountId,
|
||
});
|
||
|
||
await makeTestUser(source, {
|
||
account_id: tier5AccountId,
|
||
external_id: 'tier5UserId',
|
||
role: 'admin',
|
||
author_id: undefined,
|
||
});
|
||
|
||
const usersService = module.get<UsersService>(UsersService);
|
||
const licenseService = module.get<LicensesService>(LicensesService);
|
||
const sendGridService = module.get<SendGridService>(SendGridService);
|
||
|
||
// メール送信サービスのモックによって初期化される値たち
|
||
let _subject = '';
|
||
let _url: string | undefined = '';
|
||
let expirationDate: string | undefined = '';
|
||
let addressToTier5Admin = '';
|
||
let addressCcDealerList: string[] = [];
|
||
|
||
// ユーザー取得処理をモック化
|
||
overrideAdB2cService(usersService, {
|
||
getUsers: async (context, externalIds) => {
|
||
if (externalIds.includes('tier5UserId')) {
|
||
// 第五階層のユーザーの場合
|
||
return externalIds.map((x) => ({
|
||
displayName: `tier5Admin${x}`,
|
||
id: x,
|
||
identities: [
|
||
{
|
||
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
|
||
issuer: 'xxxxxx',
|
||
issuerAssignedId: `tier5Admin+${x}@example.com`,
|
||
},
|
||
],
|
||
}));
|
||
}
|
||
// 第五階層以外の場合
|
||
return externalIds.map((x) => ({
|
||
displayName: 'upperTieradmin',
|
||
id: x,
|
||
identities: [
|
||
{
|
||
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
|
||
issuer: 'xxxxxx',
|
||
issuerAssignedId: `upperTierAdmin+${x}@example.com`,
|
||
},
|
||
],
|
||
}));
|
||
},
|
||
});
|
||
|
||
// メール送信サービスをモック化
|
||
overrideSendgridService(licenseService, {
|
||
sendMail: jest.fn(
|
||
async (
|
||
context: Context,
|
||
to: string[],
|
||
cc: string[],
|
||
from: string,
|
||
subject: string,
|
||
text: string,
|
||
html: string,
|
||
) => {
|
||
const urlPattern = /https?:\/\/[^\s]+/g;
|
||
const urls = text.match(urlPattern);
|
||
const url = urls?.pop();
|
||
|
||
// 件名
|
||
_subject = subject;
|
||
// URL
|
||
_url = url;
|
||
// 第5階層の宛先
|
||
addressToTier5Admin = to[0];
|
||
// ディーラーの宛先
|
||
addressCcDealerList = cc;
|
||
},
|
||
),
|
||
});
|
||
|
||
const context = makeContext(`uuidv4`, 'requestId');
|
||
await licenseService.issueTrialLicense(
|
||
context,
|
||
tier2ExternalId,
|
||
tier5AccountId,
|
||
);
|
||
const dbSelectResult = await selectIssuedLicensesAndLicenseOrders(
|
||
source,
|
||
tier5AccountId,
|
||
tier2AccountId,
|
||
);
|
||
if (dbSelectResult === null) fail();
|
||
|
||
const { order, licenses } = dbSelectResult;
|
||
|
||
// 注文の確認
|
||
expect(order.from_account_id).toEqual(tier5AccountId);
|
||
expect(order.to_account_id).toEqual(tier2AccountId);
|
||
expect(order.po_number).toBeNull();
|
||
expect(order.type).toEqual(LICENSE_TYPE.TRIAL);
|
||
expect(order.status).toEqual(LICENSE_ISSUE_STATUS.ISSUED);
|
||
// 10個注文されている
|
||
expect(order.quantity).toEqual(10);
|
||
|
||
// ライセンスの確認
|
||
// 値のチェックは最初と最後の1つのみ
|
||
// 10個発行されている
|
||
expect(licenses.length).toEqual(10);
|
||
|
||
// 1レコード目
|
||
const firstLicense = licenses[0];
|
||
expect(firstLicense.account_id).toEqual(tier5AccountId);
|
||
expect(firstLicense.order_id).toEqual(order.id);
|
||
expect(firstLicense.type).toEqual(LICENSE_TYPE.TRIAL);
|
||
expect(firstLicense.status).toEqual(LICENSE_ALLOCATED_STATUS.UNALLOCATED);
|
||
expect(firstLicense.expiry_date).toEqual(
|
||
new NewTrialLicenseExpirationDate(),
|
||
);
|
||
|
||
// 10レコード目
|
||
const lastLicense = licenses.slice(-1)[0];
|
||
expect(lastLicense?.account_id).toEqual(tier5AccountId);
|
||
expect(lastLicense?.order_id).toEqual(order.id);
|
||
expect(lastLicense?.type).toEqual(LICENSE_TYPE.TRIAL);
|
||
expect(lastLicense?.status).toEqual(LICENSE_ALLOCATED_STATUS.UNALLOCATED);
|
||
expect(lastLicense?.expiry_date).toEqual(
|
||
new NewTrialLicenseExpirationDate(),
|
||
);
|
||
|
||
// メールが期待通り送信されていること
|
||
// 件名
|
||
expect(_subject).toBe('Issued Trial License Notification [U-125]');
|
||
// URL
|
||
expect(_url).toBe('http://localhost:8081/');
|
||
// 第五階層の宛先
|
||
expect(addressToTier5Admin).toBeTruthy();
|
||
// ディーラーの宛先(第一階層宛と第二階層宛)
|
||
expect(addressCcDealerList).toHaveLength(2);
|
||
// メール送信が呼ばれた回数を検査(第五階層と第一階層に同じメールを送信)
|
||
expect(sendGridService.sendMail).toBeCalledTimes(1);
|
||
});
|
||
|
||
it('DBアクセスに失敗した場合、500エラーを返却する', async () => {
|
||
if (!source) fail();
|
||
const module = await makeTestingModule(source);
|
||
if (!module) fail();
|
||
|
||
const { id: accountId } = await makeTestSimpleAccount(source);
|
||
const { external_id: externalId } = await makeTestUser(source, {
|
||
account_id: accountId,
|
||
external_id: 'userId',
|
||
role: 'admin',
|
||
author_id: undefined,
|
||
});
|
||
|
||
const service = module.get<LicensesService>(LicensesService);
|
||
const context = makeContext(`uuidv4`, 'requestId');
|
||
|
||
//DBアクセスに失敗するようにする
|
||
const licensesService = module.get<LicensesRepositoryService>(
|
||
LicensesRepositoryService,
|
||
);
|
||
licensesService.issueTrialLicense = jest
|
||
.fn()
|
||
.mockRejectedValue('DB failed');
|
||
|
||
try {
|
||
await service.issueTrialLicense(context, externalId, accountId);
|
||
} catch (e) {
|
||
if (e instanceof HttpException) {
|
||
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
|
||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||
} else {
|
||
fail();
|
||
}
|
||
}
|
||
});
|
||
});
|