Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { describe, expect, it } from "vitest";

import "../initWinstonForTest";
import "jc-backend/configure.js";
import conf from "jc-shared/commons/simpleConfigure.js";
import { toTransportObject } from "jc-backend/lib/mailsender/mailtransport.js";
import MailMessage from "jc-shared/mail/mailMessage";
import User from "jc-shared/user/user";
import MailMessage from "jc-shared/mail/mailMessage.js";
import User from "jc-shared/user/user.js";

conf.addProperties({
"sender-name": "Der Sender",
Expand All @@ -16,20 +15,21 @@ describe("Mailrendering works", () => {
const message = new MailMessage({
subject: "[B-O Jazzclub] Mails sent",
});
(message.body = `Nightly Mails have been sent
message.body = `Nightly Mails have been sent
Anzahl: 5
Error: "keiner"`),
it("renders html and text", () => {
const res = toTransportObject(message, false);
expect(res.html).to.equal(`<!DOCTYPE html>
Error: "keiner"`;

it("renders html and text", () => {
const res = toTransportObject(message, false);
expect(res.html).to.equal(`<!DOCTYPE html>
<html>
<body><p>Nightly Mails have been sent<br>Anzahl: 5<br>Error: &quot;keiner&quot;</p>
</body>
</html>`);
expect(res.text).to.equal(`Nightly Mails have been sent
expect(res.text).to.equal(`Nightly Mails have been sent
Anzahl: 5
Error: "keiner"`);
});
});

it("uses the predefined sender", () => {
const message = new MailMessage({ subject: "" });
Expand Down
4 changes: 2 additions & 2 deletions application/batchjobs/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ async function run() {

const jobtypes: JobType[] = ["Presse", "Fluegel", "Photo", "TextFehlt", "Kasse", "Programmheft", "Staff", "Bar"];

const typedResults = results.map((each, index) => ({ type: jobtypes[index], each }));
const typedResults = results.map((jobResult, index) => ({ type: jobtypes[index], jobResult }));

await Promise.all(typedResults.map(informAdmin));
await informAdmin(typedResults);
closeAndExit();
} catch (e) {
closeAndExit(e as Error);
Expand Down
67 changes: 38 additions & 29 deletions application/batchjobs/src/sendMailToAdmin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,45 +10,54 @@ const receiver = "leider";

export type JobType = "Programmheft" | "Presse" | "Kasse" | "Bar" | "Photo" | "Fluegel" | "TextFehlt" | "Staff";

export async function informAdmin({ type, each }: { type: JobType; each: JobResult }) {
const infosCompacted = Array.isArray(each.result) ? compact(each.result) : compact([each.result]);

if (each === undefined || (!infosCompacted.length && !each.error)) {
console.log(`nothing happened for JobType "${type}"`);
return;
}
export async function informAdmin(allResults: { type: JobType; jobResult: JobResult }[]) {
const user = userstore.forId(receiver);
if (!user) {
console.error("User not found");
return;
}
user.email = "nadreas.leidig@jazzclub.de";

if (each.error) {
console.error(`error occurred while informing ${each.error}`);
}
let errorHappened = false;

function createBodyFragment({ type, jobResult }: { type: JobType; jobResult: JobResult }) {
const error = jobResult.error;
const infosCompacted = Array.isArray(jobResult.result) ? compact(jobResult.result) : compact([jobResult.result]);

if (!infosCompacted.length && !error) {
console.log(`nothing happened for JobType "${type}"`);
return;
}
if (error) {
errorHappened = true;
console.error(`error occurred while informing for type: ${type}. ERROR: ${error}`);
}

const infos = infosCompacted.map(({ accepted, rejected, response }) => ({
accepted,
rejected,
response,
}));
const count = infos.length;

return `**${type}** ${count} Mail(s)

${
error
? `### Es gibt Fehler!
${error}`
: `${"\n```\n" + JSON.stringify(infos, null, 2) + "\n```"}`
}`;
} // end function createBodyFragment

const infos = infosCompacted.map(({ accepted, rejected, response, envelope }) => ({
accepted,
rejected,
response,
envelope,
}));
const count = infos.length;
const bodyFragments = compact(allResults.map(createBodyFragment));
if (!bodyFragments.length) {
return;
}

const message = new MailMessage({
subject: `[${each.error ? "ERROR" : "INFO"} B-O Jazzclub] Mails sent for jobtype "${type}"`,
subject: `[${errorHappened ? "ERROR" : "INFO"} B-O Jazzclub] Mails sent`,
});
message.to = [{ name: user.name, address: user.email }];
message.body = `${count} nightly Mails for jobtype "${type}" have been sent.

${
each.error
? `Es gibt Fehler! ${each.error.message}

${each.error}`
: `Informationen zu den gesendeten E-Mails:
${"\n```\n" + JSON.stringify(infos, null, 2) + "\n```"}`
}`;
message.body = bodyFragments.join("\n");
return mailtransport.sendMail(message);
}
13 changes: 6 additions & 7 deletions application/batchjobs/test/mailsender/sendForRules.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,18 @@ import DatumUhrzeit from "jc-shared/commons/DatumUhrzeit.js";
import mailtransport from "jc-backend/lib/mailsender/mailtransport.js";
import vermietungenstore from "jc-backend/lib/vermietungen/vermietungenstore.js";
import konzertestore from "jc-backend/lib/konzerte/konzertestore.js";
import userstore from "jc-backend/lib/users/userstore";
import { testKonzerte, testUsers, testVermietungen } from "./testObjects";
import { loadRulesAndProcess } from "../../src/sendMailsForRules";
import mailstore from "jc-backend/lib/mailsender/mailstore";
import MailRule from "jc-shared/mail/mailRule";
import userstore from "jc-backend/lib/users/userstore.js";
import { testKonzerte, testUsers, testVermietungen } from "./testObjects.js";
import { loadRulesAndProcess } from "../../src/sendMailsForRules.js";
import mailstore from "jc-backend/lib/mailsender/mailstore.js";
import MailRule from "jc-shared/mail/mailRule.js";

const sinon = sin.createSandbox();

describe("Rules Mailsender", () => {
const april17 = DatumUhrzeit.forISOString("2019-04-17T18:00:00.000Z");

// eslint-disable-next-line @typescript-eslint/no-explicit-any
let mailcheck: any;
let mailcheck: sin.SinonStub;

const rule1 = new MailRule({
name: "Regel 1",
Expand Down
9 changes: 4 additions & 5 deletions application/batchjobs/test/mailsender/sendKasseFehlt.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,16 @@ import DatumUhrzeit from "jc-shared/commons/DatumUhrzeit.js";
import mailtransport from "jc-backend/lib/mailsender/mailtransport.js";
import vermietungenstore from "jc-backend/lib/vermietungen/vermietungenstore.js";
import konzertestore from "jc-backend/lib/konzerte/konzertestore.js";
import userstore from "jc-backend/lib/users/userstore";
import { checkKasse } from "../../src/sendMailsKasseFehlt";
import { testKonzerte, testUsers, testVermietungen } from "./testObjects";
import userstore from "jc-backend/lib/users/userstore.js";
import { checkKasse } from "../../src/sendMailsKasseFehlt.js";
import { testKonzerte, testUsers, testVermietungen } from "./testObjects.js";

const sinon = sin.createSandbox();

describe("Check Kasse Mailsender", () => {
const april14 = DatumUhrzeit.forISOString("2019-04-14T18:00:00.000Z");

// eslint-disable-next-line @typescript-eslint/no-explicit-any
let mailcheck: any;
let mailcheck: sin.SinonStub;

beforeEach(() => {
sinon.stub(vermietungenstore, "byDateRangeInAscendingOrder").returns(testVermietungen);
Expand Down
64 changes: 64 additions & 0 deletions application/batchjobs/test/mailsender/sendMailToAdmin.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import * as sin from "sinon";
import "../initWinstonForTest";
import "jc-backend/configure.js";

import mailtransport from "jc-backend/lib/mailsender/mailtransport.js";
import { informAdmin } from "../../src/sendMailToAdmin.js";
import userstore from "jc-backend/lib/users/userstore.js";
import User from "jc-shared/user/user.js";
import { sentMessageInfo } from "./testObjects.js";

const sinon = sin.createSandbox();

describe("Admin Report Mail", () => {
let mailcheck: sin.SinonStub;

beforeEach(() => {
sinon.stub(userstore, "forId").returns(new User({ id: "leider", email: "admin@mail.check", name: "Admin" }));
mailcheck = sinon.stub(mailtransport, "sendMail").resolves(undefined);
});

afterEach(() => {
sinon.restore();
});

it("no jobResult information, not mail", async () => {
await informAdmin([{ type: "Bar", jobResult: {} }]);
sinon.assert.notCalled(mailcheck);
});

it("successful will send info mail", async () => {
await informAdmin([{ type: "Bar", jobResult: { result: sentMessageInfo } }]);
sinon.assert.calledOnce(mailcheck);
const message = mailcheck.args[0][0];
expect(message.subject).to.equal("[INFO B-O Jazzclub] Mails sent");
expect(message.to).to.eql([{ address: "admin@mail.check", name: "Admin" }]);
expect(message.body).to.include("**Bar** 1 Mail(s)");
expect(message.body).to.include(`[
{
"accepted": [
"success@mail"
],
"rejected": [],
"response": "some response information"
}
]`);
});

it("error will send error mail", async () => {
await informAdmin([
{
type: "Bar",
jobResult: { error: new Error("alles kaputt") },
},
]);
sinon.assert.calledOnce(mailcheck);
const message = mailcheck.args[0][0];
expect(message.subject).to.equal("[ERROR B-O Jazzclub] Mails sent");
expect(message.to).to.eql([{ address: "admin@mail.check", name: "Admin" }]);
expect(message.body).to.include("**Bar** 0 Mail(s)");
expect(message.body).to.include(`### Es gibt Fehler!
Error: alles kaputt`);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import * as sin from "sinon";
import "../initWinstonForTest";
import "jc-backend/configure.js";

import mailtransport from "jc-backend/lib/mailsender/mailtransport.js";
import { informAdmin } from "../../src/sendMailToAdmin.js";
import userstore from "jc-backend/lib/users/userstore.js";
import User from "jc-shared/user/user.js";
import { sentMessageInfo } from "./testObjects.js";

const sinon = sin.createSandbox();

describe("Admin Report Mail", () => {
let mailcheck: sin.SinonStub;

beforeEach(() => {
sinon.stub(userstore, "forId").returns(new User({ id: "leider", email: "admin@mail.check", name: "Admin" }));
mailcheck = sinon.stub(mailtransport, "sendMail").resolves(undefined);
});

afterEach(() => {
sinon.restore();
});

it("no jobResult information, not mail", async () => {
await informAdmin([
{ type: "Bar", jobResult: {} },
{ type: "Fluegel", jobResult: {} },
]);
sinon.assert.notCalled(mailcheck);
});

it("result information, no mail", async () => {
await informAdmin([]);
sinon.assert.notCalled(mailcheck);
});

it("successful will send info mail", async () => {
await informAdmin([
{ type: "Bar", jobResult: { result: sentMessageInfo } },
{ type: "Fluegel", jobResult: { result: sentMessageInfo } },
]);
sinon.assert.calledOnce(mailcheck);
const message = mailcheck.args[0][0];
expect(message.subject).to.equal("[INFO B-O Jazzclub] Mails sent");
expect(message.to).to.eql([{ address: "admin@mail.check", name: "Admin" }]);
expect(message.body).to.include("**Bar** 1 Mail(s)");
expect(message.body).to.include("**Fluegel** 1 Mail(s)");
expect(message.body).to.include(`[
{
"accepted": [
"success@mail"
],
"rejected": [],
"response": "some response information"
}
]`);
});

it("error will send error mail if one of the results has error", async () => {
await informAdmin([
{ type: "Bar", jobResult: { error: new Error("alles kaputt") } },
{ type: "Fluegel", jobResult: { result: sentMessageInfo } },
]);
sinon.assert.calledOnce(mailcheck);
const message = mailcheck.args[0][0];
expect(message.subject).to.equal("[ERROR B-O Jazzclub] Mails sent");
expect(message.to).to.eql([{ address: "admin@mail.check", name: "Admin" }]);
expect(message.body).to.include("**Bar** 0 Mail(s)");
expect(message.body).to.include(`### Es gibt Fehler!
Error: alles kaputt`);
expect(message.body).to.include("**Fluegel** 1 Mail(s)");
expect(message.body).to.include(`[
{
"accepted": [
"success@mail"
],
"rejected": [],
"response": "some response information"
}
]`);
});
});
7 changes: 3 additions & 4 deletions application/batchjobs/test/mailsender/sendMailsBar.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,15 @@ import mailtransport from "jc-backend/lib/mailsender/mailtransport.js";
import vermietungenstore from "jc-backend/lib/vermietungen/vermietungenstore.js";
import konzertestore from "jc-backend/lib/konzerte/konzertestore.js";
import { checkBar } from "../../src/sendMailsNightlyBar.js";
import userstore from "jc-backend/lib/users/userstore";
import { testKonzerte, testUsers, testVermietungen } from "./testObjects";
import userstore from "jc-backend/lib/users/userstore.js";
import { testKonzerte, testUsers, testVermietungen } from "./testObjects.js";

const sinon = sin.createSandbox();

describe("Bar Mailsender", () => {
const april14 = DatumUhrzeit.forISOString("2019-04-14T18:00:00.000Z");

// eslint-disable-next-line @typescript-eslint/no-explicit-any
let mailcheck: any;
let mailcheck: sin.SinonStub;

beforeEach(() => {
sinon.stub(vermietungenstore, "byDateRangeInAscendingOrder").returns(testVermietungen);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ import Kalender from "jc-shared/programmheft/kalender.js";
import { Event } from "jc-shared/programmheft/Event.js";
import mailtransport from "jc-backend/lib/mailsender/mailtransport.js";
import { EmailEvent, remindForProgrammheft } from "../../src/sendMailsForProgrammheft.js";
import User from "jc-shared/user/user";
import User from "jc-shared/user/user.js";

const sinon = sin.createSandbox();

describe("Programmheft Mailsender", () => {
const april12 = DatumUhrzeit.forGermanString("12.04.2019");
const april13 = DatumUhrzeit.forGermanString("13.04.2019");
const april15Text = DatumUhrzeit.forGermanString("15.04.2019").toISOString;
const june15Text = DatumUhrzeit.forGermanString("15.06.2019").toISOString;
const april15Text = DatumUhrzeit.forGermanString("15.04.2019")!.toISOString;
const june15Text = DatumUhrzeit.forGermanString("15.06.2019")!.toISOString;

const allUsers = [
new User({ id: "xyz", name: "X Y Z", email: "x@y.z" }),
Expand All @@ -35,8 +35,7 @@ describe("Programmheft Mailsender", () => {
events: [new Event({ start: june15Text, was: "Putzen", users: ["xyz"], farbe: "#9ACD32", emailOffset: 3 })],
});

// eslint-disable-next-line @typescript-eslint/no-explicit-any
let mailcheck: any;
let mailcheck: sin.SinonStub;

beforeEach(() => {
sinon.stub(kalenderstore, "getCurrentKalender").returns(currentKalender);
Expand Down
Loading