Merged PR 334: パートナー追加APIにBlobストレージ作成処理を追加

## 概要
[Task2421: パートナー追加APIにBlobストレージ作成処理を追加](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2421)

- パートナー追加APIにblobストレージ作成処理を追加しました。

## レビューポイント
- 修正内容に問題はないか

## UIの変更
- なし

## 動作確認状況
- ローカルで確認
This commit is contained in:
makabe.t 2023-08-18 01:01:26 +00:00
parent adbd57bca6
commit 502c31bcac
2 changed files with 328 additions and 73 deletions

View File

@ -33,6 +33,7 @@ import {
overrideBlobstorageService,
overrideSendgridService,
} from '../../common/test/overrides';
import { createAccountAndAdminUser } from '../users/test/utility';
describe('createAccount', () => {
let source: DataSource = null;
@ -1244,8 +1245,247 @@ describe('getDealers', () => {
});
});
describe('createAccount', () => {
it('新規にアカウントを作成できる', async () => {
expect(1).toBe(1);
describe('createPartnerAccount', () => {
let source: DataSource = null;
beforeEach(async () => {
source = new DataSource({
type: 'sqlite',
database: ':memory:',
logging: false,
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
synchronize: true, // trueにすると自動的にmigrationが行われるため注意
});
return source.initialize();
});
afterEach(async () => {
await source.destroy();
source = null;
});
it('パートナーを追加できる', async () => {
const module = await makeTestingModule(source);
const service = module.get<AccountsService>(AccountsService);
const parentExternalId = 'parent_external_id';
const { accountId: parentAccountId } = await createAccountAndAdminUser(
source,
parentExternalId,
);
const context = makeContext(parentExternalId);
const partnerExternalId = 'partner_external_id';
const companyName = 'partner_company_name';
const country = 'US';
const email = 'partner@example.com';
const username = 'partner_username';
overrideAdB2cService(service, {
createUser: async () => {
return { sub: partnerExternalId };
},
});
overrideSendgridService(service, {
sendMail: async () => {
return;
},
createMailContentFromEmailConfirm: async () => {
return { html: '', text: '', subject: '' };
},
});
overrideBlobstorageService(service, {
createContainer: async () => {},
});
{
const accounts = await getAccounts(source);
expect(accounts.length).toBe(1);
}
await service.createPartnerAccount(
context,
companyName,
country,
email,
username,
parentExternalId,
TIERS.TIER1,
);
{
const accounts = await getAccounts(source);
expect(accounts.length).toBe(2);
const partnerUser = await getUser(source, partnerExternalId);
const partnerAccount = await getAccount(source, partnerUser.account_id);
expect(partnerAccount.company_name).toBe(companyName);
expect(partnerAccount.country).toBe(country);
expect(partnerAccount.parent_account_id).toBe(parentAccountId);
expect(partnerAccount.tier).toBe(TIERS.TIER2);
expect(partnerAccount.primary_admin_user_id).toBe(partnerUser.id);
expect(partnerAccount.secondary_admin_user_id).toBe(null);
}
});
it('パートナーアカウントを作成がAzure AD B2Cへの通信失敗によって失敗すると500エラーが発生する', async () => {
const module = await makeTestingModule(source);
const service = module.get<AccountsService>(AccountsService);
const parentExternalId = 'parent_external_id';
await createAccountAndAdminUser(source, parentExternalId);
const context = makeContext(parentExternalId);
const companyName = 'partner_company_name';
const country = 'US';
const email = 'partner@example.com';
const username = 'partner_username';
overrideAdB2cService(service, {
createUser: async () => {
throw new Error();
},
});
overrideSendgridService(service, {
sendMail: async () => {
return;
},
createMailContentFromEmailConfirm: async () => {
return { html: '', text: '', subject: '' };
},
});
overrideBlobstorageService(service, {
createContainer: async () => {},
});
try {
await service.createPartnerAccount(
context,
companyName,
country,
email,
username,
parentExternalId,
TIERS.TIER1,
);
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toBe(HttpStatus.INTERNAL_SERVER_ERROR);
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
} else {
fail();
}
}
});
it('パートナーアカウントを作成がメールアドレス重複によって失敗すると400エラーが発生する', async () => {
const module = await makeTestingModule(source);
const service = module.get<AccountsService>(AccountsService);
const parentExternalId = 'parent_external_id';
await createAccountAndAdminUser(source, parentExternalId);
const context = makeContext(parentExternalId);
const companyName = 'partner_company_name';
const country = 'US';
const email = 'partner@example.com';
const username = 'partner_username';
overrideAdB2cService(service, {
createUser: async () => {
// EmailのConflictエラーを返す
return { reason: 'email', message: 'dummy' };
},
});
overrideSendgridService(service, {
sendMail: async () => {
return;
},
createMailContentFromEmailConfirm: async () => {
return { html: '', text: '', subject: '' };
},
});
overrideBlobstorageService(service, {
createContainer: async () => {},
});
try {
await service.createPartnerAccount(
context,
companyName,
country,
email,
username,
parentExternalId,
TIERS.TIER1,
);
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toBe(HttpStatus.BAD_REQUEST);
expect(e.getResponse()).toEqual(makeErrorResponse('E010301'));
} else {
fail();
}
}
});
it('パートナーアカウントを作成がBlobStorageへの通信失敗によって失敗すると500エラーが発生する', async () => {
const module = await makeTestingModule(source);
const service = module.get<AccountsService>(AccountsService);
const parentExternalId = 'parent_external_id';
await createAccountAndAdminUser(source, parentExternalId);
const context = makeContext(parentExternalId);
const partnerExternalId = 'partner_external_id';
const companyName = 'partner_company_name';
const country = 'US';
const email = 'partner@example.com';
const username = 'partner_username';
overrideAdB2cService(service, {
createUser: async () => {
return { sub: partnerExternalId };
},
});
overrideSendgridService(service, {
sendMail: async () => {
return;
},
createMailContentFromEmailConfirm: async () => {
return { html: '', text: '', subject: '' };
},
});
overrideBlobstorageService(service, {
createContainer: async () => {
throw new Error();
},
});
try {
await service.createPartnerAccount(
context,
companyName,
country,
email,
username,
parentExternalId,
TIERS.TIER1,
);
} catch (e) {
if (e instanceof HttpException) {
expect(e.getStatus()).toBe(HttpStatus.INTERNAL_SERVER_ERROR);
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
} else {
fail();
}
}
});
});

View File

@ -409,88 +409,103 @@ export class AccountsService {
`[IN] [${context.trackingId}] ${this.createPartnerAccount.name}`,
);
let myAccountId: number;
try {
// アクセストークンからユーザーIDを取得する
myAccountId = (await this.usersRepository.findUserByExternalId(userId))
.account_id;
} catch (e) {
this.logger.error(`error=${e}`);
if (e instanceof UserNotFoundError) {
throw new HttpException(
makeErrorResponse('E010204'),
HttpStatus.BAD_REQUEST,
let myAccountId: number;
try {
// アクセストークンからユーザーIDを取得する
myAccountId = (await this.usersRepository.findUserByExternalId(userId))
.account_id;
} catch (e) {
this.logger.error(`error=${e}`);
if (e instanceof UserNotFoundError) {
throw new HttpException(
makeErrorResponse('E010204'),
HttpStatus.BAD_REQUEST,
);
} else {
throw new HttpException(
makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
const ramdomPassword = makePassword();
let externalUser: { sub: string } | ConflictError;
try {
// 管理者ユーザを作成し、AzureADB2C IDを取得する
externalUser = await this.adB2cService.createUser(
context,
email,
ramdomPassword,
adminName,
);
} else {
} catch (e) {
this.logger.error(`error=${e}`);
throw new HttpException(
makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
}
const ramdomPassword = makePassword();
let externalUser: { sub: string } | ConflictError;
try {
// 管理者ユーザを作成し、AzureADB2C IDを取得する
externalUser = await this.adB2cService.createUser(
context,
email,
ramdomPassword,
adminName,
);
} catch (e) {
this.logger.error(`error=${e}`);
throw new HttpException(
makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
// メールアドレスが重複していた場合はエラーを返す
if (isConflictError(externalUser)) {
throw new HttpException(
makeErrorResponse('E010301'),
HttpStatus.BAD_REQUEST,
);
}
try {
// アカウントと管理者をセットで作成
const { newAccount, adminUser } =
await this.accountRepository.createAccount(
companyName,
country,
myAccountId,
tier + 1,
externalUser.sub,
USER_ROLES.NONE,
null,
// メールアドレスが重複していた場合はエラーを返す
if (isConflictError(externalUser)) {
throw new HttpException(
makeErrorResponse('E010301'),
HttpStatus.BAD_REQUEST,
);
}
const from = this.configService.get<string>('MAIL_FROM') || '';
const { subject, text, html } =
await this.sendgridService.createMailContentFromEmailConfirmForNormalUser(
try {
// アカウントと管理者をセットで作成
const { newAccount, adminUser } =
await this.accountRepository.createAccount(
companyName,
country,
myAccountId,
tier + 1,
externalUser.sub,
USER_ROLES.NONE,
null,
);
// 新規作成アカウント用のBlobコンテナを作成
await this.blobStorageService.createContainer(
context,
newAccount.id,
adminUser.id,
email,
country,
);
await this.sendgridService.sendMail(
context,
email,
from,
subject,
text,
html,
);
const from = this.configService.get<string>('MAIL_FROM') || '';
const { subject, text, html } =
await this.sendgridService.createMailContentFromEmailConfirmForNormalUser(
newAccount.id,
adminUser.id,
email,
);
await this.sendgridService.sendMail(
context,
email,
from,
subject,
text,
html,
);
} catch (e) {
this.logger.error(`error=${e}`);
this.logger.error('create partner account failed');
throw new HttpException(
makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
} catch (e) {
this.logger.error(`error=${e}`);
this.logger.error('create partner account failed');
throw new HttpException(
makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR,
throw e;
} finally {
this.logger.log(
`[OUT] [${context.trackingId}] ${this.createPartnerAccount.name}`,
);
}
}