Merged PR 737: ファイル削除設定API作成
## 概要 [Task3546: ファイル削除設定API作成](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3546) - プロダクト バックログ項目 1199: アカウント設定を変更したい(ファイル削除設定) - ファイル削除設定API作成を実装しました - 変数定義時に型指定が不要で、自動的に明示的な型宣言が削除されています。非テストコードについてはeslint-disable-lineによって無視設定を行っています。テストコードについては削除したままとしています。 ## レビューポイント - 特筆するものはありません ## UIの変更 - 無し ## 動作確認状況 - ローカル及びユニットテストで確認 ## 補足 - 無し
This commit is contained in:
parent
91c27b7684
commit
32d8c6b896
@ -2033,7 +2033,12 @@ export class AccountsController {
|
||||
const context = makeContext(userId, requestId);
|
||||
this.logger.log(`[${context.getTrackingId()}] ip : ${ip}`);
|
||||
|
||||
// TODO:Service層呼び出し
|
||||
await this.accountService.updateFileDeleteSetting(
|
||||
context,
|
||||
userId,
|
||||
autoFileDelete,
|
||||
retentionDays,
|
||||
);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -143,7 +143,7 @@ describe('createAccount', () => {
|
||||
},
|
||||
});
|
||||
|
||||
let _subject: string = '';
|
||||
let _subject = '';
|
||||
let _url: string | undefined = '';
|
||||
overrideSendgridService(service, {
|
||||
sendMail: async (
|
||||
@ -6080,12 +6080,7 @@ describe('アカウント情報更新', () => {
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
overrideAdB2cService(service, {
|
||||
getUser: async () => {
|
||||
return { id: 'admin.external_id', displayName: 'admin' };
|
||||
},
|
||||
});
|
||||
let _subject: string = '';
|
||||
let _subject = '';
|
||||
let _url: string | undefined = '';
|
||||
overrideSendgridService(service, {
|
||||
sendMail: async (
|
||||
@ -6806,15 +6801,7 @@ describe('deleteAccountAndData', () => {
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
// ADB2Cユーザーの削除成功
|
||||
overrideAdB2cService(service, {
|
||||
deleteUsers: jest.fn(),
|
||||
getUsers: jest.fn(),
|
||||
getUser: async () => {
|
||||
return { id: 'admin.external_id', displayName: 'admin' };
|
||||
},
|
||||
});
|
||||
let _subject: string = '';
|
||||
let _subject = '';
|
||||
let _url: string | undefined = '';
|
||||
overrideSendgridService(service, {
|
||||
sendMail: async (
|
||||
@ -7460,3 +7447,142 @@ describe('getCompanyName', () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateFileDeleteSetting', () => {
|
||||
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が行われるため注意
|
||||
});
|
||||
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 service = module.get<AccountsService>(AccountsService);
|
||||
// 第五階層のアカウント作成
|
||||
const { account, admin } = await makeTestAccount(source, {
|
||||
tier: 5,
|
||||
});
|
||||
const context = makeContext(admin.external_id, 'requestId');
|
||||
|
||||
// 作成したデータを確認
|
||||
{
|
||||
const tier5Account = await getAccount(source, account.id);
|
||||
expect(tier5Account?.tier).toBe(5);
|
||||
}
|
||||
|
||||
// 更新するデータを設定
|
||||
const autoFileDelete = true;
|
||||
const retentionDays = 100;
|
||||
|
||||
await service.updateFileDeleteSetting(
|
||||
context,
|
||||
admin.external_id,
|
||||
autoFileDelete,
|
||||
retentionDays,
|
||||
);
|
||||
|
||||
// 更新後データの確認
|
||||
{
|
||||
const updatedAccount = await getAccount(source, account.id);
|
||||
expect(updatedAccount?.auto_file_delete).toBe(autoFileDelete);
|
||||
expect(updatedAccount?.file_retention_days).toBe(retentionDays);
|
||||
}
|
||||
});
|
||||
|
||||
it('対象アカウント非存在時に500エラーを返す', async () => {
|
||||
if (!source) fail();
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
|
||||
// 更新するデータを設定
|
||||
const nonExistentId = `nonExistentId`; // 存在しないIDを指定
|
||||
const autoFileDelete = true;
|
||||
const retentionDays = 100;
|
||||
|
||||
const context = makeContext(nonExistentId, 'requestId');
|
||||
try {
|
||||
await service.updateFileDeleteSetting(
|
||||
context,
|
||||
nonExistentId,
|
||||
autoFileDelete,
|
||||
retentionDays,
|
||||
);
|
||||
} catch (e) {
|
||||
if (e instanceof HttpException) {
|
||||
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('DBアクセスに失敗した場合、500エラーとなること', async () => {
|
||||
if (!source) fail();
|
||||
const module = await makeTestingModule(source);
|
||||
if (!module) fail();
|
||||
const service = module.get<AccountsService>(AccountsService);
|
||||
// 第五階層のアカウント作成
|
||||
const { account, admin } = await makeTestAccount(source, {
|
||||
tier: 5,
|
||||
});
|
||||
const context = makeContext(admin.external_id, 'requestId');
|
||||
|
||||
// 作成したデータを確認
|
||||
{
|
||||
const tier5Account = await getAccount(source, account.id);
|
||||
expect(tier5Account?.tier).toBe(5);
|
||||
}
|
||||
|
||||
//DBアクセスに失敗するようにする
|
||||
const usersRepositoryService = module.get<UsersRepositoryService>(
|
||||
UsersRepositoryService,
|
||||
);
|
||||
usersRepositoryService.findUserByExternalId = jest
|
||||
.fn()
|
||||
.mockRejectedValue('DB failed');
|
||||
|
||||
try {
|
||||
await service.updateFileDeleteSetting(
|
||||
context,
|
||||
admin.external_id,
|
||||
true,
|
||||
100,
|
||||
);
|
||||
} catch (e) {
|
||||
if (e instanceof HttpException) {
|
||||
expect(e.getStatus()).toEqual(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
expect(e.getResponse()).toEqual(makeErrorResponse('E009999'));
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -2534,4 +2534,51 @@ export class AccountsService {
|
||||
adminEmails: adminEmails,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 自動ファイル削除に関する設定を更新する
|
||||
* @param context
|
||||
* @param externalId
|
||||
* @param isAutoFileDelete // ファイルの自動削除可否
|
||||
* @param retentionDays // ファイルの保持期間
|
||||
*/
|
||||
async updateFileDeleteSetting(
|
||||
context: Context,
|
||||
externalId: string,
|
||||
isAutoFileDelete: boolean,
|
||||
retentionDays: number,
|
||||
): Promise<void> {
|
||||
this.logger.log(
|
||||
`[IN] [${context.getTrackingId()}] ${
|
||||
this.updateFileDeleteSetting.name
|
||||
} | params: { ` +
|
||||
`externalId: ${externalId}, ` +
|
||||
`autoFileDelete: ${isAutoFileDelete}, ` +
|
||||
`retentionDays: ${retentionDays}, };`,
|
||||
);
|
||||
|
||||
// アカウントテーブルの更新を行う
|
||||
try {
|
||||
// externalIdを基に自アカウントの情報を取得する
|
||||
const { account_id: accountId } =
|
||||
await this.usersRepository.findUserByExternalId(context, externalId);
|
||||
|
||||
await this.accountRepository.updateFileDeleteSetting(
|
||||
context,
|
||||
accountId,
|
||||
isAutoFileDelete,
|
||||
retentionDays,
|
||||
);
|
||||
} catch (e) {
|
||||
this.logger.error(`[${context.getTrackingId()}] error=${e}`);
|
||||
// アカウントが存在しない場合のエラーもINTERNAL_SERVER_ERROR扱いのため個別の判定は行わない
|
||||
|
||||
throw new HttpException(
|
||||
makeErrorResponse('E009999'),
|
||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
);
|
||||
} finally {
|
||||
this.logger.log(`[OUT] [${context.getTrackingId()}]`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -662,8 +662,8 @@ export class AccountsRepositoryService {
|
||||
);
|
||||
|
||||
// 第五の不足数を算出するためのライセンス数情報を取得する
|
||||
let expiringSoonLicense: number = 0;
|
||||
let allocatableLicenseWithMargin: number = 0;
|
||||
let expiringSoonLicense: number = 0; // eslint-disable-line
|
||||
let allocatableLicenseWithMargin: number = 0; // eslint-disable-line
|
||||
if (childAccount.tier === TIERS.TIER5) {
|
||||
expiringSoonLicense = await this.getExpiringSoonLicense(
|
||||
context,
|
||||
@ -1334,4 +1334,47 @@ export class AccountsRepositoryService {
|
||||
return users;
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* 自動ファイル削除に関する項目を更新する
|
||||
* @param accountId
|
||||
* @param isAutoFileDelete
|
||||
* @param retentionDays
|
||||
*/
|
||||
async updateFileDeleteSetting(
|
||||
context: Context,
|
||||
accountId: number,
|
||||
isAutoFileDelete: boolean,
|
||||
retentionDays: number,
|
||||
): Promise<void> {
|
||||
return await this.dataSource.transaction(async (entityManager) => {
|
||||
const accountRepo = entityManager.getRepository(Account);
|
||||
|
||||
// アカウントが存在するかチェック
|
||||
const account = await accountRepo.findOne({
|
||||
where: { id: accountId },
|
||||
comment: `${context.getTrackingId()}_${new Date().toUTCString()}`,
|
||||
lock: { mode: 'pessimistic_write' },
|
||||
});
|
||||
|
||||
// アカウントが存在しない場合はエラー
|
||||
if (!account) {
|
||||
throw new AccountNotFoundError(
|
||||
`Account is not found. id: ${accountId}`,
|
||||
);
|
||||
}
|
||||
|
||||
// 自動ファイル削除設定の更新を行う
|
||||
await updateEntity(
|
||||
accountRepo,
|
||||
{ id: accountId },
|
||||
{
|
||||
auto_file_delete: isAutoFileDelete,
|
||||
file_retention_days: retentionDays,
|
||||
},
|
||||
this.isCommentOut,
|
||||
context,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user