Published source
Download source ZIP
CH-J Server Manager
Browse directories and files for a specific application release.
Source is provided under the CH-J Proprietary Software License 1.14. Its availability does not change the license terms or grant additional rights.
1
"use strict";2
const test = require("node:test");3
const assert = require("node:assert/strict");4
const fs = require("node:fs");5
const os = require("node:os");6
const path = require("node:path");7
const { LicenseAcceptance } = require("../src/main/legal/licenseAcceptance");9
function fixture(t) {10
const storageRoot = fs.mkdtempSync(path.join(os.tmpdir(), "chj-license-test-"));11
t.after(() => fs.rmSync(storageRoot, { recursive: true, force: true }));12
const licensePath = path.join(storageRoot, "LICENSE");13
fs.copyFileSync(path.join(__dirname, "..", "LICENSE"), licensePath);14
const docsRoot = path.join(storageRoot, "docs");15
fs.mkdirSync(docsRoot);16
for (const filename of Object.values(require("../src/main/legal/guidanceDocuments").GUIDANCE_FILES)) {17
fs.copyFileSync(path.join(__dirname, "..", "docs", filename), path.join(docsRoot, filename));18
}19
return { storageRoot, licensePath, docsRoot, appVersion: "0.0.1", buildId: "core-test-first-build" };20
}22
test("first launch requires explicit consent to the exact displayed license", t => {23
const options = fixture(t), service = new LicenseAcceptance(options);24
assert.equal(service.isAccepted(), false);25
for (const payload of [undefined, {}, { accepted: false, sha256: service.identity.sha256 }, { accepted: "true", sha256: service.identity.sha256 }, { accepted: true, sha256: "stale" }]) {26
assert.throws(() => service.accept(payload), /Explicit acceptance/);27
assert.equal(service.isAccepted(), false);28
}29
service.accept({ accepted: true, sha256: service.identity.sha256, guidanceShown: true, guidanceSha256: service.identity.guidanceSha256 });30
assert.equal(new LicenseAcceptance(options).isAccepted(), true);31
const record = JSON.parse(fs.readFileSync(service.filePath));32
assert.equal(record.licenseVersion, "1.14");33
assert.equal(record.guidanceDisplayed, true);34
assert.ok(Number.isFinite(Date.parse(record.acceptedAt)));35
});37
test("consent without current guidance is rejected and changed guidance requires a new display", t => {38
const options = fixture(t), service = new LicenseAcceptance(options);39
for (const payload of [40
{ accepted: true, sha256: service.identity.sha256 },41
{ accepted: true, sha256: service.identity.sha256, guidanceShown: false, guidanceSha256: service.identity.guidanceSha256 },42
{ accepted: true, sha256: service.identity.sha256, guidanceShown: true, guidanceSha256: "stale" }43
]) assert.throws(() => service.accept(payload), /Explicit acceptance/);44
service.accept({ accepted: true, sha256: service.identity.sha256, guidanceShown: true, guidanceSha256: service.identity.guidanceSha256 });45
const czech = path.join(options.docsRoot, "provozni-bezpecnost-a-zalohovani.md");46
fs.appendFileSync(czech, "\nUpdated guidance.\n");47
assert.equal(new LicenseAcceptance(options).isAccepted(), false);48
fs.unlinkSync(czech);49
assert.throws(() => new LicenseAcceptance(options), /ENOENT/);50
});52
test("updates and downgrades require consent even with the same app version and license", t => {53
const options = fixture(t), original = new LicenseAcceptance(options);54
original.accept({ accepted: true, sha256: original.identity.sha256, guidanceShown: true, guidanceSha256: original.identity.guidanceSha256 });55
const update = new LicenseAcceptance({ ...options, buildId: "core-test-next-build" });56
assert.equal(update.isAccepted(), false);57
update.accept({ accepted: true, sha256: update.identity.sha256, guidanceShown: true, guidanceSha256: update.identity.guidanceSha256 });58
assert.equal(original.isAccepted(), false);59
assert.equal(new LicenseAcceptance({ ...options, buildId: "core-test-next-build", appVersion: "0.0.2" }).isAccepted(), false);60
});62
test("changed license content, damaged or missing records require new consent", t => {63
const options = fixture(t), original = new LicenseAcceptance(options);64
original.accept({ accepted: true, sha256: original.identity.sha256, guidanceShown: true, guidanceSha256: original.identity.guidanceSha256 });65
fs.writeFileSync(options.licensePath, original.text.replace("License text date:", "License text date: "));66
assert.equal(new LicenseAcceptance(options).isAccepted(), false);67
for (const text of ["invalid json", "null", JSON.stringify({ ...original.identity, schemaVersion: 1, accepted: true, acceptedAt: "invalid" })]) {68
fs.writeFileSync(original.filePath, text);69
assert.equal(original.isAccepted(), false);70
}71
fs.unlinkSync(original.filePath);72
assert.equal(original.isAccepted(), false);73
});75
test("missing/truncated/wrong license and failed record saves cannot grant consent", t => {76
const options = fixture(t), original = new LicenseAcceptance(options);77
fs.mkdirSync(path.dirname(original.filePath), { recursive: true });78
fs.mkdirSync(original.filePath);79
assert.throws(() => original.accept({ accepted: true, sha256: original.identity.sha256, guidanceShown: true, guidanceSha256: original.identity.guidanceSha256 }));80
assert.equal(original.isAccepted(), false);81
for (const text of ["Apache License 2.0", "CH-J Proprietary Software License\n\nVersion 1.14\n", original.text.replace("Version 1.14", "Version 1.13")]) {82
fs.writeFileSync(options.licensePath, text);83
assert.throws(() => new LicenseAcceptance(options), /complete CH-J application license/);84
}85
fs.unlinkSync(options.licensePath);86
assert.throws(() => new LicenseAcceptance(options), /ENOENT/);87
});SHA-256: 81d5e8d780f1d85dd6d07eaac29fafa9988770b9bc727925e7c6c793c801c454
Archive SHA-256: 5ac91caf4fa32a6fdb114f2430deed486fbe7489d5eea343d1f034169fafb5e0