Skip to content

Commit

Permalink
Merge pull request particle-iot#38 from AntonPuko/deviceControllerTests
Browse files Browse the repository at this point in the history
Device controller tests
  • Loading branch information
jlkalberer authored Dec 15, 2016
2 parents 79eb143 + c5a16ef commit 01c5b03
Show file tree
Hide file tree
Showing 9 changed files with 216 additions and 48 deletions.
139 changes: 139 additions & 0 deletions test/DevicesController.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import test from 'ava';
import request from 'supertest-as-promised';
import ouathClients from '../src/oauthClients.json';
import app from './setup/testApp';
import settings from './setup/settings';

const USER_CREDENTIALS = {
password: 'password',
username: 'deviceTestUser@test.com',
};

const DEVICE_ID = '350023001951353337343732';
const TEST_PUBLIC_KEY =
'-----BEGIN PUBLIC KEY-----\n' +
'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsxJFqlUOxK5bsEfTtBCe9sXBa' +
'43q9QoSPFXEG5qY/+udOpf2SKacgfUVdUbK4WOkLou7FQ+DffpwztBk5fWM9qfzF' +
'EQRVMS8xwS4JqqD7slXwuPWFpS9SGy9kLNy/pl1dtGm556wVX431Dg7UBKiXuNGR' +
'7E8d2hfgeyiTtsWfUQIDAQAB\n' +
'-----END PUBLIC KEY-----\n';

let testUser;
let userToken;
let deviceToApiAttributes;

test.before(async () => {
const userResponse = await request(app)
.post('/v1/users')
.send(USER_CREDENTIALS);

testUser = userResponse.body;

const tokenResponse = await request(app)
.post('/oauth/token')
.set('Content-Type', 'application/x-www-form-urlencoded')
.send({
client_id: ouathClients[0].clientId,
client_secret: ouathClients[0].clientSecret,
grant_type: 'password',
password: USER_CREDENTIALS.password,
username: USER_CREDENTIALS.username,
});

userToken = tokenResponse.body.access_token;
});

// TODO come up better test name
test.serial('provision test', async t => {
const response = await request(app)
.post(`/v1/provisioning/${DEVICE_ID}`)
.query({ access_token: userToken })
.send({ publicKey: TEST_PUBLIC_KEY });

deviceToApiAttributes = response.body;
t.is(response.status, 200);
t.is(response.body.id, DEVICE_ID);
});
// TODO write test for checking the error if publicKey is in wrong format.

test('should throw an error for compile source code endpoint', async t => {
const response = await request(app)
.post('/v1/binaries')
.query({ access_token: userToken });

t.is(response.status, 400);
t.is(response.body.error, 'not supported in the current server version');
});

test.serial('should return device details', async t => {
const response = await request(app)
.get(`/v1/devices/${DEVICE_ID}`)
.query({ access_token: userToken });

t.is(response.status, 200);
t.is(response.body.id, deviceToApiAttributes.id);
t.is(response.body.name, deviceToApiAttributes.name);
t.is(response.body.ownerID, deviceToApiAttributes.ownerID);
});

test.serial('should throw an error if device not found', async t => {
const response = await request(app)
.get(`/v1/devices/${DEVICE_ID}123`)
.query({ access_token: userToken });

t.is(response.status, 404);
t.is(response.body.error, 'No device found');
});

test.serial('should return all devices', async t => {
const response = await request(app)
.get('/v1/devices/')
.query({ access_token: userToken });

const devices = response.body;

t.is(response.status, 200);
t.truthy(Array.isArray(devices) && devices.length > 0);
});

test.serial('should unclaim device', async t => {
const unclaimResponse = await request(app)
.delete(`/v1/devices/${DEVICE_ID}`)
.query({ access_token: userToken });

t.is(unclaimResponse.status, 200);
t.is(unclaimResponse.body.ok, true);

const getDeviceResponse = await request(app)
.get(`/v1/devices/${DEVICE_ID}`)
.query({ access_token: userToken });

t.is(getDeviceResponse.status, 404);
});

test.serial('should claim device', async t => {
const claimDeviceResponse = await request(app)
.post('/v1/devices')
.set('Content-Type', 'application/x-www-form-urlencoded')
.send({
access_token: userToken,
id: DEVICE_ID,
});

t.is(claimDeviceResponse.status, 200);
t.is(claimDeviceResponse.body.ok, true);

const getDeviceResponse = await request(app)
.get(`/v1/devices/${DEVICE_ID}`)
.query({ access_token: userToken });

t.is(getDeviceResponse.status, 200);
});
// TODO write test for checking the error if device belongs to somebody else
// TODO write tests for updateDevice & callFunction

test.after.always(() => {
settings.usersRepository.deleteById(testUser.id);
settings.deviceAttributeRepository.deleteById(DEVICE_ID);
settings.deviceKeyFileRepository.delete(DEVICE_ID);
});
4 changes: 2 additions & 2 deletions test/UsersController.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import type { TokenObject, UserCredentials } from '../src/types';
import test from 'ava';
import request from 'supertest-as-promised';
import ouathClients from '../src/oauthClients.json';
import app from './testApp';
import settings from './settings';
import app from './setup/testApp';
import settings from './setup/settings';

const USER_CREDENTIALS: UserCredentials = {
password: 'password',
Expand Down
4 changes: 2 additions & 2 deletions test/WebhooksController.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import type { Webhook, WebhookMutator } from '../src/types';
import test from 'ava';
import request from 'supertest-as-promised';
import ouathClients from '../src/oauthClients.json';
import app from './testApp';
import settings from './settings';
import app from './setup/testApp';
import settings from './setup/settings';

const USER_CREDENTIALS = {
password: 'password',
Expand Down
36 changes: 0 additions & 36 deletions test/settings.js

This file was deleted.

11 changes: 11 additions & 0 deletions test/setup/DeviceServerMock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// @flow

import SparkCoreMock from './SparkCoreMock';

class DeviceServerMock {
getCore(): SparkCoreMock {
return new SparkCoreMock();
}
}

export default DeviceServerMock;
9 changes: 9 additions & 0 deletions test/setup/SparkCoreMock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// @flow

class SparkCoreMock {
onApiMessage() {
return true;
}
}

export default SparkCoreMock;
43 changes: 43 additions & 0 deletions test/setup/settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// @flow

import path from 'path';
import WebhookFileRepository from '../../src/lib/repository/WebhookFileRepository';
import UsersFileRepository from '../../src/lib/repository/UserFileRepository';
import { DeviceAttributeFileRepository, DeviceKeyFileRepository } from 'spark-protocol';

export default {
accessTokenLifetime: 7776000, // 90 days,
baseUrl: 'http://localhost',
coreFlashTimeout: 90000,
coreKeysDir: path.join(__dirname, '../__test_data__/core_keys'),
coreRequestTimeout: 30000,
coreSignalTimeout: 30000,
isCoreOnlineTimeout: 2000,
loginRoute: '/oauth/token',
logRequests: false,
maxHooksPerDevice: 10,
maxHooksPerUser: 20,
deviceAttributeRepository: new DeviceAttributeFileRepository(
path.join(__dirname, '../__test_data__/core_keys'),
),
deviceKeyFileRepository: new DeviceKeyFileRepository(
path.join(__dirname, '../__test_data__/core_keys'),
),
usersRepository: new UsersFileRepository(
path.join(__dirname, '../__test_data__/users'),
),
webhookRepository: new WebhookFileRepository(
path.join(__dirname, '../__test_data__/webhooks'),
),

/**
* Your server crypto keys!
*/
cryptoSalt: 'aes-128-cbc',
serverKeyFile: "default_key.pem",
serverKeyPassFile: null,
serverKeyPassEnvVar: null,

PORT: 5683,
HOST: "localhost",
};
10 changes: 10 additions & 0 deletions test/setup/testApp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// @flow

import createApp from '../../src/app';
import settings from './settings';
import DeviceServerMock from './DeviceServerMock';

const deviceServer = new DeviceServerMock();
const app = createApp(settings, deviceServer);

export default app;
8 changes: 0 additions & 8 deletions test/testApp.js

This file was deleted.

0 comments on commit 01c5b03

Please sign in to comment.