fix(usage): introduce consented v4 without changing historical reports

This commit is contained in:
Paul Nothaft
2026-09-06 21:34:04 +02:00
parent 3cc893126d
commit ef8a52f02c
21 changed files with 5046 additions and 197 deletions
@@ -1,8 +1,8 @@
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const catalog = require('../../src/usage/features.v3.json');
const inventory = require('../../../docs/usage-coverage.v3.json');
const catalog = require('../../src/usage/features.v4.json');
const inventory = require('../../../docs/usage-coverage.v4.json');
const protocol = require('../../src/usage/schema.cjs');
const { RULES_V2, capabilityKeys } = require('../../src/usage/capabilityRules');
const { acceptedUpload, capabilityEvidence } = require('../../src/usage/capabilityEvidence');
@@ -52,16 +52,22 @@ test('all current settings tabs have an explicit scope decision', () => {
}
});
test('v1 wire validation is immutable; catalog, UI and translated descriptions agree', () => {
test('v1/v2/v3 wire validation is immutable; v4 catalog, UI and translated descriptions agree', () => {
expect(crypto.createHash('sha256').update(JSON.stringify(protocol.envelopeSchemas['usage.v1'].properties)).digest('hex'))
.toBe('cc8d0a865d21e36d2b24d23ca6aa8dd8d48000cb17aef83996786f70755bc922');
expect(crypto.createHash('sha256').update(JSON.stringify(protocol.envelopeSchemas['usage.v2'].properties)).digest('hex'))
.toBe('159821cf45c1951016d33a4ed9ca55a0a7ee1b60dd715b803fcfed33e5c8a846');
expect(protocol.FEATURE_KEYS).toHaveLength(86);
expect(crypto.createHash('sha256').update(JSON.stringify(protocol.envelopeSchemas['usage.v3'].properties)).digest('hex'))
.toBe('93214702c79f47823f154544ebad6612dd313604f69e60b86de4c0e4c904571a');
expect(protocol.FEATURE_KEYS).toContain('gallery_downloads_restricted');
expect(protocol.FEATURE_KEYS).not.toContain('gallery_downloads');
expect(protocol.ALL_FEATURE_KEYS).toHaveLength(87);
expect(protocol.ALL_FEATURE_KEYS).toContain('gallery_downloads');
expect(protocol.LEGACY_FEATURE_KEYS).toHaveLength(19);
expect(inventory.configuration_only).toHaveLength(23);
const frontend = path.resolve(__dirname, '../../../frontend');
expect(JSON.parse(fs.readFileSync(path.join(frontend, 'src/features/settings/usageFeatures.v3.json')))).toEqual(catalog);
expect(JSON.parse(fs.readFileSync(path.join(frontend, 'src/features/settings/usageFeatures.v4.json')))).toEqual(catalog);
for (const lang of ['en', 'de']) {
const translated = JSON.parse(fs.readFileSync(path.join(frontend, `src/i18n/locales/${lang}.json`))).productUsage.catalog;
for (const [key, value] of Object.entries(catalog.features)) {