From 84131a20482bceb46ba83f7d2a7875ff6467f4fe Mon Sep 17 00:00:00 2001 From: Ivan Date: Thu, 23 Apr 2026 14:29:17 -0500 Subject: [PATCH] feat(tests): add AboutPage tests with internationalization keys and add new tests for lxmfConversationListPreview functionality --- tests/frontend/AboutPage.test.js | 26 ++++++------ tests/frontend/MapDrawing.test.js | 2 + tests/frontend/MapPage.test.js | 2 + tests/frontend/MapPageClustering.test.js | 2 + tests/frontend/lxmfReactions.test.js | 50 +++++++++++++++++++++++- 5 files changed, 67 insertions(+), 15 deletions(-) diff --git a/tests/frontend/AboutPage.test.js b/tests/frontend/AboutPage.test.js index d22d931..6c702b2 100644 --- a/tests/frontend/AboutPage.test.js +++ b/tests/frontend/AboutPage.test.js @@ -111,18 +111,16 @@ describe("AboutPage.vue", () => { expect(axiosMock.get).toHaveBeenCalledWith("/api/v1/app/info"); expect(axiosMock.get).toHaveBeenCalledWith("/api/v1/config"); - expect(wrapper.text()).toContain("MeshChatX"); - expect(wrapper.text()).toContain("Reticulum Network Stack"); + expect(wrapper.text()).toContain("about.app_name"); + expect(wrapper.text()).toContain("about.tagline_link"); expect(wrapper.text()).toContain("hash1"); expect(wrapper.text()).toContain("hash2"); - // Check for Dependency Chain section - expect(wrapper.text()).toContain("Dependency Chain"); - expect(wrapper.text()).toContain("Lightweight Extensible Message Format"); - expect(wrapper.text()).toContain("Reticulum Network Stack"); + expect(wrapper.text()).toContain("about.dependency_chain"); + expect(wrapper.text()).toContain("about.dep_lxmf_subtitle"); + expect(wrapper.text()).toContain("about.dep_rns_subtitle"); - // Check for dependencies - expect(wrapper.text()).toContain("Backend Stack"); + expect(wrapper.text()).toContain("about.backend_stack"); expect(wrapper.text()).toContain("aiohttp"); expect(wrapper.text()).toContain("3.8.1"); }); @@ -155,7 +153,7 @@ describe("AboutPage.vue", () => { expect(getMemoryUsageSpy).toHaveBeenCalled(); expect(wrapper.vm.electronMemoryUsage).not.toBeNull(); - expect(wrapper.text()).toContain("Environment Information"); + expect(wrapper.text()).toContain("about.environment_information"); }); it("handles shutdown action", async () => { @@ -269,7 +267,7 @@ describe("AboutPage.vue", () => { await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick(); - expect(wrapper.text()).toContain("Free Space"); + expect(wrapper.text()).toContain("about.free_space"); expect(wrapper.text()).toContain("1 GB"); }); @@ -291,7 +289,7 @@ describe("AboutPage.vue", () => { await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick(); - expect(wrapper.text()).toContain("Free Space"); + expect(wrapper.text()).toContain("about.free_space"); expect(wrapper.text()).toContain("0 Bytes"); }); @@ -321,8 +319,8 @@ describe("AboutPage.vue", () => { await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick(); - expect(wrapper.text()).toContain("Reticulum Config"); - expect(wrapper.text()).toContain("Database Path"); - expect(wrapper.text()).toContain("unknown"); + expect(wrapper.text()).toContain("about.reticulum_config"); + expect(wrapper.text()).toContain("about.database_path"); + expect(wrapper.text()).toContain("about.path_unknown"); }); }); diff --git a/tests/frontend/MapDrawing.test.js b/tests/frontend/MapDrawing.test.js index 056f46e..9b8085e 100644 --- a/tests/frontend/MapDrawing.test.js +++ b/tests/frontend/MapDrawing.test.js @@ -36,10 +36,12 @@ vi.mock("ol/Map", () => ({ removeOverlay: vi.fn(), getView: vi.fn().mockReturnValue({ on: vi.fn(), + un: vi.fn(), setCenter: vi.fn(), setZoom: vi.fn(), getCenter: vi.fn().mockReturnValue([0, 0]), getZoom: vi.fn().mockReturnValue(2), + getRotation: vi.fn().mockReturnValue(0), fit: vi.fn(), animate: vi.fn(), }), diff --git a/tests/frontend/MapPage.test.js b/tests/frontend/MapPage.test.js index 5154967..0021ad3 100644 --- a/tests/frontend/MapPage.test.js +++ b/tests/frontend/MapPage.test.js @@ -36,10 +36,12 @@ vi.mock("ol/Map", () => ({ getTargetElement: vi.fn().mockReturnValue({ style: {} }), getView: vi.fn().mockReturnValue({ on: vi.fn(), + un: vi.fn(), setCenter: vi.fn(), setZoom: vi.fn(), getCenter: vi.fn().mockReturnValue([0, 0]), getZoom: vi.fn().mockReturnValue(2), + getRotation: vi.fn().mockReturnValue(0), fit: vi.fn(), animate: vi.fn(), }), diff --git a/tests/frontend/MapPageClustering.test.js b/tests/frontend/MapPageClustering.test.js index 082f367..fd53c1d 100644 --- a/tests/frontend/MapPageClustering.test.js +++ b/tests/frontend/MapPageClustering.test.js @@ -21,12 +21,14 @@ vi.mock("ol/layer/Group", () => ({ const viewMock = { on: vi.fn(), + un: vi.fn(), setCenter: vi.fn(), setZoom: vi.fn(), getCenter: vi.fn().mockReturnValue([0, 0]), getZoom: vi.fn().mockReturnValue(8), getMaxZoom: vi.fn().mockReturnValue(19), getResolution: vi.fn().mockReturnValue(10), + getRotation: vi.fn().mockReturnValue(0), fit: vi.fn(), animate: vi.fn(), }; diff --git a/tests/frontend/lxmfReactions.test.js b/tests/frontend/lxmfReactions.test.js index 59a4f8e..878ee74 100644 --- a/tests/frontend/lxmfReactions.test.js +++ b/tests/frontend/lxmfReactions.test.js @@ -1,5 +1,53 @@ import { describe, expect, it } from "vitest"; -import { mergeLxmfReactionRowsIntoMessages } from "../../meshchatx/src/frontend/js/lxmfReactions"; +import { + lxmfConversationListPreview, + mergeLxmfReactionRowsIntoMessages, +} from "../../meshchatx/src/frontend/js/lxmfReactions"; + +describe("lxmfConversationListPreview", () => { + const me = "m".repeat(32); + const peer = "p".repeat(32); + + it("uses reaction_emoji for outbound reaction from self", () => { + const s = lxmfConversationListPreview( + { + content: " ", + is_incoming: false, + is_reaction: true, + reaction_emoji: "\u{1F44D}", + source_hash: me, + }, + { myLxmfAddressHash: me, peerDisplayName: "Pat" } + ); + expect(s).toBe("You reacted \u{1F44D}"); + }); + + it("uses peer name for incoming reaction", () => { + const s = lxmfConversationListPreview( + { + content: "", + is_incoming: true, + is_reaction: true, + reaction_emoji: "\u2764\uFE0F", + source_hash: peer, + }, + { myLxmfAddressHash: me, peerDisplayName: "Alex" } + ); + expect(s).toBe("Alex reacted \u2764\uFE0F"); + }); + + it("reads emoji from fields.app_extensions when body fields are used", () => { + const s = lxmfConversationListPreview( + { + content: "", + is_incoming: true, + fields: { app_extensions: { reaction_to: "deadbeef", emoji: "\u{1F602}" } }, + }, + { myLxmfAddressHash: me, peerDisplayName: "Sam" } + ); + expect(s).toBe("Sam reacted \u{1F602}"); + }); +}); describe("mergeLxmfReactionRowsIntoMessages", () => { it("merges reaction rows onto parents and drops reaction-only rows", () => {