Skip to content
This repository was archived by the owner on Jul 9, 2024. It is now read-only.

Commit 43ab3b9

Browse files
authored
test: use Node.js test runner (#157)
1 parent 8a85905 commit 43ab3b9

13 files changed

Lines changed: 6189 additions & 9285 deletions

.github/workflows/api-tests.yaml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
node-version: "20.x"
2626
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
2727
- run: npm ci
28-
- run: npx jest agps.spec.ts
28+
- run: npx tsx --test ./api-verification/agps.spec.ts
2929
pgps:
3030
name: P-GPS Service API verification tests
3131
runs-on: ubuntu-22.04
@@ -35,7 +35,7 @@ jobs:
3535
node-version: "20.x"
3636
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
3737
- run: npm ci
38-
- run: npx jest pgps.spec.ts
38+
- run: npx tsx --test ./api-verification/pgps.spec.ts
3939
groundfix:
4040
name: Ground Fix Services API verification tests
4141
runs-on: ubuntu-22.04
@@ -45,7 +45,7 @@ jobs:
4545
node-version: "20.x"
4646
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
4747
- run: npm ci
48-
- run: npx jest ground-fix.spec.ts
48+
- run: npx tsx --test ./api-verification/ground-fix.spec.ts
4949
evaltoken:
5050
name: Evaluation Token Authentication verification tests
5151
runs-on: ubuntu-22.04
@@ -58,7 +58,9 @@ jobs:
5858
if: env.EVALUATION_TOKEN != ''
5959
- run: npm ci
6060
if: env.EVALUATION_TOKEN != ''
61-
- run: npx jest evaluation-token-authentication.spec.ts
61+
- run:
62+
npx tsx --test
63+
./api-verification/evaluation-token-authentication.spec.ts
6264
if: env.EVALUATION_TOKEN != ''
6365
devicetoken:
6466
name: Device Token Authentication verification tests
@@ -69,4 +71,5 @@ jobs:
6971
node-version: "20.x"
7072
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
7173
- run: npm ci
72-
- run: npx jest device-token-authentication.spec.ts
74+
- run:
75+
npx tsx --test ./api-verification/device-token-authentication.spec.ts

.husky/pre-commit

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/bin/sh
22
. "$(dirname "$0")/_/husky.sh"
33

4-
npx lint-staged && npx jest src --onlyChanged
4+
npx lint-staged
5+
npm test

api-verification/agps.spec.ts

Lines changed: 45 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
import { AGPSMessage, SCHEMA_VERSION, verify } from '../src/verify-agps-data'
2-
import { apiClient, tokenAuthorization } from './api-client'
1+
import { AGPSMessage, SCHEMA_VERSION, verify } from '../src/verify-agps-data.js'
2+
import { apiClient, tokenAuthorization } from './api-client.js'
3+
import { describe, it } from 'node:test'
4+
import assert from 'node:assert/strict'
35

46
const { getBinary, head } = apiClient({
57
endpoint: process.env.API_HOST,
@@ -11,9 +13,9 @@ const { getBinary, head } = apiClient({
1113
}),
1214
})
1315

14-
describe('AGPS', () => {
15-
describe('chunking', () => {
16-
describe('use HEAD request to get response size', () => {
16+
void describe('AGPS', () => {
17+
void describe('chunking', () => {
18+
void describe('use HEAD request to get response size', () => {
1719
const agpsReq = {
1820
deviceIdentifier: 'TestClient',
1921
mcc: 242,
@@ -24,14 +26,14 @@ describe('AGPS', () => {
2426
}
2527
let chunkSize: number
2628

27-
it('should describe length of A-GPS data', async () => {
29+
void it('should describe length of A-GPS data', async () => {
2830
const res = await head({ resource: 'location/agps', payload: agpsReq })
29-
chunkSize = parseInt(res['content-length'] ?? '0', 10)
30-
expect(chunkSize).toBeGreaterThan(0)
31+
chunkSize = parseInt(res.get('content-length') ?? '0', 10)
32+
assert.equal(chunkSize > 0, true)
3133
})
3234

33-
it('should return A-GPS data', async () => {
34-
expect(chunkSize).toBeGreaterThan(0) // chunk size should have been set
35+
void it('should return A-GPS data', async () => {
36+
assert.equal(chunkSize > 0, true) // chunk size should have been set
3537
const res = await getBinary({
3638
resource: 'location/agps',
3739
payload: agpsReq,
@@ -40,15 +42,15 @@ describe('AGPS', () => {
4042
Range: `bytes=0-${chunkSize}`,
4143
},
4244
})
43-
expect(res.length).toBe(chunkSize)
45+
assert.equal(res.length, chunkSize)
4446

4547
// Verify response
4648
const verified = verify(res)
47-
expect('error' in verified).toEqual(false)
48-
expect((verified as AGPSMessage).schemaVersion).toEqual(SCHEMA_VERSION)
49+
assert.equal('error' in verified, false)
50+
assert.equal((verified as AGPSMessage).schemaVersion, SCHEMA_VERSION)
4951
})
5052

51-
it('should chunk large responses', async () => {
53+
void it('should chunk large responses', async () => {
5254
const res = await getBinary({
5355
resource: 'location/agps',
5456
payload: {
@@ -64,23 +66,22 @@ describe('AGPS', () => {
6466
Range: `bytes=0-2000`,
6567
},
6668
})
67-
expect(res.length).toBeLessThan(2000)
69+
assert.equal(res.length < 2000, true)
6870

6971
// Verify response
7072
const verified = verify(res)
71-
expect('error' in verified).toEqual(false)
72-
expect((verified as AGPSMessage).schemaVersion).toEqual(SCHEMA_VERSION)
73-
expect((verified as AGPSMessage).entries).toHaveLength(1)
74-
expect((verified as AGPSMessage).entries[0].type).toEqual(2)
75-
expect((verified as AGPSMessage).entries[0].items).toBeGreaterThan(0)
73+
assert.equal('error' in verified, false)
74+
assert.equal((verified as AGPSMessage).schemaVersion, SCHEMA_VERSION)
75+
assert.equal((verified as AGPSMessage).entries.length, 1)
76+
assert.equal((verified as AGPSMessage).entries[0].type, 2)
77+
assert.equal((verified as AGPSMessage).entries[0].items > 0, true)
7678
})
7779
})
7880
})
7981

80-
describe('should support 8 types', () => {
81-
it.each([[1], [2], [3], [4], [6], [7], [8], [9]])(
82-
'should resolve custom type %d',
83-
async (type) => {
82+
void describe('should support 8 types', () => {
83+
for (const type of [1, 2, 3, 4, 6, 7, 8, 9]) {
84+
void it(`should resolve custom type ${type}`, async () => {
8485
const agpsReq = {
8586
mcc: 242,
8687
mnc: 2,
@@ -94,8 +95,8 @@ describe('AGPS', () => {
9495
resource: 'location/agps',
9596
payload: agpsReq,
9697
})
97-
const chunkSize = parseInt(headRes['content-length'] ?? '0', 10)
98-
expect(chunkSize).toBeGreaterThan(0)
98+
const chunkSize = parseInt(headRes.get('content-length') ?? '0', 10)
99+
assert.equal(chunkSize > 0, true)
99100

100101
const res = await getBinary({
101102
resource: 'location/agps',
@@ -105,20 +106,20 @@ describe('AGPS', () => {
105106
Range: `bytes=0-${chunkSize}`,
106107
},
107108
})
108-
expect(res.length).toEqual(chunkSize)
109+
assert.equal(res.length, chunkSize)
109110

110111
// Verify response
111112
const verified = verify(res)
112-
expect('error' in verified).toEqual(false)
113-
expect((verified as AGPSMessage).schemaVersion).toEqual(SCHEMA_VERSION)
114-
expect((verified as AGPSMessage).entries).toHaveLength(1)
115-
expect((verified as AGPSMessage).entries[0].type).toEqual(type)
116-
expect((verified as AGPSMessage).entries[0].items).toBeGreaterThan(0)
117-
},
118-
)
113+
assert.equal('error' in verified, false)
114+
assert.equal((verified as AGPSMessage).schemaVersion, SCHEMA_VERSION)
115+
assert.equal((verified as AGPSMessage).entries.length, 1)
116+
assert.equal((verified as AGPSMessage).entries[0].type, type)
117+
assert.equal((verified as AGPSMessage).entries[0].items > 0, true)
118+
})
119+
}
119120
})
120121

121-
it('should combine types', async () => {
122+
void it('should combine types', async () => {
122123
const types = new Set([1, 3, 4, 6, 7, 8, 9])
123124
const agpsReq = {
124125
mcc: 242,
@@ -133,8 +134,8 @@ describe('AGPS', () => {
133134
resource: 'location/agps',
134135
payload: agpsReq,
135136
})
136-
const chunkSize = parseInt(headRes['content-length'] ?? '0', 10)
137-
expect(chunkSize).toBeGreaterThan(0)
137+
const chunkSize = parseInt(headRes.get('content-length') ?? '0', 10)
138+
assert.equal(chunkSize > 0, true)
138139

139140
const res = await getBinary({
140141
resource: 'location/agps',
@@ -144,15 +145,16 @@ describe('AGPS', () => {
144145
Range: `bytes=0-${chunkSize}`,
145146
},
146147
})
147-
expect(res.length).toEqual(chunkSize)
148+
assert.equal(res.length, chunkSize)
148149

149150
// Verify response
150151
const verified = verify(res)
151-
expect('error' in verified).toEqual(false)
152-
expect((verified as AGPSMessage).schemaVersion).toEqual(SCHEMA_VERSION)
153-
expect((verified as AGPSMessage).entries).toHaveLength(7)
154-
expect(
152+
assert.equal('error' in verified, false)
153+
assert.equal((verified as AGPSMessage).schemaVersion, SCHEMA_VERSION)
154+
assert.equal((verified as AGPSMessage).entries.length, 7)
155+
assert.deepEqual(
155156
new Set((verified as AGPSMessage).entries.map(({ type }) => type)),
156-
).toEqual(types)
157+
types,
158+
)
157159
})
158160
})

api-verification/api-client.ts

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { IncomingHttpHeaders, IncomingMessage, OutgoingHttpHeaders } from 'http'
1+
import { IncomingMessage, OutgoingHttpHeaders } from 'http'
22
import * as https from 'https'
33
import * as jwt from 'jsonwebtoken'
44
import { URL, URLSearchParams } from 'url'
@@ -246,39 +246,35 @@ export const apiClient = ({
246246
}: {
247247
resource: string
248248
payload: Record<string, any>
249-
headers?: OutgoingHttpHeaders
250-
}) =>
251-
new Promise<IncomingHttpHeaders>((resolve, reject) => {
252-
const options = {
253-
hostname: e.hostname,
254-
port: 443,
255-
path: `/v1/${resource}?${new URLSearchParams(payload).toString()}`,
256-
headers: {
257-
Authorization: `Bearer ${authorizationToken}`,
258-
...headers,
259-
},
260-
method: 'HEAD',
261-
}
249+
headers?: Record<string, string>
250+
}): Promise<Headers> => {
251+
const url = new URL(
252+
`https://${e.hostname}/v1/${resource}?${new URLSearchParams(
253+
payload,
254+
).toString()}`,
255+
)
262256

263-
const req = https.request(options, (res) => {
264-
console.debug(
265-
[
266-
`> HEAD https://${e.hostname}/v1/${resource}?${new URLSearchParams(
267-
payload,
268-
).toString()}`,
269-
`< ${res.statusCode} ${res.statusMessage}`,
270-
...Object.entries(res.headers).map(([k, v]) => `< ${k}: ${v}`),
271-
].join('\n'),
272-
)
273-
274-
if ((res.statusCode ?? -1) > 399)
275-
return reject(new Error(`Request failed: ${res.statusCode}`))
276-
return resolve(res.headers)
277-
})
278-
req.on('error', reject)
279-
req.end()
257+
const res = await fetch(url, {
258+
method: 'HEAD',
259+
headers: {
260+
Authorization: `Bearer ${authorizationToken}`,
261+
...headers,
262+
},
280263
})
281264

265+
console.debug(
266+
[
267+
`> HEAD ${url.toString()}`,
268+
`< ${res.status} ${res.statusText}`,
269+
...[...new Set(res.headers.entries())].map(([k, v]) => `< ${k}: ${v}`),
270+
].join('\n'),
271+
)
272+
273+
if ((res.status ?? -1) > 399)
274+
throw new Error(`Request failed: ${res.status}`)
275+
return res.headers
276+
}
277+
282278
return {
283279
head,
284280
getJSON,

api-verification/device-token-authentication.spec.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { spawn } from 'child_process'
22
import { randomUUID } from 'node:crypto'
33
import * as os from 'os'
4-
import { apiClient, tokenAuthorization } from './api-client'
4+
import { apiClient, tokenAuthorization } from './api-client.js'
5+
import { describe, it, before } from 'node:test'
6+
import assert from 'node:assert/strict'
57

68
const endpoint = process.env.API_HOST
79

@@ -10,13 +12,13 @@ const apiKeyClient = apiClient({
1012
authorizationToken: process.env.API_KEY as string,
1113
})
1214

13-
describe('authenticate using device keys', () => {
15+
void describe('authenticate using device keys', () => {
1416
let privateKey: string
1517
let publicKey: string
1618
let deviceId: string
1719
let bulkOpsRequestId: string
1820

19-
beforeAll(async () => {
21+
before(async () => {
2022
// Generate a globally uniqe device ID
2123
deviceId = randomUUID()
2224

@@ -72,16 +74,16 @@ describe('authenticate using device keys', () => {
7274
})
7375
})
7476

75-
it('should register a new device key', async () => {
77+
void it('should register a new device key', async () => {
7678
const { bulkOpsRequestId: rid } = await apiKeyClient.postBinary({
7779
resource: 'devices/public-keys',
7880
payload: `${deviceId},"${publicKey}"`,
7981
})
8082
bulkOpsRequestId = rid
81-
expect(bulkOpsRequestId).not.toBeUndefined()
83+
assert.notEqual(bulkOpsRequestId, undefined)
8284
})
8385

84-
it('should process the request', async () => {
86+
void it('should process the request', async () => {
8587
const getStatus = async () =>
8688
apiKeyClient
8789
.getJSON({
@@ -103,10 +105,10 @@ describe('authenticate using device keys', () => {
103105
reject(new Error(`Timeout`))
104106
}, 30000)
105107
})
106-
expect(status).toEqual('SUCCEEDED')
108+
assert.equal(status, 'SUCCEEDED')
107109
})
108110

109-
it('should accept the device-key based JWT', async () => {
111+
void it('should accept the device-key based JWT', async () => {
110112
const { getJSON } = apiClient({
111113
endpoint,
112114
authorizationToken: tokenAuthorization({
@@ -123,7 +125,7 @@ describe('authenticate using device keys', () => {
123125
predictionIntervalMinutes: 120,
124126
},
125127
})
126-
expect(res.host).not.toBeUndefined()
127-
expect(res.path).not.toBeUndefined()
128+
assert.notEqual(res.host, undefined)
129+
assert.notEqual(res.path, undefined)
128130
})
129131
})
Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import { apiClient } from './api-client'
1+
import { apiClient } from './api-client.js'
2+
import { describe, it } from 'node:test'
3+
import assert from 'node:assert/strict'
24

35
const endpoint = process.env.API_HOST
46

@@ -7,16 +9,16 @@ const { getJSON } = apiClient({
79
authorizationToken: process.env.EVALUATION_TOKEN as string,
810
})
911

10-
describe('authenticate using evaluation token', () => {
11-
it('should accept the evaluation token', async () => {
12+
void describe('authenticate using evaluation token', () => {
13+
void it('should accept the evaluation token', async () => {
1214
const res = await getJSON<{ host: string; path: string }>({
1315
resource: 'location/pgps',
1416
payload: {
1517
predictionCount: 6,
1618
predictionIntervalMinutes: 120,
1719
},
1820
})
19-
expect(res.host).not.toBeUndefined()
20-
expect(res.path).not.toBeUndefined()
21+
assert.notEqual(res.host, undefined)
22+
assert.notEqual(res.path, undefined)
2123
})
2224
})

0 commit comments

Comments
 (0)