Merged PR 922: Functions
## 概要 [Task4485: Functions](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/4485) - 元PBI or タスクへのリンク(内容・目的などはそちらにあるはず) - 何をどう変更したか、追加したライブラリなど - このPull Requestでの対象/対象外 - 影響範囲(他の機能にも影響があるか) ## レビューポイント - 特にレビューしてほしい箇所 - 軽微なものや自明なものは記載不要 - 修正範囲が大きい場合などに記載 - 全体的にや仕様を満たしているか等は本当に必要な時のみ記載 - 修正箇所がほかの機能に影響していないか ## UIの変更 - Before/Afterのスクショなど - スクショ置き場 ## クエリの変更 - Repositoryを変更し、クエリが変更された場合は変更内容を確認する - Before/Afterのクエリ - クエリ置き場 ## 動作確認状況 - ローカルで確認、develop環境で確認など - 行った修正がデグレを発生させていないことを確認できるか - 具体的にどのような確認をしたか - どのケースに対してどのような手段でデグレがないことを担保しているか ## 補足 - 相談、参考資料などがあれば
This commit is contained in:
parent
f1b75a7ff0
commit
85fdec2e5a
@ -667,13 +667,14 @@ export async function sendMailWithU108(
|
||||
.replaceAll(USER_EMAIL, userMail)
|
||||
.replaceAll(TOP_URL, url);
|
||||
}
|
||||
const ccAddress = customerAdminMails.includes(userMail) ? [] : [userMail];
|
||||
const uniqueCustomerAdminMails = [...new Set(customerAdminMails)];
|
||||
const ccMails = uniqueCustomerAdminMails.includes(userMail) ? [] : [userMail];
|
||||
|
||||
// メールを送信する
|
||||
await sendGrid.sendMail(
|
||||
context,
|
||||
customerAdminMails,
|
||||
ccAddress,
|
||||
uniqueCustomerAdminMails,
|
||||
ccMails,
|
||||
mailFrom,
|
||||
subject,
|
||||
text,
|
||||
|
||||
133
dictation_function/src/sendgrid/sendgrid.spec.ts
Normal file
133
dictation_function/src/sendgrid/sendgrid.spec.ts
Normal file
@ -0,0 +1,133 @@
|
||||
import { SendGridService } from "./sendgrid";
|
||||
import sendgrid from "@sendgrid/mail";
|
||||
import { InvocationContext } from "@azure/functions";
|
||||
|
||||
// sendgridのsend関数をモック化
|
||||
jest.mock("@sendgrid/mail", () => ({
|
||||
send: jest.fn(),
|
||||
setApiKey: jest.fn(),
|
||||
}));
|
||||
|
||||
describe("SendGridService", () => {
|
||||
let service: SendGridService;
|
||||
let mockContext: Partial<InvocationContext>;
|
||||
|
||||
beforeEach(() => {
|
||||
process.env.SENDGRID_API_KEY = "dummy_key"; // 必要な環境変数
|
||||
service = new SendGridService(); // SendGridServiceのインスタンスを作成
|
||||
mockContext = {
|
||||
log: jest.fn(),
|
||||
warn: jest.fn(),
|
||||
}; // InvocationContextのモック
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it("should send an email with no duplicate to and cc addresses", async () => {
|
||||
// モックデータ
|
||||
const to = ["test1@example.com", "test2@example.com"];
|
||||
const cc = ["test3@example.com"];
|
||||
const from = "sender@example.com";
|
||||
const subject = "Test Subject";
|
||||
const text = "Test Text";
|
||||
const html = "<p>Test HTML</p>";
|
||||
|
||||
// sendgrid.sendのモック
|
||||
(sendgrid.send as jest.Mock).mockResolvedValue([
|
||||
{ statusCode: 202, body: "OK" },
|
||||
]);
|
||||
|
||||
// メール送信を実行
|
||||
await service.sendMail(
|
||||
mockContext as InvocationContext,
|
||||
to,
|
||||
cc,
|
||||
from,
|
||||
subject,
|
||||
text,
|
||||
html
|
||||
);
|
||||
|
||||
// sendgrid.sendが呼ばれたことを確認
|
||||
expect(sendgrid.send).toHaveBeenCalledWith({
|
||||
from: { email: from },
|
||||
to: to.map((v) => ({ email: v })),
|
||||
cc: cc.map((v) => ({ email: v })),
|
||||
subject,
|
||||
text,
|
||||
html,
|
||||
});
|
||||
|
||||
// ログが出力されているか確認
|
||||
expect(mockContext.log).toHaveBeenCalledWith(`[IN] sendMail`);
|
||||
expect(mockContext.log).toHaveBeenCalledWith(`[OUT] sendMail`);
|
||||
});
|
||||
|
||||
it("should remove duplicate addresses in to and cc", async () => {
|
||||
const to = ["test1@example.com", "test2@example.com", "test1@example.com"]; // 重複あり
|
||||
const cc = ["test2@example.com", "test3@example.com"]; // 重複あり
|
||||
const from = "sender@example.com";
|
||||
const subject = "Test Subject";
|
||||
const text = "Test Text";
|
||||
const html = "<p>Test HTML</p>";
|
||||
|
||||
// sendgrid.sendのモック
|
||||
(sendgrid.send as jest.Mock).mockResolvedValue([
|
||||
{ statusCode: 202, body: "OK" },
|
||||
]);
|
||||
|
||||
// メール送信を実行
|
||||
await service.sendMail(
|
||||
mockContext as InvocationContext,
|
||||
to,
|
||||
cc,
|
||||
from,
|
||||
subject,
|
||||
text,
|
||||
html
|
||||
);
|
||||
|
||||
// 重複が削除されているか確認
|
||||
expect(sendgrid.send).toHaveBeenCalledWith({
|
||||
from: { email: from },
|
||||
to: [{ email: "test1@example.com" }, { email: "test2@example.com" }], // 重複削除後
|
||||
cc: [{ email: "test3@example.com" }], // ccから重複が削除される
|
||||
subject,
|
||||
text,
|
||||
html,
|
||||
});
|
||||
});
|
||||
|
||||
it("should log an error when send fails", async () => {
|
||||
const to = ["test1@example.com"];
|
||||
const cc = ["test2@example.com"];
|
||||
const from = "sender@example.com";
|
||||
const subject = "Test Subject";
|
||||
const text = "Test Text";
|
||||
const html = "<p>Test HTML</p>";
|
||||
|
||||
// sendgrid.sendがエラーを投げるモック
|
||||
(sendgrid.send as jest.Mock).mockRejectedValue(new Error("Send failed"));
|
||||
|
||||
// エラーが投げられるか確認
|
||||
await expect(
|
||||
service.sendMail(
|
||||
mockContext as InvocationContext,
|
||||
to,
|
||||
cc,
|
||||
from,
|
||||
subject,
|
||||
text,
|
||||
html
|
||||
)
|
||||
).rejects.toThrow("Send failed");
|
||||
|
||||
// エラーログが出力されているか確認
|
||||
expect(mockContext.warn).toHaveBeenCalledWith("send mail faild.");
|
||||
expect(mockContext.warn).toHaveBeenCalledWith(
|
||||
expect.stringContaining("sendMail error=Error: Send failed")
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -32,22 +32,28 @@ export class SendGridService {
|
||||
): Promise<void> {
|
||||
context.log(`[IN] ${this.sendMail.name}`);
|
||||
try {
|
||||
// 1. toの重複を削除
|
||||
const uniqueTo = [...new Set(to)];
|
||||
|
||||
// 2. ccの重複を削除
|
||||
let uniqueCc = [...new Set(cc)];
|
||||
|
||||
// 3. toとccの重複を削除(cc側から削除)
|
||||
uniqueCc = uniqueCc.filter((email) => !uniqueTo.includes(email));
|
||||
const res = await sendgrid
|
||||
.send({
|
||||
from: {
|
||||
email: from,
|
||||
},
|
||||
to: to.map((v) => ({ email: v })),
|
||||
cc: cc.map((v) => ({ email: v })),
|
||||
to: uniqueTo.map((v) => ({ email: v })),
|
||||
cc: uniqueCc.map((v) => ({ email: v })),
|
||||
subject: subject,
|
||||
text: text,
|
||||
html: html,
|
||||
})
|
||||
.then((v) => v[0]);
|
||||
context.log(
|
||||
` status code: ${
|
||||
res.statusCode
|
||||
} body: ${JSON.stringify(res.body)}`,
|
||||
` status code: ${res.statusCode} body: ${JSON.stringify(res.body)}`
|
||||
);
|
||||
} catch (e) {
|
||||
context.warn(`send mail faild.`);
|
||||
|
||||
@ -1622,13 +1622,21 @@ export class SendGridService {
|
||||
): Promise<void> {
|
||||
this.logger.log(`[IN] [${context.getTrackingId()}] ${this.sendMail.name}`);
|
||||
try {
|
||||
// toの重複を削除
|
||||
const uniqueTo = [...new Set(to)];
|
||||
|
||||
// ccの重複を削除
|
||||
let uniqueCc = [...new Set(cc)];
|
||||
|
||||
// toとccの重複を削除(cc側から削除)
|
||||
uniqueCc = uniqueCc.filter((email) => !uniqueTo.includes(email));
|
||||
const res = await sendgrid
|
||||
.send({
|
||||
from: {
|
||||
email: from,
|
||||
},
|
||||
to: to.map((v) => ({ email: v })),
|
||||
cc: cc.map((v) => ({ email: v })),
|
||||
to: uniqueTo.map((v) => ({ email: v })),
|
||||
cc: uniqueCc.map((v) => ({ email: v })),
|
||||
subject: subject,
|
||||
text: text,
|
||||
html: html,
|
||||
|
||||
133
dictation_server/src/gateways/sendgrid/sendgrid.spec.ts
Normal file
133
dictation_server/src/gateways/sendgrid/sendgrid.spec.ts
Normal file
@ -0,0 +1,133 @@
|
||||
import sendgrid from '@sendgrid/mail';
|
||||
import { SendGridService } from './sendgrid.service';
|
||||
import { Context, makeContext } from '../../common/log';
|
||||
|
||||
// sendgridのsend関数をモック化
|
||||
jest.mock('@sendgrid/mail', () => ({
|
||||
send: jest.fn(),
|
||||
setApiKey: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('SendGridService', () => {
|
||||
let context: Context;
|
||||
let configServiceMock: any;
|
||||
let loggerMock: any;
|
||||
|
||||
beforeEach(() => {
|
||||
// Loggerのモックを作成
|
||||
loggerMock = {
|
||||
log: jest.fn(),
|
||||
error: jest.fn(),
|
||||
};
|
||||
configServiceMock = {
|
||||
getOrThrow: jest.fn(() => 'dummy'),
|
||||
get: jest.fn(() => 'SENDGRID_API_KEY'),
|
||||
};
|
||||
|
||||
// sendgridのAPIキーを設定
|
||||
sendgrid.setApiKey(configServiceMock.get('SENDGRID_API_KEY'));
|
||||
|
||||
// クラスにモックのloggerを注入
|
||||
(SendGridService as any).logger = loggerMock;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('宛先とccアドレスが重複しないメールを送信すること', async () => {
|
||||
// モックデータ
|
||||
const to = ['test1@example.com', 'test2@example.com'];
|
||||
const cc = ['test3@example.com'];
|
||||
const from = 'sender@example.com';
|
||||
const subject = 'Test Subject';
|
||||
const text = 'Test Text';
|
||||
const html = '<p>Test HTML</p>';
|
||||
|
||||
// sendgrid.sendのモック
|
||||
(sendgrid.send as jest.Mock).mockResolvedValue([
|
||||
{ statusCode: 202, body: 'OK' },
|
||||
]);
|
||||
|
||||
// メール送信を実行
|
||||
await new SendGridService(configServiceMock).sendMail(
|
||||
makeContext('trackingId', 'requestId'),
|
||||
to,
|
||||
cc,
|
||||
from,
|
||||
subject,
|
||||
text,
|
||||
html,
|
||||
);
|
||||
|
||||
// sendgrid.sendが呼ばれたことを確認
|
||||
expect(sendgrid.send).toHaveBeenCalledWith({
|
||||
from: { email: from },
|
||||
to: to.map((v) => ({ email: v })),
|
||||
cc: cc.map((v) => ({ email: v })),
|
||||
subject,
|
||||
text,
|
||||
html,
|
||||
});
|
||||
});
|
||||
|
||||
it('宛先と CC に重複したメールアドレスがあった場合、削除してからメールを送信すること(宛先とCCの重複があったときはCCを削除すること)', async () => {
|
||||
const to = ['test1@example.com', 'test2@example.com', 'test1@example.com']; // 重複あり
|
||||
const cc = ['test2@example.com', 'test3@example.com']; // 重複あり
|
||||
const from = 'sender@example.com';
|
||||
const subject = 'Test Subject';
|
||||
const text = 'Test Text';
|
||||
const html = '<p>Test HTML</p>';
|
||||
|
||||
// sendgrid.sendのモック
|
||||
(sendgrid.send as jest.Mock).mockResolvedValue([
|
||||
{ statusCode: 202, body: 'OK' },
|
||||
]);
|
||||
|
||||
// メール送信を実行
|
||||
await new SendGridService(configServiceMock).sendMail(
|
||||
makeContext('trackingId', 'requestId'),
|
||||
to,
|
||||
cc,
|
||||
from,
|
||||
subject,
|
||||
text,
|
||||
html,
|
||||
);
|
||||
|
||||
// 重複が削除されているか確認
|
||||
expect(sendgrid.send).toHaveBeenCalledWith({
|
||||
from: { email: from },
|
||||
to: [{ email: 'test1@example.com' }, { email: 'test2@example.com' }], // 重複削除後
|
||||
cc: [{ email: 'test3@example.com' }], // ccから重複が削除される
|
||||
subject,
|
||||
text,
|
||||
html,
|
||||
});
|
||||
});
|
||||
|
||||
it('送信に失敗したときはエラーを記録すること', async () => {
|
||||
const to = ['test1@example.com'];
|
||||
const cc = ['test2@example.com'];
|
||||
const from = 'sender@example.com';
|
||||
const subject = 'Test Subject';
|
||||
const text = 'Test Text';
|
||||
const html = '<p>Test HTML</p>';
|
||||
|
||||
// sendgrid.sendがエラーを投げるモック
|
||||
(sendgrid.send as jest.Mock).mockRejectedValue(new Error('Send failed'));
|
||||
|
||||
// エラーが投げられるか確認
|
||||
await expect(
|
||||
new SendGridService(configServiceMock).sendMail(
|
||||
makeContext('trackingId', 'requestId'),
|
||||
to,
|
||||
cc,
|
||||
from,
|
||||
subject,
|
||||
text,
|
||||
html,
|
||||
),
|
||||
).rejects.toThrow('Send failed');
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user