mirror of
https://github.com/praktimarc/kst4contest.git
synced 2026-09-12 04:05:34 +02:00
Added user counter and analytics to the kst4contest page
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
const assert = require("node:assert/strict");
|
||||
const fs = require("node:fs");
|
||||
const path = require("node:path");
|
||||
const test = require("node:test");
|
||||
|
||||
const {
|
||||
formatVisitorCount,
|
||||
loadVisitorCount,
|
||||
validateVisitorCount
|
||||
} = require("../src/assets/js/visitor-count");
|
||||
|
||||
const VALID_DATA = {
|
||||
schemaVersion: 1,
|
||||
visits: 1234,
|
||||
since: "2026-09-11",
|
||||
updatedAt: "2026-09-11T07:00:00Z"
|
||||
};
|
||||
|
||||
function element() {
|
||||
return { hidden: true, textContent: "" };
|
||||
}
|
||||
|
||||
test("formats valid data for the English website", async () => {
|
||||
const target = element();
|
||||
let request;
|
||||
const shown = await loadVisitorCount({
|
||||
element: target,
|
||||
fetchImpl: async (url, options) => {
|
||||
request = { url, options };
|
||||
return { ok: true, json: async () => VALID_DATA };
|
||||
}
|
||||
});
|
||||
|
||||
assert.equal(shown, true);
|
||||
assert.equal(target.hidden, false);
|
||||
assert.equal(target.textContent, "Visits since 11 September 2026: 1,234");
|
||||
assert.equal(request.url, "/visitor-count.json");
|
||||
assert.equal(request.options.credentials, "omit");
|
||||
});
|
||||
|
||||
test("rejects unsupported schemas and invalid visit counts", () => {
|
||||
for (const changes of [
|
||||
{ schemaVersion: 2 },
|
||||
{ visits: -1 },
|
||||
{ visits: 1.5 },
|
||||
{ visits: Number.MAX_SAFE_INTEGER + 1 }
|
||||
]) {
|
||||
assert.equal(validateVisitorCount({ ...VALID_DATA, ...changes }), null);
|
||||
}
|
||||
});
|
||||
|
||||
test("rejects invalid dates and timestamps without timezone shifts", () => {
|
||||
for (const changes of [
|
||||
{ since: "2026-02-30" },
|
||||
{ since: "11-09-2026" },
|
||||
{ updatedAt: "2026-09-11" },
|
||||
{ updatedAt: "2026-02-30T07:00:00Z" },
|
||||
{ updatedAt: "2026-09-11T25:00:00Z" },
|
||||
{ updatedAt: "not-a-timestamp" }
|
||||
]) {
|
||||
assert.equal(formatVisitorCount({ ...VALID_DATA, ...changes }), null);
|
||||
}
|
||||
});
|
||||
|
||||
test("keeps the element hidden for HTTP and fetch failures", async () => {
|
||||
for (const fetchImpl of [
|
||||
async () => ({ ok: false }),
|
||||
async () => { throw new Error("network failure"); }
|
||||
]) {
|
||||
const target = element();
|
||||
assert.equal(await loadVisitorCount({ element: target, fetchImpl }), false);
|
||||
assert.equal(target.hidden, true);
|
||||
assert.equal(target.textContent, "");
|
||||
}
|
||||
});
|
||||
|
||||
test("aborts a slow request and keeps the element hidden", async () => {
|
||||
const target = element();
|
||||
let aborted = false;
|
||||
const fetchImpl = (url, options) => new Promise((resolve, reject) => {
|
||||
options.signal.addEventListener("abort", () => {
|
||||
aborted = true;
|
||||
reject(new Error("aborted"));
|
||||
});
|
||||
});
|
||||
|
||||
assert.equal(await loadVisitorCount({
|
||||
element: target,
|
||||
fetchImpl,
|
||||
timeoutMs: 5
|
||||
}), false);
|
||||
assert.equal(aborted, true);
|
||||
assert.equal(target.hidden, true);
|
||||
});
|
||||
|
||||
test("uses textContent and loads the script only for the home page", () => {
|
||||
const script = fs.readFileSync(path.join(
|
||||
__dirname,
|
||||
"../src/assets/js/visitor-count.js"
|
||||
), "utf8");
|
||||
const home = fs.readFileSync(path.join(__dirname, "../src/index.njk"), "utf8");
|
||||
const layout = fs.readFileSync(path.join(
|
||||
__dirname,
|
||||
"../src/_layouts/base.njk"
|
||||
), "utf8");
|
||||
const sourceRoot = path.join(__dirname, "../src");
|
||||
const otherPages = fs.readdirSync(sourceRoot, { recursive: true })
|
||||
.filter(entry => entry.endsWith(".njk") && entry !== "index.njk");
|
||||
|
||||
assert.doesNotMatch(script, /innerHTML/);
|
||||
assert.match(script, /textContent/);
|
||||
assert.match(home, /^visitorCount: true$/m);
|
||||
assert.match(layout, /\{% if visitorCount %\}/);
|
||||
assert.equal(
|
||||
otherPages.some(entry => fs.readFileSync(path.join(sourceRoot, entry), "utf8")
|
||||
.includes("visitorCount: true")),
|
||||
false
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user