diff --git a/package.json b/package.json index 34a72c3d..81418e5c 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "license": "AFL-3.0", "private": true, "scripts": { - "build": "tsc --project test/tsconfig.json && tsc > /dev/null 2>&1", + "build": "tsc --project test/tsconfig.json && tsc > /dev/null 2>&1 && corepack yarn copy-assets", + "copy-assets": "cp src/protections/DraupnirNews/news.json lib/protections/DraupnirNews/news.json", "postbuild": "corepack yarn describe-version", "describe-version": "(git describe > version.txt.tmp && mv version.txt.tmp version.txt) || true && rm -f version.txt.tmp", "remove-tests-from-lib": "rm -rf lib/test/ && cp -r lib/src/* lib/ && rm -rf lib/src/", @@ -63,7 +64,7 @@ "jsdom": "^24.0.0", "matrix-appservice-bridge": "^10.3.1", "matrix-bot-sdk": "npm:@vector-im/matrix-bot-sdk@^0.7.1-element.6", - "matrix-protection-suite": "npm:@gnuxie/matrix-protection-suite@4.0.0", + "matrix-protection-suite": "npm:@gnuxie/matrix-protection-suite@4.1.0", "matrix-protection-suite-for-matrix-bot-sdk": "npm:@gnuxie/matrix-protection-suite-for-matrix-bot-sdk@3.12.0", "pg": "^8.8.0", "yaml": "^2.3.2" diff --git a/src/protections/DefaultEnabledProtectionsMigration.ts b/src/protections/DefaultEnabledProtectionsMigration.ts index 732ede49..54df014f 100644 --- a/src/protections/DefaultEnabledProtectionsMigration.ts +++ b/src/protections/DefaultEnabledProtectionsMigration.ts @@ -187,4 +187,25 @@ export const DefaultEnabledProtectionsMigration = [DRAUPNIR_SCHEMA_VERSION_KEY]: toVersion, }); }, + async function enableDraupnirNews(input, toVersion) { + if (!Value.Check(MjolnirEnabledProtectionsEvent, input)) { + return ActionError.Result( + `The data for ${MjolnirEnabledProtectionsEventType} is corrupted.` + ); + } + const enabledProtections = new Set(input.enabled); + const protection = findProtection("DraupnirNews"); + if (protection === undefined) { + const message = `Cannot find the DraupnirNews protection`; + return ActionException.Result(message, { + exception: new TypeError(message), + exceptionKind: ActionExceptionKind.Unknown, + }); + } + enabledProtections.add(protection.name); + return Ok({ + enabled: [...enabledProtections], + [DRAUPNIR_SCHEMA_VERSION_KEY]: toVersion, + }); + }, ]); diff --git a/src/protections/DraupnirNews/DraupnirNews.tsx b/src/protections/DraupnirNews/DraupnirNews.tsx index 1071dabe..ee80cb63 100644 --- a/src/protections/DraupnirNews/DraupnirNews.tsx +++ b/src/protections/DraupnirNews/DraupnirNews.tsx @@ -98,6 +98,9 @@ export class DraupnirNewsLifecycle { allNews, this.seenNewsIDs ); + if (unseenNews.length === 0) { + return; + } const notifiedNews = DraupnirNewsHelper.removeUnseenNews( allNews, this.seenNewsIDs @@ -128,6 +131,7 @@ const FSNews = (() => { })(); async function fetchNews(newsURL: string): Promise> { + log.debug("Fetching remote news", newsURL); return await fetch(newsURL, { method: "GET", headers: { diff --git a/test/unit/protections/DraupnirNewsTest.ts b/test/unit/protections/DraupnirNewsTest.ts index f15db5d8..f3b06e01 100644 --- a/test/unit/protections/DraupnirNewsTest.ts +++ b/test/unit/protections/DraupnirNewsTest.ts @@ -5,6 +5,7 @@ import { Ok, ResultError } from "@gnuxie/typescript-result"; import { DraupnirNewsBlob, + DraupnirNewsItem, DraupnirNewsLifecycle, } from "../../../src/protections/DraupnirNews/DraupnirNews"; import expect from "expect"; @@ -98,4 +99,46 @@ describe("DraupnirNewsTest", function () { await newsLifecycle.checkForNews(); expect(notifiedNews.length).toBe(1); }); + it("Test news is only stored when there is unseen news", async function () { + const fileSystemNews = { + news: [], + } satisfies DraupnirNewsBlob; + const seenNews = new Set(); + const storeOperations: DraupnirNewsItem[][] = []; + const notifiedNews: string[] = []; + const newsLifecycle = new DraupnirNewsLifecycle( + seenNews, + fileSystemNews, + async (allNews) => { + allNews.forEach((item) => seenNews.add(item.news_id)); + storeOperations.push(allNews); + return Ok(undefined); + }, + async () => + Ok({ + news: [ + { + news_id: "1", + matrix_event_content: { + body: "Announcing release v3.0.0!! wohoo", + msgtype: "m.text", + }, + }, + ], + }), + async (item) => { + notifiedNews.push(item.news_id); + return Ok(undefined); + } + ); + expect(seenNews.size).toBe(0); + expect(notifiedNews.length).toBe(0); + await newsLifecycle.checkForNews(); + expect(seenNews.size).toBe(1); + expect(notifiedNews.length).toBe(1); + expect(storeOperations.length).toBe(1); + await newsLifecycle.checkForNews(); + expect(notifiedNews.length).toBe(1); + expect(storeOperations.length).toBe(1); + }); }); diff --git a/yarn.lock b/yarn.lock index 03def2d5..2b1c2393 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2606,10 +2606,10 @@ matrix-appservice@^2.0.0: "@gnuxie/typescript-result" "^1.0.0" await-lock "^2.2.2" -"matrix-protection-suite@npm:@gnuxie/matrix-protection-suite@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@gnuxie/matrix-protection-suite/-/matrix-protection-suite-4.0.0.tgz#86d9522397f79672dd65077c1c4d344bcc63094e" - integrity sha512-NmkqQMgPr3mDyg8KYfSx9Prb/T1RgGG/O2ASXmJzGfEBTfWf9NeXiDeG4VqgIqJkuoxvp8vbk1/nRLcYnMDDuQ== +"matrix-protection-suite@npm:@gnuxie/matrix-protection-suite@4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@gnuxie/matrix-protection-suite/-/matrix-protection-suite-4.1.0.tgz#1df1a27c325f4945ccd7833129f87d9893b472b8" + integrity sha512-mWZT67adNefRlML8FjLOzAXRcdfoTyFAsfS/e9cmnGk0UQ+yj8mSiX9N2/Clv6N2jpT39LUzhPv9o2PLRp0ELg== dependencies: "@gnuxie/typescript-result" "^1.0.0" await-lock "^2.2.2"