Skip to content

Commit

Permalink
Implement 'Send Destination' Feature in Smartcar Node SDK (#167)
Browse files Browse the repository at this point in the history
* Update readme.md

* Update readme.md

* Update readme.md

* Update readme.md

* Update readme.md

* Update readme.md

* feat: send destination endpoint added.

* Revert doc/readme.md to the version in master branch

* feat: docs updated

* feat: added validation tests
  • Loading branch information
aytekin-smartcar authored Dec 13, 2023
1 parent 6846319 commit 20c8e31
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 8 deletions.
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
**
33 changes: 31 additions & 2 deletions doc/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,7 @@ Initializes a new Service object to make requests to the Smartcar API.
* [.permissions([paging])](#Vehicle+permissions)[<code>Permissions</code>](#Permissions)
* [.getChargeLimit()](#Vehicle+getChargeLimit)[<code>ChargeLimit</code>](#ChargeLimit)
* [.setChargeLimit(limit)](#Vehicle+setChargeLimit)[<code>ChargeLimit</code>](#ChargeLimit)
* [.sendDestination(latitude, longitude)](#Vehicle+sendDestination)[<code>ActionResponse</code>](#ActionResponse)
* [.subscribe(webhookId)](#Vehicle+subscribe) ⇒ <code>Object</code>
* [.unsubscribe(amt, webhookId)](#Vehicle+unsubscribe)[<code>Meta</code>](#Meta)
* [.batch(paths)](#Vehicle+batch)[<code>Batch</code>](#Batch)
Expand Down Expand Up @@ -711,6 +712,34 @@ Set the charge limit for an electric vehicle.
}
}
```
<a name="Vehicle+sendDestination"></a>

### vehicle.sendDestination(latitude, longitude) ⇒ [<code>ActionResponse</code>](#ActionResponse)
Send a destination to the vehicle's navigation system.

**Kind**: instance method of [<code>Vehicle</code>](#Vehicle)
**Returns**: [<code>ActionResponse</code>](#ActionResponse) - - A Response object containing the status and metadata.
**Throws**:

- [<code>SmartcarError</code>](#SmartcarError) - An instance of SmartcarError.
See the [errors section](https://github.com/smartcar/node-sdk/tree/master/doc#errors)
for all possible errors.


| Param | Type | Description |
| --- | --- | --- |
| latitude | <code>number</code> | Latitude of the destination. Must be a valid latitude value between -90 and 90 (inclusive). |
| longitude | <code>number</code> | Longitude of the destination. Must be a valid longitude value between -180 and 180 (inclusive). |

**Example**
```js
{
status: string,
meta: {
requestId: '26c14915-0c26-43c5-8e42-9edfc2a66a0f',
}
}
```
<a name="Vehicle+subscribe"></a>

### vehicle.subscribe(webhookId) ⇒ <code>Object</code>
Expand Down Expand Up @@ -782,7 +811,7 @@ General purpose method to make a request to a Smartcar endpoint.
| method | <code>String</code> | The HTTP request method to use. |
| path | <code>String</code> | The path to make the request to. |
| body | <code>Object</code> | The request body. |
| headers | <code>Object</code> | The headers to inlcude in the request. |
| headers | <code>Object</code> | The headers to include in the request. |

<a name="Vehicle+vin"></a>

Expand Down Expand Up @@ -1278,7 +1307,7 @@ the following fields :
**Example**
```js
{
frontleft: 33,
frontLeft: 33,
frontRight: 34,
backLeft: 34,
backRight: 33
Expand Down
52 changes: 50 additions & 2 deletions lib/vehicle.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const METHODS_MAP = {
stopCharge: {requestType: 'post', path: 'charge', body: {action: 'STOP'}},
disconnect: {requestType: 'delete', path: 'application'},
lockStatus: {path: 'security'},
sendDestination: {path: 'navigation/destination'},
};

/** @exports Vehicle */
Expand Down Expand Up @@ -205,6 +206,53 @@ Vehicle.prototype.setChargeLimit = async function(limit) {
return response;
};

/**
* Send a destination to the vehicle's navigation system.
*
* @method
* @param {number} latitude - Latitude of the destination. Must be a valid latitude
* value between -90 and 90 (inclusive).
* @param {number} longitude - Longitude of the destination. Must be a valid longitude
* value between -180 and 180 (inclusive).
* @returns {ActionResponse} - A Response object containing the status and metadata.
* @throws {SmartcarError} - An instance of SmartcarError.
* See the [errors section](https://github.com/smartcar/node-sdk/tree/master/doc#errors)
* for all possible errors.
*
* @example
* {
* status: string,
* meta: {
* requestId: '26c14915-0c26-43c5-8e42-9edfc2a66a0f',
* }
* }
*/
Vehicle.prototype.sendDestination = async function(latitude, longitude) {
// Validate the latitude and longitude values
if (latitude < -90 || latitude > 90) {
throw new Error('Invalid latitude value. It must be between -90 and 90.');
}
if (longitude < -180 || longitude > 180) {
throw new Error(
'Invalid longitude value. It must be between -180 and 180.',
);
}

const body = {
latitude: Number(latitude),
longitude: Number(longitude),
};

const response = await this.service.request(
'post',
'navigation/destination',
{body},
);

return response;
};


/**
* @type {Object}
* @typedef WebhookSubscription
Expand Down Expand Up @@ -310,7 +358,7 @@ Vehicle.prototype.batch = async function(paths) {
* @param {String} method - The HTTP request method to use.
* @param {String} path - The path to make the request to.
* @param {Object} body - The request body.
* @param {Object} headers - The headers to inlcude in the request.
* @param {Object} headers - The headers to include in the request.
* @return {Response}
* @throws {SmartcarError} - an instance of SmartcarError.
* See the [errors section](https://github.com/smartcar/node-sdk/tree/master/doc#errors)
Expand Down Expand Up @@ -527,7 +575,7 @@ Vehicle.prototype.request = async function(
*
* @example
* {
* frontleft: 33,
* frontLeft: 33,
* frontRight: 34,
* backLeft: 34,
* backRight: 33
Expand Down
6 changes: 3 additions & 3 deletions test/end-to-end/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ test('handleError - SmartcarError V2 resolution string', async function(t) {
t.true(error instanceof SmartcarError);
t.is(error.statusCode, 409);
t.is(error.resolution.type, 'RETRY_LATER');
t.is(error.docURL, 'https://smartcar.com/docs/errors/v2.0/vehicle-state/#unknown');
t.is(error.docURL, 'https://smartcar.com/docs/errors/api-errors/vehicle-state-errors#unknown');
t.is(error.description, description);
t.is(error.type, 'VEHICLE_STATE');
t.is(error.code, 'UNKNOWN');
Expand All @@ -52,7 +52,7 @@ test('handleError - SmartcarError V2 resolution null', async function(t) {
t.true(error instanceof SmartcarError);
t.is(error.statusCode, 400);
t.is(error.resolution.type, null);
t.is(error.docURL, 'https://smartcar.com/docs/errors/v2.0/connected-services-account/#vehicle_missing');
t.is(error.docURL, 'https://smartcar.com/docs/errors/api-errors/connected-services-account-errors#vehicle-missing');
t.is(error.description, description);
t.is(error.type, 'CONNECTED_SERVICES_ACCOUNT');
t.is(error.code, 'VEHICLE_MISSING');
Expand Down Expand Up @@ -90,7 +90,7 @@ test('handleError - SmartcarError V2 code null', async function(t) {
t.true(error instanceof SmartcarError);
t.is(error.statusCode, 403);
t.is(error.resolution.type, 'REAUTHENTICATE');
t.is(error.docURL, 'https://smartcar.com/docs/errors/v2.0/other-errors/#permission');
t.is(error.docURL, 'https://smartcar.com/docs/errors/api-errors/permission-errors#null');
t.is(error.description, description);
t.is(error.type, 'PERMISSION');
t.is(error.code, undefined);
Expand Down
39 changes: 38 additions & 1 deletion test/end-to-end/vehicle.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ test.before(async(t) => {
'required:control_charge',
'required:control_security',
'required:read_security',
'required:control_navigation',
]),
getVehicle('KIA', [
'required:read_charge',
Expand Down Expand Up @@ -494,7 +495,7 @@ test('vehicle request - override auth header', async(t) => {
t.is(err.statusCode, 401);
t.is(err.type, 'AUTHENTICATION');
t.is(err.description, errorMessage);
t.is(err.docURL, 'https://smartcar.com/docs/errors/v2.0/other-errors/#authentication');
t.is(err.docURL, 'https://smartcar.com/docs/errors/api-errors/authentication-errors#null');
});
});

Expand All @@ -510,6 +511,42 @@ test('vehicle request - set charge limit', async(t) => {
t.is(response.status, 'success');
});

test('vehicle request - send destination', async(t) => {
const latitude = 37.7749;
const longitude = -122.4194;

const response = await t.context.ford.sendDestination(latitude, longitude);
t.is(response.status, 'success');
});

test('vehicle request - send invalid coordinates', async(t) => {
// Array of invalid latitude and longitude values
const invalidCoordinates = [
{lat: 100, lon: -122.4194}, // Latitude out of range (> 90)
{lat: -91, lon: -122.4194}, // Latitude out of range (< -90)
{lat: 37.7749, lon: 200}, // Longitude out of range (> 180)
{lat: 37.7749, lon: -181}, // Longitude out of range (< -180)
];

for (const {lat, lon} of invalidCoordinates) {
// eslint-disable-next-line no-await-in-loop
const error = await t.throwsAsync(
t.context.ford.sendDestination(lat, lon),
{instanceOf: Error},
);

// Check that the error message is correct based on the invalid input
if (lat < -90 || lat > 90) {
// eslint-disable-next-line max-len
t.is(error.message, 'Invalid latitude value. It must be between -90 and 90.');
} else if (lon < -180 || lon > 180) {
// eslint-disable-next-line max-len
t.is(error.message, 'Invalid longitude value. It must be between -180 and 180.');
}
}
});


test.after.always('vehicle disconnect', async(t) => {
const response = await t.context.kia.disconnect();
t.deepEqual(
Expand Down

0 comments on commit 20c8e31

Please sign in to comment.