ui: net-sim Home network button; compact HPLMNwAcT monitor row (v2.7.18)
- netstate.home_plmn(): the card's home network — EF.HPLMNwAcT first record (the HPLMN per TS 31.102 4.2.5), falling back to the IMSI with a 2-digit MNC. Exposed as state.network.home in /api/net-state. - The net-sim parameters get a Home network button next to Random roaming operator: it fills MCC/MNC and reports the source (EF.HPLMNwAcT/IMSI). - The monitor's HPLMNwAcT row now shows only the first network (code only) plus a '… +N' counter; the tooltip keeps the full decoded list with the access technologies. - tests: netstate home_plmn cases, netsim button handler, updated netstate expectations; help EN/RU.
This commit is contained in:
@@ -6,7 +6,7 @@ const path = require('node:path');
|
||||
const html = fs.readFileSync(path.join(__dirname, '..', 'index.html'), 'utf8');
|
||||
|
||||
function extractFunc(src, name) {
|
||||
const re = new RegExp('function\\s+' + name + '\\s*\\([^)]*\\)\\s*\\{');
|
||||
const re = new RegExp('(?:async\\s+)?function\\s+' + name + '\\s*\\([^)]*\\)\\s*\\{');
|
||||
const m = re.exec(src);
|
||||
if (!m) throw new Error('function ' + name + ' not found');
|
||||
let i = m.index + m[0].length - 1;
|
||||
@@ -22,7 +22,7 @@ function extractFunc(src, name) {
|
||||
}
|
||||
|
||||
let code = '';
|
||||
for (const f of ['netSimRandomHex', 'netSimDice', 'netSimVal', 'netSimChk', 'netSimParams', 'netSimStepText']) {
|
||||
for (const f of ['netSimRandomHex', 'netSimDice', 'netSimVal', 'netSimChk', 'netSimParams', 'netSimStepText', 'netSimHomeOperator']) {
|
||||
code += extractFunc(html, f) + '\n';
|
||||
}
|
||||
code += 'function t(k){return k;}\n';
|
||||
@@ -84,3 +84,44 @@ test('netSimStepText renders the step log lines', () => {
|
||||
netSimStepText({ action: 'authenticate', parsed: { type: 'synchronisation_failure' }, sw: '9000', response: 'DC10AA' }),
|
||||
/^AUTHENTICATE synchronisation_failure → SW 9000 DC10AA$/);
|
||||
});
|
||||
|
||||
test('netSimHomeOperator fills the home PLMN and reports its source', async () => {
|
||||
_fields = {
|
||||
'netsim-mcc': { value: '' },
|
||||
'netsim-mnc': { value: '' },
|
||||
'netsim-status': { textContent: '', className: '' },
|
||||
};
|
||||
globalThis.pysimFetch = async () => ({
|
||||
available: true,
|
||||
state: { network: { home: { mcc: '250', mnc: '99', source: 'hplmnwact' } } },
|
||||
});
|
||||
await netSimHomeOperator();
|
||||
assert.strictEqual(_fields['netsim-mcc'].value, '250');
|
||||
assert.strictEqual(_fields['netsim-mnc'].value, '99');
|
||||
assert.ok(_fields['netsim-status'].textContent.includes('250/99'));
|
||||
assert.ok(_fields['netsim-status'].textContent.includes('from EF.HPLMNwAcT'));
|
||||
assert.ok(_fields['netsim-status'].className.includes('text-gray-500'));
|
||||
});
|
||||
|
||||
test('netSimHomeOperator reports the IMSI source and warns when unavailable', async () => {
|
||||
_fields = {
|
||||
'netsim-mcc': { value: '' },
|
||||
'netsim-mnc': { value: '' },
|
||||
'netsim-status': { textContent: '', className: '' },
|
||||
};
|
||||
globalThis.pysimFetch = async () => ({
|
||||
available: true,
|
||||
state: { network: { home: { mcc: '228', mnc: '06', source: 'imsi' } } },
|
||||
});
|
||||
await netSimHomeOperator();
|
||||
assert.ok(_fields['netsim-status'].textContent.includes('from IMSI'));
|
||||
// no home PLMN -> the fields stay and the status warns
|
||||
_fields['netsim-mcc'].value = '001';
|
||||
_fields['netsim-mnc'].value = '01';
|
||||
globalThis.pysimFetch = async () => ({ available: true, state: { network: { home: null } } });
|
||||
await netSimHomeOperator();
|
||||
assert.strictEqual(_fields['netsim-mcc'].value, '001');
|
||||
assert.strictEqual(_fields['netsim-mnc'].value, '01');
|
||||
assert.ok(_fields['netsim-status'].textContent.includes('not available'));
|
||||
assert.ok(_fields['netsim-status'].className.includes('text-yellow-600'));
|
||||
});
|
||||
|
||||
@@ -74,7 +74,7 @@ test('netStateSummary renders decoded file contents compactly', () => {
|
||||
const fplmn = netStateSummary('fplmn', { present: true, kind: 'transparent', data: 'AA' });
|
||||
assert.strictEqual(fplmn.text, '262-01, 246-81');
|
||||
const hplmn = netStateSummary('hplmnwact', { present: true, kind: 'transparent', data: 'AA' });
|
||||
assert.strictEqual(hplmn.text, '262-01 (LTE)');
|
||||
assert.strictEqual(hplmn.text, '262-01');
|
||||
const absent = netStateSummary('loci', { present: false });
|
||||
assert.strictEqual(absent.text, '—');
|
||||
assert.strictEqual(absent.title, 'not present');
|
||||
@@ -110,7 +110,8 @@ test('netStateSummary abbreviates a long HPLMNwAcT list', () => {
|
||||
] },
|
||||
});
|
||||
const s = netStateSummary('hplmnwact', { present: true, kind: 'transparent', data: 'AA' });
|
||||
assert.strictEqual(s.text, '250-99 (LTE), 250-32 (LTE), 250-54 (LTE) … +2');
|
||||
// first network only (no access tech in the row), plus the hidden count
|
||||
assert.strictEqual(s.text, '250-99 … +4');
|
||||
});
|
||||
|
||||
test('netStateRender paints the service badge, location and rows', () => {
|
||||
|
||||
Reference in New Issue
Block a user