mirror of
https://github.com/jason5ng32/MyIP.git
synced 2026-11-04 08:55:47 +00:00
refactor/04 complete. Four families of constants that used to live inline
in store.js are now dedicated modules under frontend/data/ with their
own tests. Consumers still read the same store shape — zero call-site
changes required for the 20+ consumers of userAchievements / ipDBs /
mountingStatus / userPreferences.
New data modules (frontend/data/):
- achievements.js
ACHIEVEMENTS_DEFINITIONS — 21 {name, img} entries
createInitialAchievementsState() — factory, returns fresh keyed map
Bonus fix: IAmHuman.img previously used 'achievements/iamhuman.webp'
(missing leading slash). All 21 entries now uniformly start with
'/achievements/'. No consumer had the legacy path string baked in.
- ip-databases.js
IP_DATABASES — 7 {id, text, url, enabled} entries
createInitialIpDBs()— factory for store.ipDBs
buildDbUrl(db, ip, lang) — pure URL template substitution,
extracted from store.getDbUrl so it can
be tested without instantiating Pinia
- default-preferences.js
DEFAULT_PREFERENCES — Object.freeze'd canonical defaults
createDefaultPreferences() — writable copy factory
- sections.js (new shared source of truth)
SECTION_IDS — ['IPInfo', 'Connectivity', ..., 'AdvancedTools']
DEFAULT_SECTION — 'IPInfo'
createMountingStatus() / createLoadingStatus() — key-set factories
Previously, the same 6 section names were duplicated in three places:
store.mountingStatus keys, store.loadingStatus keys (subset), and a
hardcoded local array inside Patch.vue's checkSectionsAndTrack().
Patch.vue now imports SECTION_IDS from data/.
store.js changes:
- Import factories from data/*, replace 60+ lines of inline literal state
with factory calls
- getDbUrl() delegates URL substitution to buildDbUrl pure function
- loadPreferences() uses createDefaultPreferences()
- currentSection default uses DEFAULT_SECTION
Tests (23 new, brings total 23 → 46, all green):
- tests/achievements.test.js — definitions shape, path format,
factory isolation, runtime shape
- tests/ip-databases.test.js — definitions integrity, factory
isolation, buildDbUrl substitution
/ default lang / missing placeholder
/ null-guard
- tests/default-preferences.test.js — freeze, shape, copy isolation
- tests/sections.test.js — id order, factory isolation
Plan updates:
- refactor/04: status → ✅ done, all checkboxes ticked, audit table
(Phase A "audit results") filled in with line numbers and routing decisions
- refactor/README.md: total status for #04 → ✅
- This also ticks the store / utils sections of refactor/03 indirectly
(the new data/ tests plus existing valid-ip and api-smoke suites).
Verified: npm run check — 46 tests pass, vite build succeeds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
69 lines
1.6 KiB
JavaScript
69 lines
1.6 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import { describe, it } from 'node:test';
|
|
|
|
import {
|
|
SECTION_IDS,
|
|
DEFAULT_SECTION,
|
|
createMountingStatus,
|
|
createLoadingStatus,
|
|
} from '../frontend/data/sections.js';
|
|
|
|
describe('SECTION_IDS', () => {
|
|
it('lists all 6 section DOM ids in render order', () => {
|
|
assert.deepEqual(SECTION_IDS, [
|
|
'IPInfo',
|
|
'Connectivity',
|
|
'WebRTC',
|
|
'DNSLeakTest',
|
|
'SpeedTest',
|
|
'AdvancedTools',
|
|
]);
|
|
});
|
|
|
|
it('DEFAULT_SECTION is the first entry', () => {
|
|
assert.equal(DEFAULT_SECTION, SECTION_IDS[0]);
|
|
});
|
|
});
|
|
|
|
describe('createMountingStatus()', () => {
|
|
it('returns all 6 mount keys set to false', () => {
|
|
const s = createMountingStatus();
|
|
assert.deepEqual(s, {
|
|
ipcheck: false,
|
|
connectivity: false,
|
|
webrtc: false,
|
|
dnsleaktest: false,
|
|
speedtest: false,
|
|
advancedtools: false,
|
|
});
|
|
});
|
|
|
|
it('returns a fresh object each call', () => {
|
|
const a = createMountingStatus();
|
|
const b = createMountingStatus();
|
|
assert.notEqual(a, b);
|
|
a.ipcheck = true;
|
|
assert.equal(b.ipcheck, false);
|
|
});
|
|
});
|
|
|
|
describe('createLoadingStatus()', () => {
|
|
it('returns the 4 loading keys set to false (subset of mounting keys)', () => {
|
|
const s = createLoadingStatus();
|
|
assert.deepEqual(s, {
|
|
ipcheck: false,
|
|
connectivity: false,
|
|
webrtc: false,
|
|
dnsleaktest: false,
|
|
});
|
|
});
|
|
|
|
it('returns a fresh object each call', () => {
|
|
const a = createLoadingStatus();
|
|
const b = createLoadingStatus();
|
|
assert.notEqual(a, b);
|
|
a.webrtc = true;
|
|
assert.equal(b.webrtc, false);
|
|
});
|
|
});
|