Merged PR 857: テスト追加

## 概要
[Task3977: テスト追加](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3977)

- エラー時にアラーム発報ログが出力されているかを確認するテストを追加
- contextを継承して、ログに吐き出す内容をstring型の配列として溜め込むテスト用のクラスを追加

## レビューポイント
- テストの内容は妥当か

## クエリの変更
- テストのみ追加なので変更なし

## 動作確認状況
- npm run testが通過したこと
This commit is contained in:
湯本 開 2024-03-26 07:05:39 +00:00
parent 114ded790e
commit 1d71bef7aa
2 changed files with 150 additions and 1 deletions

View File

@ -0,0 +1,16 @@
import { InvocationContext } from "@azure/functions";
export class TestInvocationContext extends InvocationContext {
contents: string[] = [];
getLogs(): string[] {
return this.contents;
}
log(...args: any[]): void {
super.log(args);
this.contents.push(args.toString());
}
error(...args: any[]): void {
super.error(args);
this.contents.push(args.toString());
}
}

View File

@ -15,7 +15,7 @@ import {
makeTestAccount,
makeTestTask,
} from "./common/utility";
import { TASK_STATUS } from "../constants";
import { MANUAL_RECOVERY_REQUIRED, TASK_STATUS } from "../constants";
import { TestLogger } from "./common/logger";
import { AudioFile } from "../entity/audio_file.entity";
import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity";
@ -30,6 +30,7 @@ import {
LicenseArchive,
} from "../entity/license.entity";
import { AudioOptionItem } from "../entity/audio_option_item.entity";
import { TestInvocationContext } from "./common/context";
describe("getProcessTargets | 削除対象を特定するQueryが正常に動作するか確認する", () => {
let source: DataSource | null = null;
@ -1493,4 +1494,136 @@ describe("deleteAudioFilesProcessing", () => {
expect(optionItems.length).toEqual(4);
}
});
it("Blobの削除でエラーが発生した場合、アラーム発報用のログが出力される", async () => {
if (!source) fail();
// 2024/02/29 00:00:00を"今"とする
const now = new Date("2024-02-29T00:00:00Z");
const { account: account01, admin: admin01 } = await makeTestAccount(
source,
{
file_retention_days: 2,
auto_file_delete: true,
}
);
// 2日と1秒前(削除対象)のタスクを作成
const { file: file1 } = await makeTestTask(
source,
account01.id,
admin01.id,
"case03",
{
status: TASK_STATUS.FINISHED,
job_number: "job03",
finished_at: new Date("2024-02-26T23:59:59Z"),
}
);
const args: { accountId: number; fileName: string; country: string }[] = [];
const blobstorage = new AudioBlobStorageService();
Object.defineProperty(blobstorage, blobstorage.deleteFile.name, {
value: async (
context: InvocationContext,
accountId: number,
country: string,
fileName: string
): Promise<void> => {
throw new Error(
`delete blob failed. succeeded: ${false}, errorCode: ${"ERROR_CODE"}, date: ${"DATE"}`
);
},
writable: true,
});
{
// DB全体のレコードを確認
const tasks = await getTasks(source);
expect(tasks.length).toEqual(1);
const files = await getAudioFiles(source);
expect(files.length).toEqual(1);
const optionItems = await getAudioOptionItems(source);
expect(optionItems.length).toEqual(2);
}
const context = new TestInvocationContext();
await deleteAudioFilesProcessing(context, source, blobstorage, now);
const log = context
.getLogs()
.find((log) => log.includes(MANUAL_RECOVERY_REQUIRED));
expect(log).toBeDefined();
expect(log).toEqual(
`[MANUAL_RECOVERY_REQUIRED] file delete failed. target={"id":"1","audio_file_id":"1","account_id":"1","country":"US","file_name":"testcase03.wav"}`
);
});
it("DBの削除でエラーが発生した場合、アラーム発報用のログが出力される", async () => {
if (!source) fail();
// 2024/02/29 00:00:00を"今"とする
const now = new Date("2024-02-29T00:00:00Z");
const { account: account01, admin: admin01 } = await makeTestAccount(
source,
{
file_retention_days: 2,
auto_file_delete: true,
}
);
// 2日と1秒前(削除対象)のタスクを作成
await makeTestTask(source, account01.id, admin01.id, "case03", {
status: TASK_STATUS.FINISHED,
job_number: "job03",
finished_at: new Date("2024-02-26T23:59:59Z"),
});
const args: { accountId: number; fileName: string; country: string }[] = [];
const blobstorage = new AudioBlobStorageService();
Object.defineProperty(blobstorage, blobstorage.deleteFile.name, {
value: async (
context: InvocationContext,
accountId: number,
country: string,
fileName: string
): Promise<void> => {
args.push({ accountId, country, fileName });
},
writable: true,
});
{
// DB全体のレコードを確認
const tasks = await getTasks(source);
expect(tasks.length).toEqual(1);
const files = await getAudioFiles(source);
expect(files.length).toEqual(1);
const optionItems = await getAudioOptionItems(source);
expect(optionItems.length).toEqual(2);
}
Object.defineProperty(source, "transaction", {
value: async () => {
throw new Error("transaction error");
},
writable: true,
});
const context = new TestInvocationContext();
await expect(
deleteAudioFilesProcessing(context, source, blobstorage, now)
).rejects.toThrow();
const log = context
.getLogs()
.find((log) => log.includes(MANUAL_RECOVERY_REQUIRED));
expect(log).toBeDefined();
expect(log).toEqual(
`[MANUAL_RECOVERY_REQUIRED] Failed to execute auto file deletion function. error=Error: transaction error`
);
});
});