Skip to content
This repository has been archived by the owner on Jan 22, 2020. It is now read-only.

Add service detail view and increase test coverage. #37

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions local-dev/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.DS_Store
alerts/*.yml
build/
public/service-detail/*
node_modules/
31 changes: 31 additions & 0 deletions local-dev/src/__mocks__/alerts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const alerts = [
{
alertLogged: '2016-12-05-17-23-45-42',
alertOccurred: '2016-12-05-17-20-12-34',
description: 'The decline in spirograph and the rise in gang activity',
graph: 'https://frinkiac.com/img/S07E02/1108189.jpg',
link: 'https://frinkiac.com/episode/S07E02/1108189',
resolved: false,
severity: 'h'
},
{
alertLogged: '2016-12-17-16-53-12-23',
alertOccurred: '2016-12-17-12-30-12-34',
description: 'Disco record sales were up 400%',
graph: 'https://frinkiac.com/img/S08E11/288721.jpg',
link: 'https://frinkiac.com/episode/S08E11/290589',
resolved: true,
severity: 'l'
},
{
alertLogged: '2016-12-14-12-45-12-34',
alertOccurred: '2016-12-14-12-30-12-34',
description: 'As intelligence goes up, happiness often goes down',
graph: 'https://frinkiac.com/img/S12E09/1066440.jpg',
link: 'https://frinkiac.com/episode/S12E09/1066440',
resolved: false,
severity: 'm'
}
];

export default alerts;
16 changes: 16 additions & 0 deletions local-dev/src/__mocks__/isomorphic-fetch.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import newGlobalStatusData from './newGlobalStatusData';
import newServiceDetailData from './newServiceDetailData';

export default function fetch(url, options) {
return new Promise((resolve, reject) => {
// global status polling
if (url.indexOf('status.yml') > -1) {
resolve({
ok: true,
Expand All @@ -15,6 +17,20 @@ export default function fetch(url, options) {
});
}
});
// service detail polling
} else if (url.indexOf('service-detail/') > -1) {
resolve({
ok: true,
status: 200,
statusText: 'OK',
text: function () {
return new Promise((resolve, reject) => {
// we're mocking jsyaml in actionCreators.test.js,
// so we can just pass back JSON here
resolve(JSON.stringify(newServiceDetailData));
});
}
});
} else {
// generic handler - not used at the moment
resolve({
Expand Down
23 changes: 23 additions & 0 deletions local-dev/src/__mocks__/newServiceDetailData.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// What our YAML looks like after being JSON-ified
const newServiceDetailData = {
'2016_12_17_11_53_12_34': {
description: 'First test alert',
graph: 'https://www.mozilla.org/',
link: 'https://twitter.com/search?q=%23mozaloha&src=typd',
resolved: false,
severity: '1',
time: '2016_12_17_12_30_12_34'
},
'2016_12_14_16_53_12_34': {
description: 'Second test alert',
graph: 'https://www.mozilla.org/',
link: 'https://twitter.com/search?q=%23mozaloha&src=typd',
resolved: true,
severity: '1',
time: '2016_12_14_12_30_12_34'
},
lastUpdate: '2016_12_17_20_01_11_22',
message: 'Service data updated.'
}

export default newServiceDetailData;
43 changes: 43 additions & 0 deletions local-dev/src/__mocks__/services.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const services = [
{
display: true,
group: 'group1',
hasDetail: false,
id: 1,
link: 'test link',
name: 'test service 1',
order: 1,
status: 'healthy'
},
{
display: true,
hasDetail: true,
id: 2,
link: 'test link',
name: 'test service 2',
order: 2,
status: 'healthy'
},
{
display: true,
group: 'group1',
hasDetail: false,
id: 3,
link: 'test link',
name: 'test service 3',
order: 3,
status: 'warning'
},
{
display: true,
group: 'group2',
hasDetail: false,
id: 4,
link: 'test link',
name: 'test service 4',
order: 10,
status: 'healthy'
}
];

export default services;
57 changes: 0 additions & 57 deletions local-dev/src/__tests__/GlobalStatus.test.js

This file was deleted.

23 changes: 0 additions & 23 deletions local-dev/src/__tests__/__snapshots__/GlobalStatus.test.js.snap

This file was deleted.

56 changes: 56 additions & 0 deletions local-dev/src/__tests__/actionCreators.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as actions from '../actions/actionCreators';
import jsyaml from 'js-yaml';

import newGlobalStatusData from '../__mocks__/newGlobalStatusData';
import newServiceDetailData from '../__mocks__/newServiceDetailData';

import { buildNewGlobalStatusObject } from '../helpers';

Expand Down Expand Up @@ -34,6 +35,25 @@ describe('async actions', () => {
});
});

test('fetchServiceDetail should dispatch both requestServiceDetail and receiveStatusDetail actions', () => {
// Mock jsYaml.load to just convert string to JSON.
// (No YAML has been used in this test.)
jsyaml.load = jest.fn(data => JSON.parse(data));

// A mock store for receiving/holding the dispatched actions.
const store = mockStore();

// These are the actions we expect to be dispatched from fetchGlobalStatus.
const expectedActions = [
{ type: actions.REQUEST_SERVICE_DETAIL },
{ type: actions.RECEIVE_SERVICE_DETAIL, data: newServiceDetailData }
];

return store.dispatch(actions.fetchServiceDetail()).then(() => {
expect(store.getActions()).toEqual(expectedActions);
});
});

describe('requestDesktopNotify should dispatch receiveDesktopNotify', () => {
test('should return false when Notification API is not available', () => {
// Make sure Notification API is not available.
Expand Down Expand Up @@ -159,6 +179,42 @@ describe('actions', () => {
expect(actions.receiveGlobalStatus(newGlobalData)).toEqual(expectedAction);
});

test('requestServiceDetail should create an action with type REQUEST_SERVICE_DETAIL', () => {
const expectedAction = {
type: actions.REQUEST_SERVICE_DETAIL
};

expect(actions.requestServiceDetail()).toEqual(expectedAction);
});

test('receiveServiceDetail should create an action containing type RECEIVE_STATUS_DETAIL and object of service detail data', () => {
const newServiceDetailData = {
'date_1': {
resolved: true,
severity: 'l'
},
'date_2': {
resolved: false,
severity: 'h'
}
};

const expectedAction = {
type: actions.RECEIVE_SERVICE_DETAIL,
data: newServiceDetailData
}

expect(actions.receiveServiceDetail(newServiceDetailData)).toEqual(expectedAction);
});

test('resetServiceDetail should create an action with type RESET_SERVICE_DETAIL', () => {
const expectedAction = {
type: actions.RESET_SERVICE_DETAIL
};

expect(actions.resetServiceDetail()).toEqual(expectedAction);
});

test('receiveDesktopNotify should create an action containing type RECEIVE_DESKTOP_NOTIFY and boolean user response', () => {
const userResponse = true;

Expand Down
77 changes: 77 additions & 0 deletions local-dev/src/__tests__/components/GlobalStatus.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import React from 'react';
import renderer from 'react-test-renderer';

import GlobalStatus from '../../components/GlobalStatus';

const mockClearDesktopNotify = jest.fn();

describe('render GlobalStatus', () => {
test('renders a healthy GlobalStatus', () => {
const component = renderer.create(
<GlobalStatus status='healthy'
message='test'
notifyMessage={false}
desktopNotify={false}
clearDesktopNotify={mockClearDesktopNotify} />
);

let tree = component.toJSON();
expect(tree).toMatchSnapshot();
});

test('renders a warning GlobalStatus', () => {
const component = renderer.create(
<GlobalStatus status='healthy'
message='test'
notifyMessage={false}
desktopNotify={false}
clearDesktopNotify={mockClearDesktopNotify} />
);

let tree = component.toJSON();
expect(tree).toMatchSnapshot();
});

test('renders a failed GlobalStatus', () => {
const component = renderer.create(
<GlobalStatus status='healthy'
message='test'
notifyMessage={false}
desktopNotify={false}
clearDesktopNotify={mockClearDesktopNotify} />
);

let tree = component.toJSON();
expect(tree).toMatchSnapshot();
});

test('renders a pending GlobalStatus', () => {
const component = renderer.create(
<GlobalStatus status='healthy'
message='test'
notifyMessage={false}
desktopNotify={false}
clearDesktopNotify={mockClearDesktopNotify} />
);

let tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
});

test('GlobalStatus sends a desktop notification', () => {
// tests can't actually send a desktop notification
GlobalStatus.prototype.sendDesktopNotification = jest.fn(() => true);
// tests don't like looking for file paths, so we create a predictable stub
GlobalStatus.prototype.statusToIcon = jest.fn(() => 'stub');

const component = renderer.create(
<GlobalStatus status='healthy'
message='playtime is fun'
notifyMessage={true}
desktopNotify={true}
clearDesktopNotify={mockClearDesktopNotify} />
);

expect(GlobalStatus.prototype.sendDesktopNotification).toHaveBeenCalledWith('playtime is fun', 'stub');
});
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react';
import renderer from 'react-test-renderer';

import ServiceSummary from '../components/ServiceSummary';
import ServiceSummary from '../../components/ServiceSummary';

test('service summary', () => {
test('render ServiceSummary', () => {
const component = renderer.create(
<ServiceSummary status='healthy' name='police cops'/>
);
Expand Down
Loading