// A user who cannot update needs to be told what to DO. // // Every failure that was not a Chromium net:: error used to collapse into "Update check failed. // Please try again later." A real 1.5.9 user sat on that message with a perfectly healthy release // feed: the release, its ymls, checksums, signature and notarization all verified good. The cause // was local and permanent, and the app told them to wait. // // Run: cd electron && node --test updateErrorMessage.test.js 'use strict'; const test = require('node:test'); const assert = require('node:assert/strict'); const { friendlyUpdateError } = require('./updateErrorMessage'); const GENERIC = 'Update check failed. Please try again later.'; test('running from the disk image tells the user to move the app', () => { const msg = friendlyUpdateError(new Error('Cannot update while running on a read-only volume'), false); assert.match(msg, /Applications folder/); assert.notEqual(msg, GENERIC); }); test('a Gatekeeper-translocated copy gets the same advice', () => { const msg = friendlyUpdateError(new Error('app is translocated'), false); assert.match(msg, /Applications folder/); }); test('a quarantined Windows updater says so instead of "try again"', () => { const msg = friendlyUpdateError(new Error('Can not find Squirrel'), false); assert.match(msg, /antivirus/); assert.notEqual(msg, GENERIC); }); test('an HTTP refusal reads as reachability, not as an unexplained failure', () => { for (const raw of ['HTTP error: Forbidden', 'ECONNRESET', 'unable to verify the first certificate']) { const msg = friendlyUpdateError(new Error(raw), false); assert.match(msg, /VPN or network/, `"${raw}" should read as reachability`); } }); test('a full disk names the disk', () => { assert.match(friendlyUpdateError(new Error('ENOSPC: no space left on device'), false), /disk space/); }); test('network errors keep their existing message', () => { const msg = friendlyUpdateError(new Error('net::ERR_INTERNET_DISCONNECTED'), false); assert.match(msg, /Check your connection/); }); test('the experimental-channel 404 still wins when prerelease is on', () => { const msg = friendlyUpdateError(new Error('404 Not Found: latest-mac.yml'), true); assert.match(msg, /No experimental builds/); }); test('the same 404 is NOT the experimental message when prerelease is off', () => { const msg = friendlyUpdateError(new Error('404 Not Found: latest-mac.yml'), false); assert.doesNotMatch(msg, /No experimental builds/); }); test('a genuinely unknown failure still falls through to the generic message', () => { // The discriminating half. If everything matched something, the buckets would be meaningless. assert.equal(friendlyUpdateError(new Error('something nobody predicted'), false), GENERIC); }); test('a null error does not throw', () => { assert.equal(typeof friendlyUpdateError(null, false), 'string'); assert.equal(typeof friendlyUpdateError(undefined, true), 'string'); });