Merged PR 335: API修正(アカウント登録)&テスト実装
## 概要 [Task2369: API修正(アカウント登録)&テスト実装](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2369) - リカバリ処理を実装 - テスト追加 ## レビューポイント - テストケースは足りているか - リカバリ処理を追加したが、漏れはないか ## UIの変更 - Before/Afterのスクショなど - スクショ置き場 ## 動作確認状況 - ローカルで確認 ## 補足 - 相談、参考資料などがあれば
This commit is contained in:
parent
76ed87d82a
commit
b8c2640719
@ -7,6 +7,8 @@ import { SendGridService } from '../../gateways/sendgrid/sendgrid.service';
|
||||
import { User, newUser } from '../../repositories/users/entity/user.entity';
|
||||
import { UsersRepositoryService } from '../../repositories/users/users.repository.service';
|
||||
import { BlobstorageService } from '../../gateways/blobstorage/blobstorage.service';
|
||||
import { AccountsRepositoryService } from '../../repositories/accounts/accounts.repository.service';
|
||||
import { Account } from '../../repositories/accounts/entity/account.entity';
|
||||
|
||||
// ### ユニットテスト用コード以外では絶対に使用してはいけないダーティな手段を使用しているが、他の箇所では使用しないこと ###
|
||||
|
||||
@ -155,6 +157,11 @@ export const overrideBlobstorageService = <TService>(
|
||||
accountId: number,
|
||||
country: string,
|
||||
) => Promise<void>;
|
||||
deleteContainer?: (
|
||||
context: Context,
|
||||
accountId: number,
|
||||
country: string,
|
||||
) => Promise<void>;
|
||||
},
|
||||
): void => {
|
||||
// テストコードでのみ許される強引な方法でprivateメンバ変数の参照を取得
|
||||
@ -165,4 +172,47 @@ export const overrideBlobstorageService = <TService>(
|
||||
writable: true,
|
||||
});
|
||||
}
|
||||
if (overrides.deleteContainer) {
|
||||
Object.defineProperty(obj, obj.deleteContainer.name, {
|
||||
value: overrides.deleteContainer,
|
||||
writable: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* accountsRepositoryのモックを作成して、TServiceが依存するサービス(AccountsRepositoryService)の参照を上書きする
|
||||
* ※ serviceに指定するオブジェクトは`accountsRepository: AccountsRepositoryService`メンバ変数を持つ必要がある
|
||||
* @param service 上書きしたいTService
|
||||
* @param overrides accountsRepositoryの各種メソッドのモックが返す値(省略した場合は本物のメソッドが呼ばれる)
|
||||
*/
|
||||
export const overrideAccountsRepositoryService = <TService>(
|
||||
service: TService,
|
||||
overrides: {
|
||||
createAccount?: (
|
||||
companyName: string,
|
||||
country: string,
|
||||
dealerAccountId: number | undefined,
|
||||
tier: number,
|
||||
adminExternalUserId: string,
|
||||
adminUserRole: string,
|
||||
adminUserAcceptedTermsVersion: string,
|
||||
) => Promise<{ newAccount: Account; adminUser: User }>;
|
||||
deleteAccount?: (accountId: number, userId: number) => Promise<void>;
|
||||
},
|
||||
): void => {
|
||||
// テストコードでのみ許される強引な方法でprivateメンバ変数の参照を取得
|
||||
const obj = (service as any).accountRepository as AccountsRepositoryService;
|
||||
if (overrides.deleteAccount) {
|
||||
Object.defineProperty(obj, obj.deleteAccount.name, {
|
||||
value: overrides.deleteAccount,
|
||||
writable: true,
|
||||
});
|
||||
}
|
||||
if (overrides.createAccount) {
|
||||
Object.defineProperty(obj, obj.createAccount.name, {
|
||||
value: overrides.createAccount,
|
||||
writable: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -21,19 +21,23 @@ import {
|
||||
getUserFromExternalID,
|
||||
getAccounts,
|
||||
getUsers,
|
||||
getSortCriteria,
|
||||
createAccountAndAdminUser,
|
||||
} from './test/utility';
|
||||
import { DataSource } from 'typeorm';
|
||||
import { makeTestingModule } from '../../common/test/modules';
|
||||
import { AccountsService } from './accounts.service';
|
||||
import { makeContext } from '../../common/log';
|
||||
import { Context, makeContext } from '../../common/log';
|
||||
import { TIERS } 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';
|
||||
|
||||
describe('createAccount', () => {
|
||||
let source: DataSource = null;
|
||||
@ -247,10 +251,10 @@ describe('createAccount', () => {
|
||||
expect(users.length).toBe(0);
|
||||
});
|
||||
|
||||
it('アカウントを作成がBlobStorageへの通信失敗によって失敗すると500エラーが発生する', async () => {
|
||||
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';
|
||||
@ -265,6 +269,135 @@ describe('createAccount', () => {
|
||||
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, {
|
||||
@ -290,9 +423,270 @@ describe('createAccount', () => {
|
||||
expect(e.getStatus()).toBe(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||||
} else {
|
||||
expect(true).toBe(false); // ここには来てはいけない
|
||||
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,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -190,9 +190,10 @@ export class AccountsService {
|
||||
} catch (e) {
|
||||
this.logger.error(`error=${e}`);
|
||||
this.logger.error('create account failed');
|
||||
this.logger.error(
|
||||
`[NOT IMPLEMENT] [RECOVER] delete account: ${externalUser.sub}`,
|
||||
);
|
||||
//リカバリ処理
|
||||
// idpのユーザーを削除
|
||||
await this.deleteAdB2cUser(externalUser.sub, context);
|
||||
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E009999'),
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
@ -209,6 +210,13 @@ export class AccountsService {
|
||||
} catch (e) {
|
||||
this.logger.error(`error=${e}`);
|
||||
this.logger.error('create container failed');
|
||||
//リカバリ処理
|
||||
// idpのユーザーを削除
|
||||
await this.deleteAdB2cUser(externalUser.sub, context);
|
||||
|
||||
// DBのアカウントを削除
|
||||
await this.deleteAccount(account.id, user.id, context);
|
||||
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E009999'),
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
@ -238,16 +246,18 @@ export class AccountsService {
|
||||
html,
|
||||
);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
this.logger.error(`error=${e}`);
|
||||
this.logger.error('create user failed');
|
||||
this.logger.error(
|
||||
`[NOT IMPLEMENT] [RECOVER] delete account: ${account.id}`,
|
||||
);
|
||||
this.logger.error(
|
||||
`[NOT IMPLEMENT] [RECOVER] delete externalUser: ${externalUser.sub}`,
|
||||
);
|
||||
this.logger.error(`[NOT IMPLEMENT] [RECOVER] delete user: ${user.id}`);
|
||||
this.logger.error('send E-mail failed');
|
||||
//リカバリ処理
|
||||
// idpのユーザーを削除
|
||||
await this.deleteAdB2cUser(externalUser.sub, context);
|
||||
|
||||
// DBのアカウントを削除
|
||||
await this.deleteAccount(account.id, user.id, context);
|
||||
|
||||
// Blobコンテナを削除
|
||||
await this.deleteBlobContainer(account.id, country, context);
|
||||
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E009999'),
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
@ -268,6 +278,67 @@ export class AccountsService {
|
||||
}
|
||||
}
|
||||
|
||||
// AdB2cのユーザーを削除
|
||||
// TODO「タスク 2452: リトライ処理を入れる箇所を検討し、実装する」の候補
|
||||
private async deleteAdB2cUser(
|
||||
externalUserId: string,
|
||||
context: Context,
|
||||
): Promise<void> {
|
||||
try {
|
||||
await this.adB2cService.deleteUser(externalUserId, context);
|
||||
this.logger.log(
|
||||
`[${context.trackingId}] delete externalUser: ${externalUserId}`,
|
||||
);
|
||||
} catch (error) {
|
||||
this.logger.error(`error=${error}`);
|
||||
this.logger.error(
|
||||
`[MANUAL_RECOVERY_REQUIRED] [${context.trackingId}] Failed to delete externalUser: ${externalUserId}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// DBのアカウントを削除
|
||||
private async deleteAccount(
|
||||
accountId: number,
|
||||
userId: number,
|
||||
context: Context,
|
||||
): Promise<void> {
|
||||
try {
|
||||
await this.accountRepository.deleteAccount(accountId, userId);
|
||||
this.logger.log(
|
||||
`[${context.trackingId}] delete account: ${accountId}, user: ${userId}`,
|
||||
);
|
||||
} catch (error) {
|
||||
this.logger.error(`error=${error}`);
|
||||
this.logger.error(
|
||||
`[MANUAL_RECOVERY_REQUIRED] [${context.trackingId}] Failed to delete account: ${accountId}, user: ${userId}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Blobコンテナを削除
|
||||
// TODO「タスク 2452: リトライ処理を入れる箇所を検討し、実装する」の候補
|
||||
private async deleteBlobContainer(
|
||||
accountId: number,
|
||||
country: string,
|
||||
context: Context,
|
||||
): Promise<void> {
|
||||
try {
|
||||
await this.blobStorageService.deleteContainer(
|
||||
context,
|
||||
accountId,
|
||||
country,
|
||||
);
|
||||
this.logger.log(
|
||||
`[${context.trackingId}] delete container: ${accountId}, country: ${country}`,
|
||||
);
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
`[MANUAL_RECOVERY_REQUIRED] [${context.trackingId}] Failed to delete container: ${accountId}, country: ${country}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* アクセストークンからアカウント情報を取得する
|
||||
* @param token
|
||||
|
||||
@ -5,6 +5,7 @@ import {
|
||||
License,
|
||||
LicenseOrder,
|
||||
} from '../../../repositories/licenses/entity/license.entity';
|
||||
import { SortCriteria } from '../../../repositories/sort_criteria/entity/sort_criteria.entity';
|
||||
|
||||
// TODO: [PBI 2379] 他のUtilityからコピペしてきたもの。後日整理される前提。
|
||||
export const createAccountAndAdminUser = async (
|
||||
@ -162,6 +163,15 @@ export const getUsers = async (dataSource: DataSource): Promise<User[]> => {
|
||||
return await dataSource.getRepository(User).find();
|
||||
};
|
||||
|
||||
/**
|
||||
* テスト ユーティリティ: すべてのソート条件を取得する
|
||||
* @param dataSource データソース
|
||||
* @returns 該当ソート条件一覧
|
||||
*/
|
||||
export const getSortCriteria = async (dataSource: DataSource) => {
|
||||
return await dataSource.getRepository(SortCriteria).find();
|
||||
};
|
||||
|
||||
export const createLicense = async (
|
||||
datasource: DataSource,
|
||||
accountId: number,
|
||||
|
||||
@ -160,14 +160,14 @@ export class AccountsRepositoryService {
|
||||
const accountsRepo = entityManager.getRepository(Account);
|
||||
const usersRepo = entityManager.getRepository(User);
|
||||
const sortCriteriaRepo = entityManager.getRepository(SortCriteria);
|
||||
// アカウントを削除
|
||||
await accountsRepo.delete({ id: accountId });
|
||||
// プライマリ管理者を削除
|
||||
await usersRepo.delete({ id: userId });
|
||||
// ソート条件を削除
|
||||
await sortCriteriaRepo.delete({
|
||||
user_id: userId,
|
||||
});
|
||||
// プライマリ管理者を削除
|
||||
await usersRepo.delete({ id: userId });
|
||||
// アカウントを削除
|
||||
await accountsRepo.delete({ id: accountId });
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user