From 1c18bf03b6a6b80b5f70dc256211e68a795933a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B0=B4=E6=9C=AC=20=E7=A5=90=E5=B8=8C?= Date: Mon, 25 Dec 2023 00:17:17 +0000 Subject: [PATCH] =?UTF-8?q?Merged=20PR=20640:=20=E5=A3=8A=E3=82=8C?= =?UTF-8?q?=E3=81=9F=E3=83=A9=E3=82=A4=E3=82=BB=E3=83=B3=E3=82=B9=E3=83=86?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=82=92DB=E3=83=86=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=81=A7=E6=9B=B8=E3=81=8D=E7=9B=B4=E3=81=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task3356: 壊れたライセンステストをDBテストで書き直す](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3356) - 何をどう変更したか、追加したライブラリなど ライセンスのモック使ったたUTをDBテストになるよう修正 - ライセンス注文が完了する - ライセンス注文が完了する - ユーザID取得できなかった場合、エラーとなる - 親ユーザID取得できなかった場合、エラーとなる - POナンバー重複時、エラーとなる - カードライセンス発行が完了する - カードライセンス発行に失敗した場合、エラーになる - カードライセンス取り込みが完了する - カードライセンス取り込みに失敗した場合、エラーになる(DBエラー) - カードライセンス取り込みに失敗した場合、エラーになる(ライセンスが存在しないエラー) - カードライセンス取り込みに失敗した場合、エラーになる(ライセンスが既に取り込まれているエラー) ※カードライセンス発行、カードライセンス取り込みが完了する、取込可能なライセンスのみが取得できる 以上の3点はすでにDBテストになっていたので、特に修正・追加していません。 ## レビューポイント 特になし ## 動作確認状況 - ユニットテスト --- .../licenses/licenses.service.spec.ts | 359 +++++++++++++++++- 1 file changed, 340 insertions(+), 19 deletions(-) diff --git a/dictation_server/src/features/licenses/licenses.service.spec.ts b/dictation_server/src/features/licenses/licenses.service.spec.ts index ad5092a..f3f0ec4 100644 --- a/dictation_server/src/features/licenses/licenses.service.spec.ts +++ b/dictation_server/src/features/licenses/licenses.service.spec.ts @@ -1,23 +1,6 @@ -import { - CreateOrdersRequest, - IssueCardLicensesRequest, - IssueCardLicensesResponse, - ActivateCardLicensesRequest, - NewAllocatedLicenseExpirationDate, -} from './types/types'; -import { - makeDefaultAccountsRepositoryMockValue, - makeDefaultLicensesRepositoryMockValue, - makeDefaultUsersRepositoryMockValue, - makeLicensesServiceMock, -} from './test/liscense.service.mock'; +import { NewAllocatedLicenseExpirationDate } from './types/types'; import { makeErrorResponse } from '../../common/error/makeErrorResponse'; import { HttpException, HttpStatus } from '@nestjs/common'; -import { - PoNumberAlreadyExistError, - LicenseKeyAlreadyActivatedError, - LicenseNotExistError, -} from '../../repositories/licenses/errors/types'; import { LicensesService } from './licenses.service'; import { makeTestingModule } from '../../common/test/modules'; import { DataSource } from 'typeorm'; @@ -41,9 +24,171 @@ import { makeTestSimpleAccount, makeTestUser, } from '../../common/test/utility'; +import { LicensesRepositoryService } from '../../repositories/licenses/licenses.repository.service'; import { overrideSendgridService } from '../../common/test/overrides'; -describe('DBテスト', () => { +describe('ライセンス注文', () => { + let source: DataSource | null = null; + beforeEach(async () => { + source = new DataSource({ + type: 'sqlite', + database: ':memory:', + logging: false, + entities: [__dirname + '/../../**/*.entity{.ts,.js}'], + synchronize: true, // trueにすると自動的にmigrationが行われるため注意 + }); + return source.initialize(); + }); + + afterEach(async () => { + if (!source) return; + await source.destroy(); + source = null; + }); + + it('ライセンス注文が完了する', async () => { + if (!source) fail(); + const module = await makeTestingModule(source); + if (!module) fail(); + + const { 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); + + 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'); + }); + + 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); + + 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); + + 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); + + const context = makeContext(`uuidv4`, 'requestId'); + try { + await service.licenseOrders(context, externalId, poNumber, orderCount); + } 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; beforeEach(async () => { source = new DataSource({ @@ -83,6 +228,62 @@ describe('DBテスト', () => { 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); + const issueCount = 500; + const context = makeContext(`uuidv4`, 'requestId'); + + //DBアクセスに失敗するようにする + const licensesService = module.get( + 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; + beforeEach(async () => { + source = new DataSource({ + type: 'sqlite', + database: ':memory:', + logging: false, + entities: [__dirname + '/../../**/*.entity{.ts,.js}'], + synchronize: true, // trueにすると自動的にmigrationが行われるため注意 + }); + return source.initialize(); + }); + + afterEach(async () => { + if (!source) return; + await source.destroy(); + source = null; + }); it('カードライセンス取り込みが完了する', async () => { if (!source) fail(); const module = await makeTestingModule(source); @@ -276,6 +477,126 @@ describe('DBテスト', () => { 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); + 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); + 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); + const context = makeContext(`uuidv4`, 'requestId'); + const cardLicenseKey = 'WZCETXC0Z9PQZ9GKRGGY'; + + //DBアクセスに失敗するようにする + const licensesService = module.get( + 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('ライセンス割り当て', () => {