improving pipelines
This commit is contained in:
1 parent
b9159cf61f
commit
032d2a100a
4 files changed
+39
-4
No files matched your search
@@ -32,6 +32,9 @@ jobs:
|
|||||||
- name: Install JS dependencies
|
- name: Install JS dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Type check
|
||||||
|
run: npm run typecheck
|
||||||
|
|
||||||
- name: Run build
|
- name: Run build
|
||||||
run: |
|
run: |
|
||||||
bash scripts/prepare_release.sh
|
bash scripts/prepare_release.sh
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ jobs:
|
|||||||
- name: Install JS dependencies
|
- name: Install JS dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Type check
|
||||||
|
run: npm run typecheck
|
||||||
|
|
||||||
- name: Run build
|
- name: Run build
|
||||||
run: |
|
run: |
|
||||||
bash scripts/prepare_release.sh
|
bash scripts/prepare_release.sh
|
||||||
|
|||||||
@@ -42,13 +42,13 @@ globalThis.localStorage = {
|
|||||||
globalThis.window = { chrome: { storage: { local: {
|
globalThis.window = { chrome: { storage: { local: {
|
||||||
get: (keys, callback) => {
|
get: (keys, callback) => {
|
||||||
chromeReads++;
|
chromeReads++;
|
||||||
callback(Object.fromEntries(keys.map(key => [key, chromeStorage.get(key)])));
|
callback(keys === null ? Object.fromEntries(chromeStorage) : Object.fromEntries(keys.map(key => [key, chromeStorage.get(key)])));
|
||||||
},
|
},
|
||||||
set: (values, callback) => {
|
set: (values, callback) => {
|
||||||
Object.entries(values).forEach(([key, value]) => chromeStorage.set(key, value));
|
Object.entries(values).forEach(([key, value]) => chromeStorage.set(key, value));
|
||||||
callback();
|
callback();
|
||||||
},
|
},
|
||||||
remove: (key, callback) => { chromeStorage.delete(key); callback(); },
|
remove: (keys, callback) => { [keys].flat().forEach(key => chromeStorage.delete(key)); callback(); },
|
||||||
} } } };
|
} } } };
|
||||||
globalThis.FileReader = class {
|
globalThis.FileReader = class {
|
||||||
readAsDataURL(blob) {
|
readAsDataURL(blob) {
|
||||||
@@ -59,10 +59,12 @@ globalThis.FileReader = class {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const [{ ConfigurationService, DEFAULT_CONFIG, normalizeConfig, normalizeCategories }, icons, { default: ping }] = await Promise.all([
|
const [{ ConfigurationService, DEFAULT_CONFIG, normalizeConfig, normalizeCategories }, icons, { default: ping }, { normalizeWebsiteUrl }, { pruneCachedIconsFromChromeStorageLocal }] = await Promise.all([
|
||||||
loadModule('components/services/ConfigurationService.ts'),
|
loadModule('components/services/ConfigurationService.ts'),
|
||||||
loadModule('components/utils/iconService.ts'),
|
loadModule('components/utils/iconService.ts'),
|
||||||
loadModule('components/utils/jsping.ts'),
|
loadModule('components/utils/jsping.ts'),
|
||||||
|
loadModule('components/utils/urlUtils.ts'),
|
||||||
|
loadModule('components/utils/StorageLocalManager.ts'),
|
||||||
]);
|
]);
|
||||||
const file = value => new File([JSON.stringify(value)], 'config.json', { type: 'application/json' });
|
const file = value => new File([JSON.stringify(value)], 'config.json', { type: 'application/json' });
|
||||||
const iconUrl = name => `https://www.google.com/s2/favicons?domain=${name}.com&sz=128`;
|
const iconUrl = name => `https://www.google.com/s2/favicons?domain=${name}.com&sz=128`;
|
||||||
@@ -88,6 +90,31 @@ await test('malformed stored data recovers without shared defaults or unsafe pol
|
|||||||
assert.deepEqual(ConfigurationService.loadUserWallpapers(), []);
|
assert.deepEqual(ConfigurationService.loadUserWallpapers(), []);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await test('website URLs, clock fonts, and wallpaper frequency are normalized', async () => {
|
||||||
|
assert.equal(normalizeWebsiteUrl('github.com'), 'https://github.com/');
|
||||||
|
assert.equal(normalizeWebsiteUrl('localhost:8080/app'), 'https://localhost:8080/app');
|
||||||
|
assert.equal(normalizeWebsiteUrl('mailto:me@example.com'), 'mailto:me@example.com');
|
||||||
|
assert.equal(normalizeWebsiteUrl('javascript:alert(1)'), null);
|
||||||
|
assert.equal(normalizeWebsiteUrl('data:text/html,hi'), null);
|
||||||
|
assert.equal(normalizeWebsiteUrl(' '), null);
|
||||||
|
const websites = normalizeCategories([{ id: 'c', name: 'Group', websites: [
|
||||||
|
{ id: 'a', name: 'Bad', url: 'javascript:alert(1)' },
|
||||||
|
{ id: 'b', name: 'Bare', url: 'example.com' },
|
||||||
|
] }])[0].websites;
|
||||||
|
assert.deepEqual(websites.map(website => website.url), ['https://example.com/']);
|
||||||
|
assert.equal(normalizeConfig({ clock: { font: `'Orbitron', sans-serif` } }).clock.font, 'Helvetica');
|
||||||
|
assert.equal(normalizeConfig({ clock: { font: 'monospace' } }).clock.font, 'monospace');
|
||||||
|
assert.equal(normalizeConfig({ wallpaperFrequency: '2d' }).wallpaperFrequency, '48h');
|
||||||
|
assert.equal(normalizeConfig({ wallpaperFrequency: 'weekly' }).wallpaperFrequency, '24h');
|
||||||
|
chromeStorage.clear();
|
||||||
|
chromeStorage.set(`vision-start:icon:${encodeURIComponent(iconUrl('keep'))}`, 'data:image/png;base64,a');
|
||||||
|
chromeStorage.set(`vision-start:icon:${encodeURIComponent(iconUrl('drop'))}`, 'data:image/png;base64,b');
|
||||||
|
chromeStorage.set('My Wallpaper', 'data:image/png;base64,c');
|
||||||
|
assert.equal(await pruneCachedIconsFromChromeStorageLocal([iconUrl('keep')]), 1);
|
||||||
|
assert.deepEqual([...chromeStorage.keys()].sort(), ['My Wallpaper', `vision-start:icon:${encodeURIComponent(iconUrl('keep'))}`].sort());
|
||||||
|
chromeStorage.clear();
|
||||||
|
});
|
||||||
|
|
||||||
await test('imports validate before writing, roll back failures, and preserve omitted settings', async () => {
|
await test('imports validate before writing, roll back failures, and preserve omitted settings', async () => {
|
||||||
await assert.rejects(ConfigurationService.importConfig({ size: 10 * 1024 * 1024 + 1, text: () => assert.fail('Oversized files must not be read into memory') }), /10MB/);
|
await assert.rejects(ConfigurationService.importConfig({ size: 10 * 1024 * 1024 + 1, text: () => assert.fail('Oversized files must not be read into memory') }), /10MB/);
|
||||||
storage.clear();
|
storage.clear();
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
wget https://raw.githubusercontent.com/homarr-labs/dashboard-icons/refs/heads/main/metadata.json -O public/icon-metadata.json
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
wget -q https://raw.githubusercontent.com/homarr-labs/dashboard-icons/refs/heads/main/metadata.json -O public/icon-metadata.json
|
||||||
Reference in new issue
Block a user