Decode catalog numbers strictly and add the changelog fragment

Route tleCatalogNumber() and noradIdFromSatnum() through one decoder that
accepts only plain digits or a valid Alpha-5 field. parseInt and Number()
read '2554A', '255 4', '-1234', '0x1F0', '1.5' and blank as numbers; they
now return null/NaN. Digit satnums of any length still decode, so OMM
satrecs numbered past 99999 keep working.

Add a layer test that several Alpha-5 satellites survive ingestion dedupe,
the changelog fragment for #767, and note in CURRENT-STATE that this is
Alpha-5 TLE compatibility and malformed fields are rejected.
This commit is contained in:
Sameh Khamis committed 2026-10-17 11:40:30 -07:00
1 parent 6ae854c121
commit 7ec84ac316
5 files changed
+147 -34

No files matched your search

+30 -5
View File
@@ -72,14 +72,39 @@ test('Alpha-5 catalog numbers decode, skipping I and O', () => {
}
});
test('every other catalog field reads as it did before', () => {
test('a digit catalog field reads as it did before', () => {
assert.equal(noradIdFromSatnum('25544'), 25544);
assert.equal(noradIdFromSatnum('00404'), 404);
assert.equal(noradIdFromSatnum(''), 0); // as Number('') did
for (const field of ['I0000', 'O0000', 'a0404', 'A00']) {
assert.ok(Number.isNaN(noradIdFromSatnum(field)), field);
assert.equal(tleCatalogNumber(`1 ${field}U`), null, field);
assert.equal(noradIdFromSatnum(' 404'), 404);
assert.equal(tleCatalogNumber('1 25544U'), 25544);
assert.equal(tleCatalogNumber('1 404U'), 404);
// An OMM satrec carries the number unpadded, past five digits.
assert.equal(noradIdFromSatnum('100000'), 100000);
});
test('a malformed catalog field is no number', () => {
for (const field of [
'I0000',
'O0000',
'a0404',
'A00',
'2554A',
'255 4',
'-1234',
'0x1F0',
'1.5',
'1e3',
'',
' ',
]) {
assert.ok(Number.isNaN(noradIdFromSatnum(field)), JSON.stringify(field));
assert.equal(
tleCatalogNumber(`1 ${field.padEnd(5)}U`),
null,
JSON.stringify(field),
);
}
assert.ok(Number.isNaN(noradIdFromSatnum(undefined)));
});
test('a satellite numbered above 99999 keeps its number and is found by it', async () => {