Use fetch-mock to mock requests in tests (#18)

* Use fetch-mock to mock requests in tests

* Use flag to enable/disable fetch-mock
This commit is contained in:
Thomas Hopkins 2016-10-17 11:37:18 -07:00 committed by Harrison Healey
parent ce9dbcfb16
commit 8611b3e28a
6 changed files with 213 additions and 4 deletions

View file

@ -18,6 +18,7 @@
"babel-register": "6.16.3",
"eslint": "3.7.1",
"eslint-plugin-react": "6.3.0",
"fetch-mock": "5.5.0",
"mocha": "3.1.0",
"react-native-mock": "0.2.7",
"react-test-renderer": "15.3.2",

View file

@ -247,7 +247,11 @@ export default class Client {
try {
const response = await fetch(url, this.getOptions(options));
const data = await response.json();
return response.ok ? onSuccess(data, response) : Promise.reject(data);
if (response.ok) {
return onSuccess(data, response);
}
const {message} = data;
throw new Error(message || 'Failed to fetch');
} catch (err) {
if (this.logToConsole) {
console.log(err); // eslint-disable-line no-console

View file

@ -2,9 +2,38 @@
// See License.txt for license information.
import assert from 'assert';
import fetchMock from 'fetch_mock';
import TestHelper from 'test_helper.js';
const fakeNotFoundResp = {
status: 404,
body: {
id: 'api.context.404.app_error',
message: 'Sorry, we could not find the page.',
detailed_error: [
"There doesn't appear to be an api call for the url='/api/v3/fake/url/general/ping'.",
'Typo? are you missing a team_id or user_id as part of the url?'
].join(' '),
status_code: 404
}
};
fetchMock.get(/\/ping/, (url) => {
if (url.match(/\/fake\/url/)) {
return fakeNotFoundResp;
}
return {
server_time: `${Date.now()}`,
version: '3.4.0'
};
});
fetchMock.post(/\/log_client/, {
status: 200,
headers: {'Content-Type': 'application/json'},
body: {status: 'OK'}
});
describe('Client', () => {
it('doFetch', (done) => {
const client = TestHelper.createClient();

20
test/fetch_mock.js Normal file
View file

@ -0,0 +1,20 @@
/* eslint-disable no-empty-function */
// set this to false to allow requests to server in test suite
const MOCK_FETCH = false;
let fetchMock = {
mock: () => {},
delete: () => {},
get: () => {},
head: () => {},
patch: () => {},
post: () => {},
put: () => {}
};
if (MOCK_FETCH) {
fetchMock = require('fetch-mock');
}
export default fetchMock;

View file

@ -2,6 +2,11 @@
// See License.txt for license information.
import 'react-native';
import fetchMock from 'fetch_mock';
fetchMock.get('http://example.com', {
status: 200
});
// Ensure that everything is imported correctly for testing
describe('Sanity test', () => {
@ -20,4 +25,4 @@ describe('Sanity test', () => {
done.fail(err);
});
});
});
});

View file

@ -2,10 +2,160 @@
// See License.txt for license information.
import assert from 'assert';
import fetchMock from 'fetch_mock';
import Client from 'client/client.js';
import Config from 'config/config.js';
const fakeUserId = '146677bbcefgjjmmnpqqrruxyz';
const fakeTeamId = '1378899bbcddefghknnpqsttyz';
const fakeChannelId = '1335568899aaccefkkmmpprtwz';
const fakePostId = '346aabceeffhhikopruuwxyyyy';
const fakeTimestamp = Date.now();
const fakeTeamRespBody = {
id: fakeTeamId,
create_at: fakeTimestamp,
update_at: fakeTimestamp,
delete_at: 0,
display_name: `est-eam-${fakeTimestamp}`,
name: `est-eam-${fakeTimestamp}`,
email: '',
type: 'O',
company_name: '',
allowed_domains: '',
invite_id: '',
allow_open_invite: false
};
const fakeChannelRespBody = {
id: fakeChannelId,
create_at: fakeTimestamp,
update_at: fakeTimestamp,
delete_at: 0,
team_id: fakeTeamId,
type: 'O',
display_name: 'bestchannel',
name: 'bestchannel',
header: '',
purpose: '',
last_post_at: 0,
total_msg_count: 0,
extra_update_at: fakeTimestamp,
creator_id: fakeUserId
};
const fakePostRespBody = {
id: fakePostId,
create_at: fakeTimestamp,
update_at: fakeTimestamp,
delete_at: 0,
user_id: fakeUserId,
channel_id: fakeChannelId,
root_id: '',
parent_id: '',
original_id: '',
message: 'TEST POST',
type: '',
props: {},
hashtags: '',
pending_post_id: ''
};
const fakeUserRespBody = {
id: fakeUserId,
create_at: fakeTimestamp,
update_at: fakeTimestamp,
delete_at: 0,
username: 'testuser',
auth_data: '',
auth_service: '',
email: 'testuser',
nickname: '',
first_name: '',
last_name: '',
roles: 'system_user',
allow_marketing: true,
notify_props: {
channel: 'true',
desktop: 'all',
desktop_sound: 'true',
email: 'true',
first_name: 'false',
mention_keys: 'testuser,@testuser',
push: 'mention'
},
last_password_update: fakeTimestamp,
locale: 'en'
};
const fakeClientConfig = {
Version: '3.4.0',
BuildNumber: 'dev',
BuildDate: 'Wed Dec 14 23:59:59 UTC 2016',
BuildHash: '01111123555566677788888888abbbbcccccdeff'
};
const fakeInitLoadRespBody = {
user: fakeUserRespBody,
team_members: [{
team_id: fakeTeamId,
user_id: fakeUserId,
roles: 'team_user team_admin',
delete_at: 0
}],
teams: [fakeTeamRespBody],
direct_profiles: {},
preferences: [{
user_id: fakeUserId,
category: 'last',
name: 'channel',
value: fakeChannelId
}, {
user_id: fakeUserId,
category: 'tutorial_step',
name: fakeUserId,
value: '1'
}],
client_cfg: fakeClientConfig,
license_cfg: {
IsLicensed: 'false'
},
no_accounts: false
};
fetchMock.post(/\/users\/create$/, (url, opts) => ({
headers: {'Content-Type': 'application/json'},
body: {...fakeUserRespBody, ...JSON.parse(opts.body)}
}));
fetchMock.post(/\/users\/login$/, (url, opts) => {
const reqBody = JSON.parse(opts.body);
return {
headers: {
'Content-Type': 'application/json',
token: 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
},
body: {...fakeUserRespBody,
...reqBody,
email: reqBody.login_id
}
};
});
fetchMock.post(/\/teams\/create/, (url, opts) => ({
headers: {'Content-Type': 'application/json'},
body: {...fakeTeamRespBody, ...JSON.parse(opts.body)}
}));
fetchMock.post(/\/channels\/create/, (url, opts) => ({
headers: {'Content-Type': 'application/json'},
body: {...fakeChannelRespBody, ...JSON.parse(opts.body)}
}));
fetchMock.post(/\/posts\/create$/, {
headers: {'Content-Type': 'application/json'},
body: fakePostRespBody
});
fetchMock.get(/\/users\/initial_load$/, {
headers: {'Content-Type': 'application/json'},
body: fakeInitLoadRespBody
});
fetchMock.get(/\/general\/client_props$/, {
headers: {'Content-Type': 'application/json'},
body: fakeClientConfig
});
const PASSWORD = 'password1';
class TestHelper {