mirror of https://github.com/rancher/dashboard.git
217 lines
9.1 KiB
TypeScript
217 lines
9.1 KiB
TypeScript
import { processReleaseVersion } from '../new-release';
|
|
import { NotificationLevel } from '@shell/types/notifications';
|
|
import { READ_NEW_RELEASE } from '@shell/store/prefs';
|
|
import { Context, VersionInfo } from '../types';
|
|
import * as util from '../util'; // Import util to mock removeMatchingNotifications
|
|
import semver from 'semver';
|
|
|
|
describe('processReleaseVersion', () => {
|
|
let mockContext: Context;
|
|
let mockDispatch: jest.Mock;
|
|
let mockGetters: any;
|
|
let mockLogger: any;
|
|
let mockRemoveMatchingNotifications: jest.SpyInstance;
|
|
|
|
beforeEach(() => {
|
|
mockDispatch = jest.fn();
|
|
mockGetters = {
|
|
'prefs/get': jest.fn(),
|
|
'i18n/t': jest.fn((key: string, params?: any) => {
|
|
// Simple mock for i18n/t to return predictable strings
|
|
const { version, version1, version2 } = params || {};
|
|
|
|
if (key === 'dynamicContent.newRelease.title') return `A new Rancher release is available`;
|
|
if (key === 'dynamicContent.newRelease.message') return `Rancher ${ version } has been released`;
|
|
if (key === 'dynamicContent.newRelease.moreInfo') return `More Info`;
|
|
if (key === 'dynamicContent.multipleNewReleases.title') return 'New Rancher releases are available';
|
|
if (key === 'dynamicContent.multipleNewReleases.message') return `Message for ${ version1 } and ${ version2 }`;
|
|
if (key === 'dynamicContent.multipleNewReleases.moreInfo') return `More Info for ${ version }`;
|
|
|
|
return key;
|
|
}),
|
|
};
|
|
mockLogger = {
|
|
info: jest.fn(),
|
|
debug: jest.fn(),
|
|
error: jest.fn(),
|
|
};
|
|
|
|
mockContext = {
|
|
dispatch: mockDispatch,
|
|
getters: mockGetters,
|
|
axios: {},
|
|
logger: mockLogger,
|
|
isAdmin: true,
|
|
config: {
|
|
enabled: true,
|
|
debug: false,
|
|
log: false,
|
|
endpoint: '',
|
|
prime: false,
|
|
distribution: 'community',
|
|
},
|
|
settings: {
|
|
releaseNotesUrl: 'https://example.com/releases/v$version',
|
|
suseExtensions: [],
|
|
},
|
|
};
|
|
|
|
// Mock the utility function. Default: notification does not exist, so add it.
|
|
mockRemoveMatchingNotifications = jest.spyOn(util, 'removeMatchingNotifications')
|
|
.mockResolvedValue(false);
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.restoreAllMocks();
|
|
});
|
|
|
|
it('should return early if releaseInfo is null/undefined or empty', async() => {
|
|
const versionInfo: VersionInfo = { version: semver.coerce('2.12.0')!, isPrime: false };
|
|
|
|
await processReleaseVersion(mockContext, null as any, versionInfo);
|
|
expect(mockDispatch).not.toHaveBeenCalled();
|
|
expect(mockLogger.info).not.toHaveBeenCalled();
|
|
|
|
await processReleaseVersion(mockContext, [], versionInfo);
|
|
expect(mockDispatch).not.toHaveBeenCalled();
|
|
expect(mockLogger.info).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should return early if versionInfo is null/undefined or version is missing', async() => {
|
|
const releaseInfo = [{ name: '2.12.1' }];
|
|
|
|
await processReleaseVersion(mockContext, releaseInfo, null as any);
|
|
expect(mockDispatch).not.toHaveBeenCalled();
|
|
expect(mockLogger.info).not.toHaveBeenCalled();
|
|
|
|
await processReleaseVersion(mockContext, releaseInfo, { version: null as any, isPrime: false });
|
|
expect(mockDispatch).not.toHaveBeenCalled();
|
|
expect(mockLogger.info).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should not add notification if no newer release exists', async() => {
|
|
const releaseInfo = [{ name: '2.12.0' }, { name: '2.11.0' }];
|
|
const versionInfo: VersionInfo = { version: semver.coerce('2.12.0')!, isPrime: false };
|
|
|
|
await processReleaseVersion(mockContext, releaseInfo, versionInfo);
|
|
|
|
expect(mockLogger.info).not.toHaveBeenCalledWith(expect.stringContaining('Found a newer release'));
|
|
expect(mockDispatch).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should add a single new release notification for a newer patch version', async() => {
|
|
const releaseInfo = [{ name: '2.12.1' }, { name: '2.12.0' }, { name: '2.11.0' }];
|
|
const versionInfo: VersionInfo = { version: semver.coerce('2.12.0')!, isPrime: false };
|
|
|
|
await processReleaseVersion(mockContext, releaseInfo, versionInfo);
|
|
|
|
expect(mockLogger.info).toHaveBeenCalledWith('Found a newer release: 2.12.1');
|
|
expect(mockLogger.info).not.toHaveBeenCalledWith(expect.stringContaining('Also found a newer patch release')); // Because newer and newerPatch are the same
|
|
expect(mockDispatch).toHaveBeenCalledTimes(1);
|
|
expect(mockDispatch).toHaveBeenCalledWith('notifications/add', {
|
|
id: 'new-release-2.12.1',
|
|
level: NotificationLevel.Announcement,
|
|
title: 'A new Rancher release is available',
|
|
message: 'Rancher 2.12.1 has been released',
|
|
preference: {
|
|
key: READ_NEW_RELEASE,
|
|
value: '2.12.1',
|
|
},
|
|
primaryAction: {
|
|
label: 'More Info',
|
|
target: 'https://example.com/releases/v2.12.1',
|
|
},
|
|
});
|
|
expect(mockRemoveMatchingNotifications).toHaveBeenCalledWith(mockContext, 'new-release-', '2.12.1');
|
|
});
|
|
|
|
it('should add a single new release notification for a newer major/minor version (no patch)', async() => {
|
|
const releaseInfo = [{ name: '2.13.0' }, { name: '2.12.0' }];
|
|
const versionInfo: VersionInfo = { version: semver.coerce('2.12.0')!, isPrime: false };
|
|
|
|
await processReleaseVersion(mockContext, releaseInfo, versionInfo);
|
|
|
|
expect(mockLogger.info).toHaveBeenCalledWith('Found a newer release: 2.13.0');
|
|
expect(mockLogger.info).not.toHaveBeenCalledWith(expect.stringContaining('Also found a newer patch release'));
|
|
expect(mockDispatch).toHaveBeenCalledTimes(1);
|
|
expect(mockDispatch).toHaveBeenCalledWith('notifications/add', {
|
|
id: 'new-release-2.13.0',
|
|
level: NotificationLevel.Announcement,
|
|
title: 'A new Rancher release is available',
|
|
message: 'Rancher 2.13.0 has been released',
|
|
preference: {
|
|
key: READ_NEW_RELEASE,
|
|
value: '2.13.0',
|
|
},
|
|
primaryAction: {
|
|
label: 'More Info',
|
|
target: 'https://example.com/releases/v2.13.0',
|
|
},
|
|
});
|
|
expect(mockRemoveMatchingNotifications).toHaveBeenCalledWith(mockContext, 'new-release-', '2.13.0');
|
|
});
|
|
|
|
it('should add a multiple new releases notification when both newer patch and newer major/minor exist', async() => {
|
|
const releaseInfo = [{ name: '2.13.0' }, { name: '2.12.1' }, { name: '2.12.0' }];
|
|
const versionInfo: VersionInfo = { version: semver.coerce('2.12.0')!, isPrime: false };
|
|
|
|
await processReleaseVersion(mockContext, releaseInfo, versionInfo);
|
|
|
|
expect(mockLogger.info).toHaveBeenCalledWith('Found a newer release: 2.13.0');
|
|
expect(mockLogger.info).toHaveBeenCalledWith('Also found a newer patch release: 2.12.1');
|
|
expect(mockDispatch).toHaveBeenCalledTimes(1);
|
|
expect(mockDispatch).toHaveBeenCalledWith('notifications/add', {
|
|
id: 'new-release-2.12.1-2.13.0',
|
|
level: NotificationLevel.Announcement,
|
|
title: 'New Rancher releases are available',
|
|
message: 'Message for 2.12.1 and 2.13.0',
|
|
preference: {
|
|
key: READ_NEW_RELEASE,
|
|
value: '2.12.1-2.13.0',
|
|
},
|
|
primaryAction: {
|
|
label: 'More Info for 2.12.1',
|
|
target: 'https://example.com/releases/v2.12.1',
|
|
},
|
|
secondaryAction: {
|
|
label: 'More Info for 2.13.0',
|
|
target: 'https://example.com/releases/v2.13.0',
|
|
},
|
|
});
|
|
expect(mockRemoveMatchingNotifications).toHaveBeenCalledWith(mockContext, 'new-release-', '2.12.1-2.13.0');
|
|
});
|
|
|
|
it('should not add notification if it was already read (single release)', async() => {
|
|
mockGetters['prefs/get'].mockReturnValue('2.12.1'); // Simulate already read
|
|
const releaseInfo = [{ name: '2.12.1' }];
|
|
const versionInfo: VersionInfo = { version: semver.coerce('2.12.0')!, isPrime: false };
|
|
|
|
await processReleaseVersion(mockContext, releaseInfo, versionInfo);
|
|
|
|
expect(mockDispatch).not.toHaveBeenCalled();
|
|
expect(mockLogger.debug).not.toHaveBeenCalledWith(expect.stringContaining('Adding new release notification'));
|
|
});
|
|
|
|
it('should not add notification if it was already read (multiple releases)', async() => {
|
|
mockGetters['prefs/get'].mockReturnValue('2.12.1-2.13.0'); // Simulate already read
|
|
const releaseInfo = [{ name: '2.13.0' }, { name: '2.12.1' }];
|
|
const versionInfo: VersionInfo = { version: semver.coerce('2.12.0')!, isPrime: false };
|
|
|
|
await processReleaseVersion(mockContext, releaseInfo, versionInfo);
|
|
|
|
expect(mockDispatch).not.toHaveBeenCalled();
|
|
expect(mockLogger.info).not.toHaveBeenCalledWith(expect.stringContaining('Adding new multiple release notification'));
|
|
});
|
|
|
|
it('should not add notification if removeMatchingNotifications indicates it exists', async() => {
|
|
mockRemoveMatchingNotifications.mockResolvedValue(true); // Simulate notification already exists
|
|
const releaseInfo = [{ name: '2.12.1' }];
|
|
const versionInfo: VersionInfo = { version: semver.coerce('2.12.0')!, isPrime: false };
|
|
|
|
await processReleaseVersion(mockContext, releaseInfo, versionInfo);
|
|
|
|
expect(mockDispatch).not.toHaveBeenCalled();
|
|
expect(mockLogger.debug).not.toHaveBeenCalledWith(expect.stringContaining('Adding new release notification'));
|
|
});
|
|
});
|