feat: 添加版本比较和排序功能,优化获取更新快照的逻辑
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
|
||||
const source = fs.readFileSync('sidepanel/update-service.js', 'utf8');
|
||||
|
||||
function createUpdateService(options = {}) {
|
||||
const manifest = options.manifest || {
|
||||
version: '2.0',
|
||||
version_name: 'Pro2.0',
|
||||
};
|
||||
const cache = new Map();
|
||||
const windowObject = {};
|
||||
let fetchCalls = 0;
|
||||
|
||||
const localStorage = {
|
||||
getItem(key) {
|
||||
return cache.has(key) ? cache.get(key) : null;
|
||||
},
|
||||
setItem(key, value) {
|
||||
cache.set(key, String(value));
|
||||
},
|
||||
};
|
||||
|
||||
if (options.cachedSnapshot) {
|
||||
cache.set(
|
||||
'multipage-release-snapshot-v1',
|
||||
JSON.stringify(options.cachedSnapshot)
|
||||
);
|
||||
}
|
||||
|
||||
const fetchImpl = options.fetchImpl || (async () => ({
|
||||
ok: true,
|
||||
async json() {
|
||||
return [];
|
||||
},
|
||||
}));
|
||||
|
||||
const wrappedFetch = async (...args) => {
|
||||
fetchCalls += 1;
|
||||
return fetchImpl(...args);
|
||||
};
|
||||
|
||||
const api = new Function(
|
||||
'window',
|
||||
'localStorage',
|
||||
'fetch',
|
||||
'chrome',
|
||||
'AbortController',
|
||||
'setTimeout',
|
||||
'clearTimeout',
|
||||
`${source}; return window.SidepanelUpdateService;`
|
||||
)(
|
||||
windowObject,
|
||||
localStorage,
|
||||
wrappedFetch,
|
||||
{
|
||||
runtime: {
|
||||
getManifest() {
|
||||
return manifest;
|
||||
},
|
||||
},
|
||||
},
|
||||
AbortController,
|
||||
setTimeout,
|
||||
clearTimeout
|
||||
);
|
||||
|
||||
return {
|
||||
api,
|
||||
getFetchCalls() {
|
||||
return fetchCalls;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
test('getReleaseSnapshot keeps Pro releases ahead of legacy v releases', async () => {
|
||||
const { api } = createUpdateService({
|
||||
manifest: {
|
||||
version: '2.0',
|
||||
version_name: 'Pro2.0',
|
||||
},
|
||||
fetchImpl: async () => ({
|
||||
ok: true,
|
||||
async json() {
|
||||
return [
|
||||
{
|
||||
tag_name: 'v11.0.0',
|
||||
name: 'v11.0.0',
|
||||
html_url: 'https://example.com/v11.0.0',
|
||||
published_at: '2026-04-17T00:00:00.000Z',
|
||||
body: '- legacy release',
|
||||
draft: false,
|
||||
prerelease: false,
|
||||
},
|
||||
{
|
||||
tag_name: 'Pro2.4',
|
||||
name: 'Pro2.4',
|
||||
html_url: 'https://example.com/Pro2.4',
|
||||
published_at: '2026-04-18T00:00:00.000Z',
|
||||
body: '- pro release',
|
||||
draft: false,
|
||||
prerelease: false,
|
||||
},
|
||||
{
|
||||
tag_name: 'Pro2.0',
|
||||
name: 'Pro2.0',
|
||||
html_url: 'https://example.com/Pro2.0',
|
||||
published_at: '2026-04-16T00:00:00.000Z',
|
||||
body: '- current release',
|
||||
draft: false,
|
||||
prerelease: false,
|
||||
},
|
||||
];
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
const snapshot = await api.getReleaseSnapshot({ force: true });
|
||||
|
||||
assert.equal(snapshot.status, 'update-available');
|
||||
assert.equal(snapshot.localVersion, 'Pro2.0');
|
||||
assert.equal(snapshot.latestVersion, 'Pro2.4');
|
||||
assert.deepEqual(
|
||||
snapshot.newerReleases.map((release) => release.displayVersion),
|
||||
['Pro2.4']
|
||||
);
|
||||
});
|
||||
|
||||
test('getReleaseSnapshot reorders cached releases before choosing latest version', async () => {
|
||||
const { api, getFetchCalls } = createUpdateService({
|
||||
manifest: {
|
||||
version: '2.0',
|
||||
version_name: 'Pro2.0',
|
||||
},
|
||||
cachedSnapshot: {
|
||||
fetchedAt: Date.now(),
|
||||
releases: [
|
||||
{
|
||||
version: '11.0.0',
|
||||
displayVersion: 'v11.0.0',
|
||||
family: 'legacy',
|
||||
title: '',
|
||||
url: 'https://example.com/v11.0.0',
|
||||
publishedAt: '2026-04-17T00:00:00.000Z',
|
||||
notes: [],
|
||||
},
|
||||
{
|
||||
version: '2.4',
|
||||
displayVersion: 'Pro2.4',
|
||||
family: 'pro',
|
||||
title: '',
|
||||
url: 'https://example.com/Pro2.4',
|
||||
publishedAt: '2026-04-18T00:00:00.000Z',
|
||||
notes: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
fetchImpl: async () => {
|
||||
throw new Error('should not fetch when cache is fresh');
|
||||
},
|
||||
});
|
||||
|
||||
const snapshot = await api.getReleaseSnapshot();
|
||||
|
||||
assert.equal(getFetchCalls(), 0);
|
||||
assert.equal(snapshot.status, 'update-available');
|
||||
assert.equal(snapshot.latestVersion, 'Pro2.4');
|
||||
assert.deepEqual(
|
||||
snapshot.newerReleases.map((release) => release.displayVersion),
|
||||
['Pro2.4']
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user