Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ const da = {
'Analysis date · {{date}}': 'Analysedato · {{date}}',
'Analysis date': 'Analysedato',
'Awaiting analysis': 'Afventer analyse',
'Analysis pending': 'Analyse afventer',
'This page refreshes automatically while analysis is pending.': 'Denne side opdateres automatisk, mens analysen afventes.',
'See on the App Store ↗': 'Se i App Store ↗',
'Report metadata': 'Rapportmetadata',
'Analysed version': 'Analyseret version',
Expand Down
1 change: 1 addition & 0 deletions public/css/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ progress.bar-track::-moz-progress-bar { background: var(--brand); }
.notice p:last-child { margin-bottom: 0; }
.notice--quiet { background: var(--warm); color: #544646; }
.notice--warning { background: #f4ece1; border-left-color: #95652c; color: #4f3c27; }
.pending-analysis__progress { accent-color: var(--brand); display: block; height: .65rem; margin: 1rem 0; width: 100%; }
.error-list { margin: 0; padding-left: 1.2rem; }

.directory-controls, .tracker-controls { display: grid; gap: .5rem .75rem; grid-template-columns: auto minmax(160px, 1fr) auto; margin: 1.5rem 0 1rem; }
Expand Down
7 changes: 7 additions & 0 deletions public/js/analysis-pending.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
(function () {
'use strict';

window.setTimeout(function () {
window.location.reload();
}, 30000);
}());
39 changes: 35 additions & 4 deletions test/websiteViews.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
'use strict';

const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const test = require('node:test');
const vm = require('node:vm');
const pug = require('pug');
const { createTranslator, formatDate, formatDateTime, languageUrl, localUrl } = require('../lib/i18n');

Expand Down Expand Up @@ -113,6 +115,7 @@ test('production templates preserve the principal page states and data', () => {
assert.match(success, /Camera/);
assert.match(success, /href="\/tracker\/acme-analytics"/);
assert.match(success, /href="\/company\/acme-corp"/);
assert.doesNotMatch(render('form.pug', { ...reportBase, analyserOnline: true }), /analysis-pending\.js/);

const noTrackers = render('form.pug', {
...reportBase,
Expand Down Expand Up @@ -142,19 +145,47 @@ test('production templates preserve the principal page states and data', () => {
assert.match(failed, /Analysis failed/);
assert.doesNotMatch(failed, /Tracking software/);
assert.doesNotMatch(failed, /Acme Analytics/);
assert.doesNotMatch(render('form.pug', { ...reportBase, app: { ...reportBase.app, analysis: { success: false } }, analyserOnline: true }), /analysis-pending\.js/);

const pending = render('form.pug', {
const pendingData = {
app: {
appid: 'com.example.pending', details: { title: 'Pending App', version: '2.0.0' },
reportMetadata: { title: 'Pending App', queueVersion: '2.0.0', currentVersion: '2.0.0', currentVersionFromStorefront: false },
queueCount: 0
},
analyserOnline: false
});
}
};
const pending = render('form.pug', { ...pendingData, analyserOnline: false });
assert.match(pending, /Awaiting analysis/);
assert.match(pending, /next in the analysis queue/);
assert.match(pending, /currently offline/);
assert.match(pending, /Queue-time version/);
assert.doesNotMatch(pending, /analysis-pending\.js|pending-analysis__progress/);

const pendingOnline = render('form.pug', { ...pendingData, analyserOnline: true });
assert.match(pendingOnline, /<progress[^>]*pending-analysis__progress[^>]*>/);
assert.match(pendingOnline, /refreshes automatically/);
assert.match(pendingOnline, /src="\/js\/analysis-pending\.js"/);
assert.doesNotMatch(pendingOnline, /currently offline/);

const pendingDanish = render('form.pug', { ...pendingData, analyserOnline: true, locale: 'da', t: createTranslator('da') });
assert.match(pendingDanish, /Denne side opdateres automatisk/);
});

test('pending analysis script schedules a fresh report request', () => {
const script = fs.readFileSync(path.join(__dirname, '..', 'public/js/analysis-pending.js'), 'utf8');
let refresh;
let interval;
let reloads = 0;
vm.runInNewContext(script, {
window: {
setTimeout(callback, milliseconds) { refresh = callback; interval = milliseconds; },
location: { reload() { reloads += 1; } }
}
});
assert.equal(interval, 30000);
assert.equal(reloads, 0);
refresh();
assert.equal(reloads, 1);
});

test('search, directory, lookup, statistics, about, request and error states render safely', () => {
Expand Down
7 changes: 7 additions & 0 deletions views/form.pug
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,9 @@ block app
p= translate(report.queueCount === 1 ? 'This app is queued for analysis. {{count}} other app will be analysed first.' : 'This app is queued for analysis. {{count}} other apps will be analysed first.', { count: report.queueCount || 0 })
if typeof analyserOnline !== 'undefined' && analyserOnline === false
p= translate('Analyser service is currently offline. Analysis will resume when the service is available.')
else if typeof analyserOnline !== 'undefined' && analyserOnline === true
progress.pending-analysis__progress(aria-label=translate('Analysis pending'))
p= translate('This page refreshes automatically while analysis is pending.')
else
.report-summary(aria-label=translate('Report summary'))
.summary-item
Expand Down Expand Up @@ -372,3 +375,7 @@ block app
| .

p.stale-note= translate('Store details are retained from the last recorded metadata check and may be stale. They do not verify the current app version or current behaviour.')

block scripts
if typeof app !== 'undefined' && app && !app.analysis && typeof analyserOnline !== 'undefined' && analyserOnline === true
script(src=assets + '/js/analysis-pending.js' defer)
Loading