@eox/pages-theme-eox 2.0.0-alpha.5 → 2.0.0-alpha.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,153 @@
1
+ import { describe, it, beforeEach } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import {
4
+ normalizeTrackingUrl,
5
+ trackPageView,
6
+ trackEvent,
7
+ trackSiteSearch,
8
+ formatPrice,
9
+ t,
10
+ isActive,
11
+ } from "./helpers.js";
12
+
13
+ describe("normalizeTrackingUrl", () => {
14
+ it("strips trailing slashes from path", () => {
15
+ assert.equal(normalizeTrackingUrl("/explore/"), "/explore");
16
+ assert.equal(normalizeTrackingUrl("/explore"), "/explore");
17
+ assert.equal(normalizeTrackingUrl("/story/"), "/story");
18
+ assert.equal(normalizeTrackingUrl("/news_updates/"), "/news_updates");
19
+ });
20
+
21
+ it("keeps single root slash as /", () => {
22
+ assert.equal(normalizeTrackingUrl("/"), "/");
23
+ assert.equal(normalizeTrackingUrl(""), "");
24
+ });
25
+
26
+ it("removes volatile map coordinate parameters (x, y, z) and keeps template/zoom/datetime", () => {
27
+ assert.equal(
28
+ normalizeTrackingUrl("/explore/?x=15.0000&y=48.0000&z=4.0000"),
29
+ "/explore",
30
+ );
31
+ assert.equal(
32
+ normalizeTrackingUrl(
33
+ "/explore/?x=15.0000&y=48.0000&z=4.0000&template=expert&indicator=N11&datetime=2024-08-16&zoom=5",
34
+ ),
35
+ "/explore?datetime=2024-08-16&indicator=N11&template=expert&zoom=5",
36
+ );
37
+ });
38
+
39
+ it("preserves semantic content query params and sorts them", () => {
40
+ assert.equal(
41
+ normalizeTrackingUrl("/story/?page=2&id=sea-ice-extent"),
42
+ "/story?id=sea-ice-extent&page=2",
43
+ );
44
+ assert.equal(
45
+ normalizeTrackingUrl("/story/?id=sea-ice-extent&page=2"),
46
+ "/story?id=sea-ice-extent&page=2",
47
+ );
48
+ });
49
+
50
+ it("normalizes full URLs", () => {
51
+ assert.equal(
52
+ normalizeTrackingUrl("https://eodash.eox.at/explore/"),
53
+ "https://eodash.eox.at/explore",
54
+ );
55
+ assert.equal(
56
+ normalizeTrackingUrl(
57
+ "https://eodash.eox.at/explore/?x=12&y=34&indicator=TEST",
58
+ ),
59
+ "https://eodash.eox.at/explore?indicator=TEST",
60
+ );
61
+ });
62
+ });
63
+
64
+ describe("trackEvent", () => {
65
+ beforeEach(() => {
66
+ globalThis._paq = [];
67
+ globalThis.window = globalThis;
68
+ });
69
+
70
+ it("pushes array payload to _paq and normalizes path arguments", () => {
71
+ trackEvent(["Interaction", "Scroll Depth", "/explore/", 50]);
72
+ assert.deepEqual(globalThis._paq, [
73
+ ["trackEvent", "Interaction", "Scroll Depth", "/explore", 50],
74
+ ]);
75
+ });
76
+
77
+ it("supports positional arguments", () => {
78
+ trackEvent("CTA", "/click-link/", "Button Text");
79
+ assert.deepEqual(globalThis._paq, [
80
+ ["trackEvent", "CTA", "/click-link", "Button Text"],
81
+ ]);
82
+ });
83
+ });
84
+
85
+ describe("trackPageView", () => {
86
+ beforeEach(() => {
87
+ globalThis._paq = [];
88
+ globalThis.window = globalThis;
89
+ globalThis.document = { title: "Default Title" };
90
+ });
91
+
92
+ it("normalizes URL and sets document title before tracking page view", () => {
93
+ trackPageView({
94
+ path: "/explore/?x=10&indicator=AIR",
95
+ title: "Explore Indicators",
96
+ });
97
+ assert.deepEqual(globalThis._paq, [
98
+ ["setCustomUrl", "/explore?indicator=AIR"],
99
+ ["setDocumentTitle", "Explore Indicators"],
100
+ ["trackPageView"],
101
+ ["enableLinkTracking"],
102
+ ]);
103
+ });
104
+
105
+ it("accepts router route object", () => {
106
+ trackPageView({
107
+ route: {
108
+ path: "/story/",
109
+ data: { title: "Climate Story" },
110
+ },
111
+ });
112
+ assert.deepEqual(globalThis._paq, [
113
+ ["setCustomUrl", "/story"],
114
+ ["setDocumentTitle", "Climate Story"],
115
+ ["trackPageView"],
116
+ ["enableLinkTracking"],
117
+ ]);
118
+ });
119
+ });
120
+
121
+ describe("trackSiteSearch", () => {
122
+ beforeEach(() => {
123
+ globalThis._paq = [];
124
+ globalThis.window = globalThis;
125
+ });
126
+
127
+ it("pushes trackSiteSearch event with keyword, category, and result count", () => {
128
+ trackSiteSearch("methane", "indicators", 5);
129
+ assert.deepEqual(globalThis._paq, [
130
+ ["trackSiteSearch", "methane", "indicators", 5],
131
+ ]);
132
+ });
133
+ });
134
+
135
+ describe("existing helpers", () => {
136
+ it("formats prices correctly", () => {
137
+ assert.equal(formatPrice(12000, "en"), "€ 12,000.-");
138
+ assert.equal(formatPrice(49.99, "de"), "€ 49,99");
139
+ });
140
+
141
+ it("translates i18n keys with fallback", () => {
142
+ assert.equal(t("nav.home", { nav: { home: "Home Page" } }), "Home Page");
143
+ assert.equal(
144
+ t("nav.unknown", { nav: { home: "Home Page" } }),
145
+ "nav.unknown",
146
+ );
147
+ });
148
+
149
+ it("checks isActive links correctly", () => {
150
+ assert.equal(isActive({ link: "/explore/" }, "/explore"), true);
151
+ assert.equal(isActive({ link: "/explore" }, "/explore/"), true);
152
+ });
153
+ });
@@ -0,0 +1,64 @@
1
+ import llmstxt from "vitepress-plugin-llms";
2
+ import { createStoriesPlugin } from "./storiesPlugin.js";
3
+
4
+ const LLMS_DEFAULTS = {};
5
+
6
+ /**
7
+ * Normalizes a URL by stripping trailing slashes.
8
+ * @param {string | undefined | null} url
9
+ * @returns {string | null}
10
+ */
11
+ export const normalizeDomain = (url) => {
12
+ if (!url || typeof url !== "string") return null;
13
+ return url.replace(/\/+$/, "");
14
+ };
15
+
16
+ /**
17
+ * Resolve the llms option into Vite plugins and package-owned flags.
18
+ * @param {boolean | Record<string, any>} [option] The `llms` option
19
+ * @param {Record<string, any>} [brandConfig] Brand configuration object
20
+ * @returns {{ plugins: any[], copyButtons: boolean, stories: any, domain: string | null }}
21
+ */
22
+ export const resolveLlms = (option, brandConfig = {}) => {
23
+ if (option === false) {
24
+ return {
25
+ plugins: [],
26
+ copyButtons: false,
27
+ stories: null,
28
+ domain: null,
29
+ };
30
+ }
31
+
32
+ const {
33
+ copyButtons = false,
34
+ stories = null,
35
+ ...settings
36
+ } = option === true || option === undefined ? {} : option;
37
+
38
+ const rawDomain = settings.domain;
39
+ const domain = normalizeDomain(rawDomain);
40
+
41
+ const upstreamPlugins = llmstxt({
42
+ ...LLMS_DEFAULTS,
43
+ ...settings,
44
+ ...(domain ? { domain } : {}),
45
+ });
46
+
47
+ const plugins = [...upstreamPlugins];
48
+ if (stories !== false) {
49
+ plugins.push(
50
+ createStoriesPlugin({
51
+ storiesOption: stories,
52
+ brandConfig,
53
+ domain,
54
+ }),
55
+ );
56
+ }
57
+
58
+ return {
59
+ plugins,
60
+ copyButtons: Boolean(copyButtons),
61
+ stories,
62
+ domain,
63
+ };
64
+ };