Skip to content

Commit 909abc2

Browse files
committed
Add token header to next request for US commands
1 parent dadd088 commit 909abc2

7 files changed

Lines changed: 2048 additions & 831 deletions

File tree

jest.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module.exports = {
55
transform: {
66
'^.+\\.ts?$': 'ts-jest',
77
},
8-
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.ts?$',
8+
testRegex: '(lib/__tests__/.*|(\\.|/)(test|spec))\\.ts?$',
99
moduleFileExtensions: ['ts', 'js', 'json', 'node'],
1010
globals: {
1111
'ts-jest': {

lib/__tests__/vehicle.spec.ts

Lines changed: 108 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import EUROPE_STATUS_MOCK from './mock/europeStatus.json';
1515

1616
jest.mock('got');
1717

18+
const gotMock = got as any;
19+
1820
const referenceMap = {
1921
US: {
2022
controller: AmericanController,
@@ -30,14 +32,14 @@ const referenceMap = {
3032
},
3133
};
3234

33-
const getVehicle = region => {
35+
const getVehicle = (region: string) => {
3436
const Vehicle = referenceMap[region].vehicle;
3537
const Controller = referenceMap[region].controller;
3638

3739
const controller = new Controller({
3840
username: 'testuser@gmail.com',
3941
password: 'test',
40-
region: 'US',
42+
region: region,
4143
autoLogin: true,
4244
pin: '1234',
4345
vin: '4444444444444',
@@ -67,9 +69,48 @@ describe('AmericanVehicle', () => {
6769
expect(vehicle.nickname()).toEqual('Jest is best');
6870
});
6971

72+
it('refresh expired access token', async () => {
73+
// create session with expired access token
74+
vehicle.controller.session = {
75+
accessToken: 'JEST_TOKEN',
76+
refreshToken: 'JEST_TOKEN',
77+
tokenExpiresAt: Math.floor(Date.now() / 1000) - 100,
78+
};
79+
80+
// mock token request
81+
gotMock.mockReturnValueOnce({
82+
body: {
83+
access_token: 'JEST_TOKEN',
84+
refresh_token: 'JEST_TOKEN',
85+
expires_in: 10,
86+
},
87+
json: true,
88+
statusCode: 200,
89+
});
90+
91+
const result = await vehicle.controller.refreshAccessToken();
92+
expect(result).toEqual('Token refreshed');
93+
94+
// should update access token
95+
expect(vehicle.controller.session.accessToken).toEqual('JEST_TOKEN');
96+
expect(vehicle.controller.session.tokenExpiresAt).toBeGreaterThan(
97+
Math.floor(Date.now() / 1000)
98+
);
99+
expect(vehicle.controller.session.tokenExpiresAt).toBeLessThan(
100+
Math.floor(Date.now() / 1000 + 20)
101+
);
102+
});
103+
70104
it('call lock commmand', async () => {
71-
(got as any).mockReturnValueOnce({
72-
body: {},
105+
// default session with a valid token
106+
vehicle.controller.session = {
107+
accessToken: 'JEST_TOKEN',
108+
refreshToken: 'JEST_TOKEN',
109+
tokenExpiresAt: Date.now() / 1000 + 300,
110+
};
111+
112+
gotMock.mockReturnValueOnce({
113+
body: JSON.stringify({}),
73114
statusCode: 200,
74115
});
75116

@@ -78,7 +119,7 @@ describe('AmericanVehicle', () => {
78119
});
79120

80121
it('call status commmand', async () => {
81-
(got as any).mockReturnValueOnce({
122+
gotMock.mockReturnValueOnce({
82123
body: JSON.stringify({ vehicleStatus: AMERICAN_STATUS_MOCK }),
83124
statusCode: 200,
84125
});
@@ -89,14 +130,49 @@ describe('AmericanVehicle', () => {
89130
});
90131

91132
describe('CanadianVehicle', () => {
92-
const vehicle = getVehicle('CA');
133+
const vehicle: CanadianVehicle = getVehicle('CA');
93134

94135
it('define new vehicle', () => {
95136
expect(vehicle.nickname()).toEqual('Jest is best');
96137
});
97138

139+
it('refresh expired access token', async () => {
140+
// create session with expired access token
141+
vehicle.controller.session = {
142+
accessToken: 'JEST_TOKEN',
143+
refreshToken: 'JEST_TOKEN',
144+
tokenExpiresAt: Date.now() / 1000,
145+
controlTokenExpiresAt: 0,
146+
};
147+
148+
// mock token request
149+
gotMock.mockReturnValueOnce({
150+
body: JSON.stringify({
151+
access_token: 'JEST_TOKEN',
152+
refresh_token: 'JEST_TOKEN',
153+
expires_in: 10,
154+
}),
155+
statusCode: 200,
156+
});
157+
158+
const result = await vehicle.controller.refreshAccessToken();
159+
expect(result).toEqual('Token refreshed');
160+
// should update access token
161+
expect(vehicle.controller.session.accessToken).toEqual('JEST_TOKEN');
162+
expect(vehicle.controller.session.tokenExpiresAt).toBeGreaterThan(Math.floor(Date.now() / 1000));
163+
expect(vehicle.controller.session.tokenExpiresAt).toBeLessThan(Math.floor(Date.now() / 1000 + 20));
164+
165+
});
166+
98167
it('call lock commmand', async () => {
99-
(got as any).mockReturnValueOnce({
168+
// default session with a valid token
169+
vehicle.controller.session = {
170+
accessToken: 'JEST_TOKEN',
171+
refreshToken: 'JEST_TOKEN',
172+
tokenExpiresAt: Date.now() / 1000 + 300,
173+
};
174+
175+
gotMock.mockReturnValueOnce({
100176
body: {
101177
result: {
102178
pAuth: 'test',
@@ -106,15 +182,17 @@ describe('CanadianVehicle', () => {
106182
},
107183
},
108184
statusCode: 200,
185+
json: true,
109186
});
110187

111-
(got as any).mockReturnValueOnce({
188+
gotMock.mockReturnValueOnce({
112189
body: {
113190
responseHeader: {
114191
responseCode: 0,
115192
},
116193
},
117194
statusCode: 200,
195+
json: true,
118196
});
119197

120198
const response = await vehicle.lock();
@@ -141,24 +219,28 @@ describe('EuropeanVehicle', () => {
141219
};
142220

143221
// mock token request
144-
(got as any).mockReturnValueOnce({
222+
gotMock.mockReturnValueOnce({
145223
body: JSON.stringify({ access_token: 'AAAAAAAA', expires_in: 10 }),
146224
statusCode: 200,
147225
});
148226

149-
(got as any).mockClear();
227+
gotMock.mockClear();
150228

151229
const result = await vehicle.controller.refreshAccessToken();
152230
expect(result).toEqual('Token refreshed');
153231
// should update access token
154232
expect(vehicle.controller.session.accessToken).toEqual('Bearer AAAAAAAA');
155-
expect(vehicle.controller.session.tokenExpiresAt).toBeGreaterThan(Date.now() / 1000);
156-
expect(vehicle.controller.session.tokenExpiresAt).toBeLessThan(Date.now() / 1000 + 20);
157-
158-
const gotArgs = (got as any).mock.calls[0];
233+
expect(vehicle.controller.session.tokenExpiresAt).toBeGreaterThan(
234+
Math.floor(Date.now() / 1000)
235+
);
236+
expect(vehicle.controller.session.tokenExpiresAt).toBeLessThan(
237+
Math.floor(Date.now() / 1000 + 20)
238+
);
239+
240+
const gotArgs = gotMock.mock.calls[0];
159241
expect(gotArgs[0]).toMatch(/token$/);
160-
expect(gotArgs[1].body).toContain("grant_type=refresh_token");
161-
expect(gotArgs[1].body).toContain("refresh_token=" + vehicle.controller.session.refreshToken);
242+
expect(gotArgs[1].body).toContain('grant_type=refresh_token');
243+
expect(gotArgs[1].body).toContain('refresh_token=' + vehicle.controller.session.refreshToken);
162244
});
163245

164246
it('not refresh active access token', async () => {
@@ -172,12 +254,12 @@ describe('EuropeanVehicle', () => {
172254
controlTokenExpiresAt: 0,
173255
};
174256

175-
(got as any).mockClear();
257+
gotMock.mockClear();
176258

177259
const result = await vehicle.controller.refreshAccessToken();
178260
expect(result).toEqual('Token not expired, no need to refresh');
179261
// should not call got
180-
expect((got as any).mock.calls).toHaveLength(0);
262+
expect(gotMock.mock.calls).toHaveLength(0);
181263
});
182264

183265
it('refresh expired control token', async () => {
@@ -192,24 +274,24 @@ describe('EuropeanVehicle', () => {
192274
};
193275

194276
// mock pin request
195-
(got as any).mockReturnValueOnce({
277+
gotMock.mockReturnValueOnce({
196278
body: { controlToken: 'BBBBBB', expiresTime: 10 },
197279
statusCode: 200,
198280
});
199281

200-
(got as any).mockClear();
282+
gotMock.mockClear();
201283

202284
await vehicle.checkControlToken();
203285
// should update control token
204286
expect(vehicle.controller.session.controlToken).toEqual('Bearer BBBBBB');
205287
expect(vehicle.controller.session.controlTokenExpiresAt).toBeGreaterThan(Date.now() / 1000);
206288
expect(vehicle.controller.session.controlTokenExpiresAt).toBeLessThan(Date.now() / 1000 + 20);
207289

208-
const gotArgs = (got as any).mock.calls[0];
290+
const gotArgs = gotMock.mock.calls[0];
209291
expect(gotArgs[0]).toMatch(/pin$/);
210292
expect(gotArgs[1].headers.Authorization).toEqual(vehicle.controller.session.accessToken);
211-
expect(gotArgs[1].body.deviceId).toEqual("aaaa-bbbb-cccc-eeee");
212-
expect(gotArgs[1].body.pin).toEqual("1234");
293+
expect(gotArgs[1].body.deviceId).toEqual('aaaa-bbbb-cccc-eeee');
294+
expect(gotArgs[1].body.pin).toEqual('1234');
213295
});
214296

215297
it('not refresh active control token', async () => {
@@ -223,11 +305,11 @@ describe('EuropeanVehicle', () => {
223305
controlTokenExpiresAt: Date.now() / 1000 + 10,
224306
};
225307

226-
(got as any).mockClear();
308+
gotMock.mockClear();
227309

228310
await vehicle.checkControlToken();
229311
// should not call got
230-
expect((got as any).mock.calls).toHaveLength(0);
312+
expect(gotMock.mock.calls).toHaveLength(0);
231313
});
232314

233315
it('call status commmand', async () => {
@@ -242,7 +324,7 @@ describe('EuropeanVehicle', () => {
242324
};
243325

244326
// mock the status request
245-
(got as any).mockReturnValueOnce({
327+
gotMock.mockReturnValueOnce({
246328
body: EUROPE_STATUS_MOCK,
247329
statusCode: 200,
248330
});

lib/controllers/american.controller.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ export class AmericanController extends SessionController {
3333
},
3434
json: true,
3535
});
36+
37+
logger.debug(response.body);
3638
this.session.accessToken = response.body.access_token;
3739
this.session.refreshToken = response.body.refresh_token;
3840
this.session.tokenExpiresAt = Math.floor(
@@ -64,6 +66,8 @@ export class AmericanController extends SessionController {
6466
json: true,
6567
});
6668

69+
logger.debug(response.body);
70+
6771
if (response.statusCode !== 200) {
6872
return 'login bad';
6973
}

lib/vehicles/american.vehicle.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,14 @@ export default class AmericanVehicle extends Vehicle {
293293
// add logic for token refresh if to ensure we don't use a stale token
294294
await this.controller.refreshAccessToken();
295295

296+
// if we refreshed token make sure to apply it to the request
297+
options.headers.access_token = this.controller.session.accessToken;
298+
296299
const response = await got(`${BASE_URL}/${service}`, { throwHttpErrors: false, ...options });
297-
logger.debug(response.body);
300+
301+
if (response?.body) {
302+
logger.debug(response.body);
303+
}
298304

299305
return response;
300306
}

lib/vehicles/canadian.vehicle.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ export default class CanadianVehicle extends Vehicle {
229229
private async request(endpoint, body: any, headers: any = {}): Promise<any | null> {
230230
logger.debug(`[${endpoint}] ${JSON.stringify(headers)} ${JSON.stringify(body)}`);
231231

232-
// add logic for token refresh if to ensure we don't use a stale token
232+
// add logic for token refresh to ensure we don't use a stale token
233233
await this.controller.refreshAccessToken();
234234

235235
const options = {

0 commit comments

Comments
 (0)