## 概要 [Task3025: [ライセンスアラート改善]リトライ対応](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3025) ライセンスアラート処理にリトライ処理を追加しました。 メールの多重送信を防ぐために、送信成功したメールについてはredisに保存し、送信時にキャッシュをチェックする処理を入れました。 ## レビューポイント 処理の流れが妥当か。 redisに保存するキー、値は適切か。 if文のネストが相当深くなってしまったが、改善できるポイントはあるか。 ## UIの変更 なし ## 動作確認状況 ローカルで動作確認済み。(テスト用コードで無理やりエラーを発生させての確認) ## 補足 なし
300 lines
7.8 KiB
TypeScript
300 lines
7.8 KiB
TypeScript
import { DataSource } from "typeorm";
|
|
import { licenseAlertProcessing } from "../functions/licenseAlert";
|
|
import { makeTestAccount, createLicense } from "./common/utility";
|
|
import * as dotenv from "dotenv";
|
|
import {
|
|
DateWithDayEndTime,
|
|
DateWithZeroTime,
|
|
ExpirationThresholdDate,
|
|
NewTrialLicenseExpirationDate,
|
|
} from "../common/types/types";
|
|
import { AdB2cUser } from "../adb2c/types/types";
|
|
import { ADB2C_SIGN_IN_TYPE } from "../constants";
|
|
import { SendGridService } from "../sendgrid/sendgrid";
|
|
import { AdB2cService } from "../adb2c/adb2c";
|
|
import { InvocationContext } from "@azure/functions";
|
|
import { RedisClient } from "redis";
|
|
import { createRedisClient } from "../redis/redis";
|
|
|
|
describe("licenseAlert", () => {
|
|
dotenv.config({ path: ".env" });
|
|
dotenv.config({ path: ".env.local", override: true });
|
|
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 context = new InvocationContext();
|
|
const sendgridMock = new SendGridServiceMock() as SendGridService;
|
|
const adb2cMock = new AdB2cServiceMock() as AdB2cService;
|
|
const redisClient = createRedisClient();
|
|
// 呼び出し回数でテスト成否を判定
|
|
const spySend = jest.spyOn(sendgridMock, "sendMail");
|
|
|
|
const currentDate = new DateWithZeroTime();
|
|
const expiringSoonDate = new ExpirationThresholdDate(currentDate.getTime());
|
|
const { account, admin } = await makeTestAccount(
|
|
source,
|
|
{ tier: 5 },
|
|
{ external_id: "external_id1" }
|
|
);
|
|
await createLicense(
|
|
source,
|
|
1,
|
|
expiringSoonDate,
|
|
account.id,
|
|
"STANDARD",
|
|
"Allocated",
|
|
admin.id,
|
|
null,
|
|
null,
|
|
null
|
|
);
|
|
|
|
await licenseAlertProcessing(
|
|
context,
|
|
source,
|
|
redisClient,
|
|
sendgridMock,
|
|
adb2cMock
|
|
);
|
|
expect(spySend.mock.calls).toHaveLength(1);
|
|
redisClient.quit;
|
|
});
|
|
|
|
it("ライセンス在庫不足メール、ライセンス失効警告メールが送信されること", async () => {
|
|
if (!source) fail();
|
|
const context = new InvocationContext();
|
|
const sendgridMock = new SendGridServiceMock() as SendGridService;
|
|
const adb2cMock = new AdB2cServiceMock() as AdB2cService;
|
|
const redisClient = createRedisClient();
|
|
|
|
// 呼び出し回数でテスト成否を判定
|
|
const spySend = jest.spyOn(sendgridMock, "sendMail");
|
|
|
|
const currentDate = new DateWithZeroTime();
|
|
const expiringSoonDate = new DateWithDayEndTime(currentDate.getTime());
|
|
const { account, admin } = await makeTestAccount(
|
|
source,
|
|
{ tier: 5 },
|
|
{ external_id: "external_id2", auto_renew: false }
|
|
);
|
|
await createLicense(
|
|
source,
|
|
1,
|
|
expiringSoonDate,
|
|
account.id,
|
|
"STANDARD",
|
|
"Allocated",
|
|
admin.id,
|
|
null,
|
|
null,
|
|
null
|
|
);
|
|
|
|
await licenseAlertProcessing(
|
|
context,
|
|
source,
|
|
redisClient,
|
|
sendgridMock,
|
|
adb2cMock
|
|
);
|
|
expect(spySend.mock.calls).toHaveLength(2);
|
|
redisClient.quit;
|
|
});
|
|
|
|
it("在庫があるため、ライセンス在庫不足メールが送信されないこと", async () => {
|
|
if (!source) fail();
|
|
const context = new InvocationContext();
|
|
const sendgridMock = new SendGridServiceMock() as SendGridService;
|
|
const adb2cMock = new AdB2cServiceMock() as AdB2cService;
|
|
const redisClient = createRedisClient();
|
|
|
|
// 呼び出し回数でテスト成否を判定
|
|
const spySend = jest.spyOn(sendgridMock, "sendMail");
|
|
|
|
const currentDate = new DateWithZeroTime();
|
|
const expiringSoonDate = new ExpirationThresholdDate(currentDate.getTime());
|
|
const expiryDate = new NewTrialLicenseExpirationDate(currentDate.getTime());
|
|
const { account, admin } = await makeTestAccount(
|
|
source,
|
|
{ tier: 5 },
|
|
{ external_id: "external_id3" }
|
|
);
|
|
await createLicense(
|
|
source,
|
|
1,
|
|
expiringSoonDate,
|
|
account.id,
|
|
"STANDARD",
|
|
"Allocated",
|
|
admin.id,
|
|
null,
|
|
null,
|
|
null
|
|
);
|
|
await createLicense(
|
|
source,
|
|
2,
|
|
expiryDate,
|
|
account.id,
|
|
"STANDARD",
|
|
"Unallocated",
|
|
null,
|
|
null,
|
|
null,
|
|
null
|
|
);
|
|
|
|
await licenseAlertProcessing(
|
|
context,
|
|
source,
|
|
redisClient,
|
|
sendgridMock,
|
|
adb2cMock
|
|
);
|
|
expect(spySend.mock.calls).toHaveLength(0);
|
|
redisClient.quit;
|
|
});
|
|
|
|
it("AutoRenewがtureのため、ライセンス失効警告メールが送信されないこと", async () => {
|
|
if (!source) fail();
|
|
const context = new InvocationContext();
|
|
const sendgridMock = new SendGridServiceMock() as SendGridService;
|
|
const adb2cMock = new AdB2cServiceMock() as AdB2cService;
|
|
const redisClient = createRedisClient();
|
|
|
|
// 呼び出し回数でテスト成否を判定
|
|
const spySend = jest.spyOn(sendgridMock, "sendMail");
|
|
|
|
const currentDate = new DateWithZeroTime();
|
|
const expiringSoonDate = new DateWithDayEndTime(currentDate.getTime());
|
|
const { account, admin } = await makeTestAccount(
|
|
source,
|
|
{ tier: 5 },
|
|
{ external_id: "external_id4", auto_renew: true }
|
|
);
|
|
await createLicense(
|
|
source,
|
|
1,
|
|
expiringSoonDate,
|
|
account.id,
|
|
"STANDARD",
|
|
"Allocated",
|
|
admin.id,
|
|
null,
|
|
null,
|
|
null
|
|
);
|
|
|
|
await licenseAlertProcessing(
|
|
context,
|
|
source,
|
|
redisClient,
|
|
sendgridMock,
|
|
adb2cMock
|
|
);
|
|
expect(spySend.mock.calls).toHaveLength(1);
|
|
redisClient.quit;
|
|
});
|
|
});
|
|
|
|
// テスト用sendgrid
|
|
export class SendGridServiceMock {
|
|
/**
|
|
* メールを送信する
|
|
* @param to
|
|
* @param from
|
|
* @param subject
|
|
* @param text
|
|
* @param html
|
|
* @returns mail
|
|
*/
|
|
async sendMail(
|
|
to: string,
|
|
from: string,
|
|
subject: string,
|
|
text: string,
|
|
html: string
|
|
): Promise<void> {
|
|
return;
|
|
}
|
|
}
|
|
|
|
// テスト用adb2c
|
|
export class AdB2cServiceMock {
|
|
/**
|
|
* Azure AD B2Cからユーザ情報を取得する
|
|
* @param externalIds 外部ユーザーID
|
|
* @returns ユーザ情報
|
|
*/
|
|
async getUsers(
|
|
context: InvocationContext,
|
|
redisClient: RedisClient,
|
|
externalIds: string[]
|
|
): Promise<AdB2cUser[]> {
|
|
const AdB2cMockUsers: AdB2cUser[] = [
|
|
{
|
|
id: "external_id1",
|
|
displayName: "test1",
|
|
identities: [
|
|
{
|
|
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
|
|
issuer: "issuer",
|
|
issuerAssignedId: "test1@mail.com",
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: "external_id2",
|
|
displayName: "test2",
|
|
identities: [
|
|
{
|
|
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
|
|
issuer: "issuer",
|
|
issuerAssignedId: "test2@mail.com",
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: "external_id3",
|
|
displayName: "test3",
|
|
identities: [
|
|
{
|
|
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
|
|
issuer: "issuer",
|
|
issuerAssignedId: "test3@mail.com",
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: "external_id4",
|
|
displayName: "test4",
|
|
identities: [
|
|
{
|
|
signInType: ADB2C_SIGN_IN_TYPE.EMAILADDRESS,
|
|
issuer: "issuer",
|
|
issuerAssignedId: "test4@mail.com",
|
|
},
|
|
],
|
|
},
|
|
];
|
|
return AdB2cMockUsers;
|
|
}
|
|
}
|