Check for last dismissed upgrade check in UpgradeController using data-w-dismissible-value-param

pull/12387/head
Sage Abdullah 2024-10-17 16:59:23 +01:00 zatwierdzone przez Thibaud Colas
rodzic 098b48e074
commit bf842b32ef
2 zmienionych plików z 206 dodań i 3 usunięć

Wyświetl plik

@ -112,6 +112,181 @@ describe('UpgradeController', () => {
expect(document.getElementById('panel').hidden).toBe(true);
});
it('should not show the message if the version has been dismissed before', async () => {
const data = {
version: '6.2.2',
url: 'https://docs.wagtail.org/latest/url',
minorUrl: 'https://docs.wagtail.org/latest-minor/url',
lts: {
version: '5.2.6',
url: 'https://docs.wagtail.org/lts/url',
minorUrl: 'https://docs.wagtail.org/lts-minor/url',
},
};
fetch.mockResponseSuccessJSON(JSON.stringify(data));
expect(global.fetch).not.toHaveBeenCalled();
const panel = document.getElementById('panel');
const dismissButton = document.createElement('button');
dismissButton.setAttribute('data-w-upgrade-target', 'dismiss');
panel.appendChild(dismissButton);
// Last dismissed version is 6.2.2 (the same as the latest version)
dismissButton.setAttribute('data-w-dismissible-value-param', '6.2.2');
// start application
application = Application.start();
application.register('w-upgrade', UpgradeController);
// trigger next browser render cycle
await Promise.resolve();
expect(global.fetch).toHaveBeenCalledWith(
'https://releases.wagtail.org/mock.txt',
{ referrerPolicy: 'strict-origin-when-cross-origin' },
);
expect(document.getElementById('panel').hidden).toBe(true);
await new Promise(requestAnimationFrame);
// should remove the hidden class on success
expect(document.getElementById('panel').hidden).toBe(true);
});
it('should show the message if the last dismissed version is not the latest', async () => {
const data = {
version: '6.2.3',
url: 'https://docs.wagtail.org/latest/url',
minorUrl: 'https://docs.wagtail.org/latest-minor/url',
lts: {
version: '5.2.9', // latest LTS version
url: 'https://docs.wagtail.org/lts/url',
minorUrl: 'https://docs.wagtail.org/lts-minor/url',
},
};
fetch.mockResponseSuccessJSON(JSON.stringify(data));
expect(global.fetch).not.toHaveBeenCalled();
const panel = document.getElementById('panel');
const dismissButton = document.createElement('button');
dismissButton.setAttribute('data-w-upgrade-target', 'dismiss');
panel.appendChild(dismissButton);
// Simulate the case where we only care about LTS versions
panel.setAttribute('data-w-upgrade-lts-only-value', 'true');
// Last dismissed version is 5.2.6
dismissButton.setAttribute('data-w-dismissible-value-param', '5.2.6');
// Current installed version is 4.1.2
panel.setAttribute('data-w-upgrade-current-version-value', '4.1.2');
// start application
application = Application.start();
application.register('w-upgrade', UpgradeController);
// trigger next browser render cycle
await Promise.resolve();
expect(global.fetch).toHaveBeenCalledWith(
'https://releases.wagtail.org/mock.txt',
{ referrerPolicy: 'strict-origin-when-cross-origin' },
);
expect(document.getElementById('panel').hidden).toBe(true);
await new Promise(requestAnimationFrame);
// should remove the hidden class on success
expect(document.getElementById('panel').hidden).toBe(false);
// should update the latest version number in the text
// and include the (LTS) label since we only care about the LTS versions
expect(document.getElementById('latest-version').textContent).toBe(
`${data.lts.version} (LTS)`,
);
// should add the link using the minorUrl,
// since the actual installed version is way behind, i.e. 4.1.2 vs 5.2.9,
// even though the last dismissed version is 5.2.6
expect(document.getElementById('link').getAttribute('href')).toEqual(
data.lts.minorUrl,
);
// Should update the dismissible value param to the latest LTS version,
// so this version is not shown again if the user dismisses it
expect(
document
.querySelector('[data-w-upgrade-target="dismiss"]')
.getAttribute('data-w-dismissible-value-param'),
).toEqual('5.2.9');
});
it('should use the latest URL if the currently installed version is at the same minor version', async () => {
const data = {
version: '6.2.6',
url: 'https://docs.wagtail.org/latest/url',
minorUrl: 'https://docs.wagtail.org/latest-minor/url',
lts: {
version: '5.2.6',
url: 'https://docs.wagtail.org/lts/url',
minorUrl: 'https://docs.wagtail.org/lts-minor/url',
},
};
fetch.mockResponseSuccessJSON(JSON.stringify(data));
expect(global.fetch).not.toHaveBeenCalled();
const panel = document.getElementById('panel');
const dismissButton = document.createElement('button');
dismissButton.setAttribute('data-w-upgrade-target', 'dismiss');
panel.appendChild(dismissButton);
// Last dismissed version is 6.2.2
dismissButton.setAttribute('data-w-dismissible-value-param', '6.2.2');
// Current installed version is 6.2.3
panel.setAttribute('data-w-upgrade-current-version-value', '6.2.3');
// start application
application = Application.start();
application.register('w-upgrade', UpgradeController);
// trigger next browser render cycle
await Promise.resolve();
expect(global.fetch).toHaveBeenCalledWith(
'https://releases.wagtail.org/mock.txt',
{ referrerPolicy: 'strict-origin-when-cross-origin' },
);
expect(document.getElementById('panel').hidden).toBe(true);
await new Promise(requestAnimationFrame);
// should remove the hidden class on success
expect(document.getElementById('panel').hidden).toBe(false);
// should update the latest version number in the text
expect(document.getElementById('latest-version').textContent).toBe(
data.version,
);
// should add the latest version link using the latest version,
// since the actual installed version is not far behind (6.2.3 vs 6.2.6)
expect(document.getElementById('link').getAttribute('href')).toEqual(
data.url,
);
// Should update the dismissible value param to the latest version,
// so this version is not shown again if the user dismisses it
expect(
document
.querySelector('[data-w-upgrade-target="dismiss"]')
.getAttribute('data-w-dismissible-value-param'),
).toEqual('6.2.6');
});
it('should throw an error if the fetch fails', async () => {
// Spy on console.error to verify that it is called with the expected error message
jest.spyOn(console, 'error').mockImplementation(() => {});

Wyświetl plik

@ -30,7 +30,7 @@ interface LatestVersionData extends VersionData {
* }
*/
export class UpgradeController extends Controller<HTMLElement> {
static targets = ['latestVersion', 'link'];
static targets = ['latestVersion', 'link', 'dismiss'];
static values = {
currentVersion: String,
ltsOnly: { default: false, type: Boolean },
@ -39,9 +39,11 @@ export class UpgradeController extends Controller<HTMLElement> {
declare readonly hasLatestVersionTarget: boolean;
declare readonly hasLinkTarget: boolean;
declare readonly hasDismissTarget: boolean;
declare currentVersionValue: string;
declare latestVersionTarget: HTMLElement;
declare linkTarget: HTMLElement;
declare dismissTarget: HTMLElement;
declare ltsOnlyValue: any;
declare urlValue: string;
@ -49,6 +51,19 @@ export class UpgradeController extends Controller<HTMLElement> {
this.checkVersion();
}
/**
* The version number that the user has acknowledged.
*
* Use the last dismissed version if it exists, or the current version otherwise.
*/
get knownVersion() {
return new VersionNumber(
(this.hasDismissTarget &&
this.dismissTarget.getAttribute('data-w-dismissible-value-param')) ||
this.currentVersionValue,
);
}
checkVersion() {
const releasesUrl = this.urlValue;
const currentVersion = new VersionNumber(this.currentVersionValue);
@ -75,10 +90,15 @@ export class UpgradeController extends Controller<HTMLElement> {
const latestVersion = new VersionNumber(data.version);
const versionDelta = currentVersion.howMuchBehind(latestVersion);
let releaseNotesUrl: string;
if (!versionDelta) {
// Check with the last dismissed version if it exists, so we don't
// show the notification again if the user has already dismissed it.
if (!this.knownVersion.howMuchBehind(latestVersion)) {
return;
}
// But use the actual installed version to check whether we want to
// link to the feature release notes or the patch release notes.
let releaseNotesUrl: string;
if (
versionDelta === VersionDeltaType.MAJOR ||
versionDelta === VersionDeltaType.MINOR
@ -98,6 +118,14 @@ export class UpgradeController extends Controller<HTMLElement> {
if (this.hasLinkTarget) {
this.linkTarget.setAttribute('href', releaseNotesUrl || '');
}
if (this.hasDismissTarget) {
this.dismissTarget.setAttribute(
'data-w-dismissible-value-param',
data.version,
);
}
this.element.hidden = false;
})
.catch((err) => {