From e4d25b25a4dedc9987410725bbbb919fbf36400f Mon Sep 17 00:00:00 2001 From: Anton Tiptyuk Date: Wed, 25 Jan 2017 14:48:36 +0200 Subject: [PATCH 1/5] secure flow of .env params configured --- .env_test | 5 +++++ .example.env | 11 +++++------ .example.env_test | 4 ++++ config/env.js | 9 ++++++--- config/gonebusy_env.js | 38 ++++++++++++++++++++------------------ scripts/start.js | 10 +++++----- scripts/test.js | 8 +++++++- src/lib/BusyAdapter.js | 7 +------ 8 files changed, 53 insertions(+), 39 deletions(-) create mode 100644 .env_test create mode 100644 .example.env_test diff --git a/.env_test b/.env_test new file mode 100644 index 0000000..09a3af9 --- /dev/null +++ b/.env_test @@ -0,0 +1,5 @@ +REACT_APP_API_ENDPOINT="http://sandbox.gonebusy.com/api/v1" +REACT_APP_API_ENDPOINT="v1" +REACT_APP_TOKEN="Token af9094c6d46658e60cde12e34ad26979" + +CI="true" diff --git a/.example.env b/.example.env index 8c10d90..de52b4a 100644 --- a/.example.env +++ b/.example.env @@ -1,6 +1,5 @@ -REACT_APP_SERVICE_ID=7891245607 -REACT_APP_GONEBUSY_TOKEN="Token af9094c6d46658e60cde12e34ad26979" -REACT_APP_API_HOST="http://sandbox.gonebusy.com" -REACT_APP_API_PATH="/api/v1" -REACT_APP_IS_PROXIED="true" -REACT_APP_PROXY_HOST="http://localhost:3000" +GONEBUSY_TOKEN="Token af9094c6d46658e60cde12e34ad26979" +GONEBUSY_API_HOST="http://sandbox.gonebusy.com" +GONEBUSY_API_PATH="/api/v1" +GONEBUSY_IS_PROXIED="true" +GONEBUSY_PROXY_HOST="http://localhost:3000" diff --git a/.example.env_test b/.example.env_test new file mode 100644 index 0000000..88110ea --- /dev/null +++ b/.example.env_test @@ -0,0 +1,4 @@ +REACT_APP_API_ENDPOINT="http://sandbox.gonebusy.com/api/v1" +REACT_APP_TOKEN="Token af9094c6d46658e60cde12e34ad26979" + +CI="true" diff --git a/config/env.js b/config/env.js index 5d0ab7b..383b9fe 100644 --- a/config/env.js +++ b/config/env.js @@ -2,19 +2,22 @@ // injected into the application via DefinePlugin in Webpack configuration. var REACT_APP = /^REACT_APP_/i; +var clientParams = require('./gonebusy_env').client; function getClientEnvironment(publicUrl) { + var envData = Object.assign({}, process.env, clientParams); + var processEnv = Object - .keys(process.env) + .keys(envData) .filter(key => REACT_APP.test(key)) .reduce((env, key) => { - env[key] = JSON.stringify(process.env[key]); + env[key] = JSON.stringify(envData[key]); return env; }, { // Useful for determining whether we’re running in production mode. // Most importantly, it switches React into the correct mode. 'NODE_ENV': JSON.stringify( - process.env.NODE_ENV || 'development' + envData.NODE_ENV || 'development' ), // Useful for resolving the correct path to static assets in `public`. // For example, . diff --git a/config/gonebusy_env.js b/config/gonebusy_env.js index b467b7e..113b824 100644 --- a/config/gonebusy_env.js +++ b/config/gonebusy_env.js @@ -1,26 +1,28 @@ const url = require('url'); const env = process.env; -const reactAppServiceId = env['REACT_APP_SERVICE_ID']; -const reactAppGonebusyToken = env['REACT_APP_GONEBUSY_TOKEN']; -const gonebusyApiHost = env['REACT_APP_API_HOST']; -const gonebusyApiPath = env['REACT_APP_API_PATH']; -const gonebusyIsProxied = env['REACT_APP_IS_PROXIED']; -const gonebusyProxyHost = env['REACT_APP_PROXY_HOST']; -const is_proxied = !!(gonebusyIsProxied && JSON.parse(gonebusyIsProxied)); +const envToken = env['GONEBUSY_TOKEN']; +const envApiHost = env['GONEBUSY_API_HOST']; +const envApiPath = env['GONEBUSY_API_PATH']; +const envIsProxied = env['GONEBUSY_IS_PROXIED']; +const envProxyHost = env['GONEBUSY_PROXY_HOST']; -const clientApiEndpoint = url.resolve((is_proxied ? gonebusyProxyHost : gonebusyApiHost) || '', gonebusyApiPath); -const clientToken = is_proxied ? 'none' : reactAppGonebusyToken; -const middlewareProxyHost = is_proxied ? gonebusyApiHost : undefined; -const middlewareToken = is_proxied ? reactAppGonebusyToken : undefined; +const is_proxied = !!(envIsProxied && JSON.parse(envIsProxied)); -console.log("to change the way we process .env so that it won't appear in plain JS", is_proxied); +const clientApiEndpoint = url.resolve((is_proxied ? envProxyHost : envApiHost) || '', envApiPath); +const clientToken = is_proxied ? 'none' : envToken; + +const middlewareProxyHost = is_proxied ? envApiHost : undefined; +const middlewareToken = is_proxied ? envToken : undefined; module.exports = { - service_id: reactAppServiceId, - clientApiEndpoint, - clientToken, - middlewareProxyHost, - middlewarePath: gonebusyApiPath, - middlewareToken, + client: { + REACT_APP_API_ENDPOINT: clientApiEndpoint, + REACT_APP_TOKEN: clientToken + }, + middleware: { + proxy: middlewareProxyHost, + path: envApiPath, + token: middlewareToken + } }; diff --git a/scripts/start.js b/scripts/start.js index 1336e60..480f7ea 100644 --- a/scripts/start.js +++ b/scripts/start.js @@ -156,10 +156,10 @@ function addMiddleware(devServer) { // `proxy` lets you to specify a fallback server during development. // Every unrecognized request will be forwarded to it. - const gonebusy_env = require('../config/gonebusy_env'); - const proxy = gonebusy_env['middlewareProxyHost']; - const token = gonebusy_env['middlewareToken']; - const middlewarePath = gonebusy_env['middlewarePath']; + var envParams = require('../config/gonebusy_env').middleware; + var proxy = envParams.proxy; + var token = envParams.token; + var apiPath = envParams.path; devServer.use(historyApiFallback({ // Paths with dots should still use the history fallback. @@ -192,7 +192,7 @@ function addMiddleware(devServer) { // Tip: use https://jex.im/regulex/ to visualize the regex // var mayProxy = /^(?!\/(index\.html$|.*\.hot-update\.json$|sockjs-node\/)).*$/; // var mayProxy = /^\/api.*$/; - var mayProxy = new RegExp('^' + middlewarePath + '.*$'); + var mayProxy = new RegExp('^' + apiPath + '.*$'); // Pass the scope regex both to Express and to the middleware for proxying // of both HTTP and WebSockets to work without false positives. diff --git a/scripts/test.js b/scripts/test.js index c4dc347..6a78928 100644 --- a/scripts/test.js +++ b/scripts/test.js @@ -5,13 +5,19 @@ process.env.PUBLIC_URL = ''; // if this file is missing. dotenv will never modify any environment variables // that have already been set. // https://github.com/motdotla/dotenv -require('dotenv').config({silent: true}); +require('dotenv').config({ + silent: true, + path: './.env_test' +}); const jest = require('jest'); const argv = process.argv.slice(2); +// console.log(process.env); + // Watch unless on CI or in coverage mode if (!process.env.CI && argv.indexOf('--coverage') < 0) { + console.log('got inside'); argv.push('--watch'); } diff --git a/src/lib/BusyAdapter.js b/src/lib/BusyAdapter.js index 4bb690d..29d73ae 100644 --- a/src/lib/BusyAdapter.js +++ b/src/lib/BusyAdapter.js @@ -2,15 +2,10 @@ import gonebusy, { CreateBookingBody } from 'gonebusy-nodejs-client/lib'; import { Promise } from 'bluebird'; import Scheduler from './Scheduler'; -import gonebusyEnv from '../../config/gonebusy_env'; - const ServicesController = Promise.promisifyAll(gonebusy.ServicesController); const BookingsController = Promise.promisifyAll(gonebusy.BookingsController); -const { - clientToken: authorization, - clientApiEndpoint -} = gonebusyEnv; +const { REACT_APP_TOKEN: authorization, REACT_APP_API_ENDPOINT: clientApiEndpoint } = process.env; gonebusy.configuration.BASEURI = clientApiEndpoint; From 51d0a3c51e4acd687b6abd1b3ed8eeb299de5155 Mon Sep 17 00:00:00 2001 From: Anton Tiptyuk Date: Thu, 26 Jan 2017 14:59:21 +0200 Subject: [PATCH 2/5] tests introduced; zero-approximation --- package.json | 2 + scripts/start.js | 4 +- src/__tests__sample/Bookie.js | 19 ++ src/components/.env_test | 5 + src/components/Bookie.jsx | 2 +- src/components/Bookie.test.jsx | 66 +++++++ .../__snapshots__/Bookie.test.jsx.snap | 156 ++++++++++++++++ src/components/cut_response.js | 172 ++++++++++++++++++ src/lib/Scheduler.js | 8 +- src/lib/StateUpdaterForDatePicker.js | 4 +- 10 files changed, 431 insertions(+), 7 deletions(-) create mode 100644 src/__tests__sample/Bookie.js create mode 100644 src/components/.env_test create mode 100644 src/components/Bookie.test.jsx create mode 100644 src/components/__snapshots__/Bookie.test.jsx.snap create mode 100644 src/components/cut_response.js diff --git a/package.json b/package.json index b9b09b4..2755c98 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,9 @@ "path-exists": "2.1.0", "postcss-loader": "1.0.0", "promise": "7.1.1", + "react-addons-test-utils": "^15.4.2", "react-dev-utils": "^0.4.2", + "react-test-renderer": "^15.4.2", "recursive-readdir": "2.1.0", "strip-ansi": "3.0.1", "style-loader": "0.13.1", diff --git a/scripts/start.js b/scripts/start.js index 480f7ea..ecb236b 100644 --- a/scripts/start.js +++ b/scripts/start.js @@ -204,13 +204,13 @@ function addMiddleware(devServer) { proxyReq.setHeader('authorization', token); console.log(`requested: [${req.method}] ${req.url}`); console.log('query:', req.query); - console.log('-\n'); + console.log('-'); }, onProxyRes: (proxyRes, req, res) => { proxyRes.on('data', (chunk) => { console.log(`response for: [${req.method}] ${req.url}`); console.log((new StringDecoder('utf8')).write(chunk)); - console.log('-\n'); + console.log('-'); }); }, // pathRewrite: { diff --git a/src/__tests__sample/Bookie.js b/src/__tests__sample/Bookie.js new file mode 100644 index 0000000..23a4522 --- /dev/null +++ b/src/__tests__sample/Bookie.js @@ -0,0 +1,19 @@ +jest.dontMock('../Bookie.jsx'); + +describe('Bookie', function () { + var React = require('react'); + var ReactDOM = require('react-dom'); + var TestUtils = require('react-addons-test-utils'); + + var Bookie; + + beforeEach(function () { + Bookie = require('../Bookie').default; + }); + + it('should exists', function () { + // Render into document + var bookie = TestUtils.renderIntoDocument(); + expect(TestUtils.isCompositeComponent(bookie)).toBeTruthy(); + }); +}); \ No newline at end of file diff --git a/src/components/.env_test b/src/components/.env_test new file mode 100644 index 0000000..09a3af9 --- /dev/null +++ b/src/components/.env_test @@ -0,0 +1,5 @@ +REACT_APP_API_ENDPOINT="http://sandbox.gonebusy.com/api/v1" +REACT_APP_API_ENDPOINT="v1" +REACT_APP_TOKEN="Token af9094c6d46658e60cde12e34ad26979" + +CI="true" diff --git a/src/components/Bookie.jsx b/src/components/Bookie.jsx index 6640abf..023e9aa 100644 --- a/src/components/Bookie.jsx +++ b/src/components/Bookie.jsx @@ -75,7 +75,7 @@ class Bookie extends Component { pickerUpdater.adjust(); if (setLoading) this.setParentLoading(pickerUpdater.state().loading); - console.log('applying diff', diff, pickerUpdater.diff()); + // console.log('applying diff', diff, pickerUpdater.diff()); this.setState(pickerUpdater.diff(), () => { this.pullMissingData(); }); } } diff --git a/src/components/Bookie.test.jsx b/src/components/Bookie.test.jsx new file mode 100644 index 0000000..904cd2b --- /dev/null +++ b/src/components/Bookie.test.jsx @@ -0,0 +1,66 @@ +const React = require('react'); +const ReactDOM = require('react-dom'); +import ReactDOMServer from 'react-dom/server'; + +const TestUtils = require('react-addons-test-utils'); +const Bookie = require('./Bookie').default; +const renderer = require('react-test-renderer'); + +const Scheduler = require('../lib/Scheduler').default; +const moment = require('moment'); + +Scheduler.getCurrentMoment = (() => moment('2017-01-02 17:00')); + +it('should exists', () => { + const bookie = TestUtils.renderIntoDocument(); + expect(TestUtils.isCompositeComponent(bookie)).toBeTruthy(); +}); + +it('markup matches snapshot', () => { + const tree = renderer.create().toJSON(); + expect(tree).toMatchSnapshot(); +}); + +describe('enabling bookie button', () => { + // there's a gap on 2017-01-01 at 17:00-18:00 + const savedState = require('./cut_response'); + + const createBookieWithState = function(state) { + const result = TestUtils.renderIntoDocument(); + result.setState(state); + result.negotiateStateDiff({}, true); + return result; + } + + it('is enabled for valid range', () => { + const bookieComponent = createBookieWithState(savedState); + + // ensure booking is enabled in state + expect(bookieComponent.state.bookingAllowed).toBe(true); + + // ensure booking button is enabled + expect(ReactDOM.findDOMNode(bookieComponent).querySelector('button').disabled).toBe(false); + + // check markup snapshot + const reactElement = bookieComponent.render(); + const renderedMarkup = ReactDOMServer.renderToStaticMarkup(reactElement); + expect(renderedMarkup).toMatchSnapshot(); + }); + + it('is disabled for the range with a gap', () => { + const state = Object.assign({}, savedState, { + "hourPicked": 16, + "minutesIdxPicked": 2, + "endVal": "2017-01-01T18:15:00+02:00", + }); + + const bookieComponent = createBookieWithState(state); + + expect(bookieComponent.state.bookingAllowed).toBe(false); + expect(ReactDOM.findDOMNode(bookieComponent).querySelector('button').disabled).toBe(true); + + const reactElement = bookieComponent.render(); + const renderedMarkup = ReactDOMServer.renderToStaticMarkup(reactElement); + expect(renderedMarkup).toMatchSnapshot(); + }); +}); \ No newline at end of file diff --git a/src/components/__snapshots__/Bookie.test.jsx.snap b/src/components/__snapshots__/Bookie.test.jsx.snap new file mode 100644 index 0000000..e4dcda2 --- /dev/null +++ b/src/components/__snapshots__/Bookie.test.jsx.snap @@ -0,0 +1,156 @@ +exports[`enabling bookie button is disabled for the range with a gap 1`] = `""`; + +exports[`enabling bookie button is enabled for valid range 1`] = `""`; + +exports[`test markup matches snapshot 1`] = ` +
+ + + +
+ + choose start + + +  —  + + + choose end + +
+
+ +
+
+`; diff --git a/src/components/cut_response.js b/src/components/cut_response.js new file mode 100644 index 0000000..4c72d2e --- /dev/null +++ b/src/components/cut_response.js @@ -0,0 +1,172 @@ +module.exports = { + "initialized": true, + "loading": false, + "daysFrameStart": "2017-01-01", + "dayPicked": "2017-01-01", + "hourPicked": 18, + "minutesIdxPicked": 1, + "daysToFetch": [], + "dayData": { + "2017-01-01": { + "presentSlots": { + "9": [ + 0, + 15, + 30, + 45 + ], + "10": [ + 0, + 15, + 30, + 45 + ], + "11": [ + 0, + 15, + 30, + 45 + ], + "12": [ + 0, + 15, + 30, + 45 + ], + "13": [ + 0, + 15, + 30, + 45 + ], + "14": [ + 0, + 15, + 30, + 45 + ], + "15": [ + 0, + 15, + 30, + 45 + ], + "16": [ + 0, + 15, + 30, + 45 + ], + "18": [ + 0, + 15, + 30, + 45 + ], + "19": [ + 0, + 15, + 30, + 45 + ] + }, + "presentHours": [ + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 18, + 19 + ] + }, + "2017-01-02": { + "presentSlots": { + "9": [ + 0, + 15, + 30, + 45 + ], + "10": [ + 0, + 15, + 30, + 45 + ], + "11": [ + 0, + 15, + 30, + 45 + ], + "12": [ + 0, + 15, + 30, + 45 + ], + "13": [ + 0, + 15, + 30, + 45 + ], + "14": [ + 0, + 15, + 30, + 45 + ], + "15": [ + 0, + 15, + 30, + 45 + ], + "16": [ + 0, + 15, + 30, + 45 + ], + "17": [ + 0, + 15, + 30, + 45 + ], + "18": [ + 0, + 15, + 30, + 45 + ], + "19": [ + 0, + 15, + 30, + 45 + ] + }, + "presentHours": [ + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19 + ] + } + }, + "startVal": "2017-01-01T18:15:00+02:00", + "endVal": "2017-01-01T19:00:00+02:00", +}; diff --git a/src/lib/Scheduler.js b/src/lib/Scheduler.js index a3de043..eec816d 100644 --- a/src/lib/Scheduler.js +++ b/src/lib/Scheduler.js @@ -21,6 +21,10 @@ moment.updateLocale(moment.locale(), { }); class Scheduler { + static getCurrentMoment() { + return moment(); + } + static getDaysFrame(frameStartDate) { const mbase = moment.utc(frameStartDate); const result = []; @@ -80,7 +84,7 @@ class Scheduler { } static getNowStr() { - return moment().startOf('minute').format(); + return Scheduler.getCurrentMoment().startOf('minute').format(); } static getNextDayString(date) { @@ -102,7 +106,7 @@ class Scheduler { let result = ''; if (dateStr) { const mVal = moment(dateStr); - const mToday = moment(); + const mToday = Scheduler.getCurrentMoment(); if (formatDayToString(mToday) === formatDayToString(mVal)) result = mVal.format('ha:mm'); else if (mToday.year() === mVal.year()) diff --git a/src/lib/StateUpdaterForDatePicker.js b/src/lib/StateUpdaterForDatePicker.js index 0a1cb51..52d10b8 100644 --- a/src/lib/StateUpdaterForDatePicker.js +++ b/src/lib/StateUpdaterForDatePicker.js @@ -257,8 +257,8 @@ class StateUpdaterForDatePicker extends StateUpdaterBase { gapFound = !dayData || !dayData.presentSlots[hour] || !~dayData.presentSlots[hour].indexOf(qMinIdx * 15); - if (gapFound) - console.log('gap found', nextMomentStr); + // if (gapFound) + // console.log('gap found', nextMomentStr); } while (!gapFound && Scheduler.isAfterMin(day, hour, qMinIdx * 15, endVal)); bookingAllowed = !gapFound; } From a72f9adb47db9b99fec54b0dd2b5d67e4b1476e4 Mon Sep 17 00:00:00 2001 From: Anton Tiptyuk Date: Fri, 27 Jan 2017 10:43:27 +0200 Subject: [PATCH 3/5] dummy test data m0ved --- src/components/{cut_response.js => Bookie.test.data.js} | 6 +++++- src/components/Bookie.test.jsx | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) rename src/components/{cut_response.js => Bookie.test.data.js} (98%) diff --git a/src/components/cut_response.js b/src/components/Bookie.test.data.js similarity index 98% rename from src/components/cut_response.js rename to src/components/Bookie.test.data.js index 4c72d2e..a4e4ede 100644 --- a/src/components/cut_response.js +++ b/src/components/Bookie.test.data.js @@ -1,4 +1,4 @@ -module.exports = { +const savedState = { "initialized": true, "loading": false, "daysFrameStart": "2017-01-01", @@ -170,3 +170,7 @@ module.exports = { "startVal": "2017-01-01T18:15:00+02:00", "endVal": "2017-01-01T19:00:00+02:00", }; + +module.exports = { + savedState +}; diff --git a/src/components/Bookie.test.jsx b/src/components/Bookie.test.jsx index 904cd2b..3ccadcd 100644 --- a/src/components/Bookie.test.jsx +++ b/src/components/Bookie.test.jsx @@ -23,7 +23,7 @@ it('markup matches snapshot', () => { describe('enabling bookie button', () => { // there's a gap on 2017-01-01 at 17:00-18:00 - const savedState = require('./cut_response'); + const savedState = require('./Bookie.test.data').savedState; const createBookieWithState = function(state) { const result = TestUtils.renderIntoDocument(); From 299b78819790b87d54209022602da475c46db68c Mon Sep 17 00:00:00 2001 From: Anton Tiptyuk Date: Fri, 27 Jan 2017 11:26:08 +0200 Subject: [PATCH 4/5] with mocks --- .env_test | 4 - .example.env_test | 3 - src/components/.env_test | 5 - src/components/App.test.jsx | 6 + src/components/Bookie.test.jsx | 10 +- .../__snapshots__/Bookie.test.jsx.snap | 153 ------------------ src/lib/__mocks__/BusyAdapter.js | 20 +++ src/lib/__mocks__/BusyAdapter.test.data.js | 101 ++++++++++++ 8 files changed, 133 insertions(+), 169 deletions(-) delete mode 100644 src/components/.env_test create mode 100644 src/lib/__mocks__/BusyAdapter.js create mode 100644 src/lib/__mocks__/BusyAdapter.test.data.js diff --git a/.env_test b/.env_test index 09a3af9..851861a 100644 --- a/.env_test +++ b/.env_test @@ -1,5 +1 @@ -REACT_APP_API_ENDPOINT="http://sandbox.gonebusy.com/api/v1" -REACT_APP_API_ENDPOINT="v1" -REACT_APP_TOKEN="Token af9094c6d46658e60cde12e34ad26979" - CI="true" diff --git a/.example.env_test b/.example.env_test index 88110ea..851861a 100644 --- a/.example.env_test +++ b/.example.env_test @@ -1,4 +1 @@ -REACT_APP_API_ENDPOINT="http://sandbox.gonebusy.com/api/v1" -REACT_APP_TOKEN="Token af9094c6d46658e60cde12e34ad26979" - CI="true" diff --git a/src/components/.env_test b/src/components/.env_test deleted file mode 100644 index 09a3af9..0000000 --- a/src/components/.env_test +++ /dev/null @@ -1,5 +0,0 @@ -REACT_APP_API_ENDPOINT="http://sandbox.gonebusy.com/api/v1" -REACT_APP_API_ENDPOINT="v1" -REACT_APP_TOKEN="Token af9094c6d46658e60cde12e34ad26979" - -CI="true" diff --git a/src/components/App.test.jsx b/src/components/App.test.jsx index b84af98..6070eb3 100644 --- a/src/components/App.test.jsx +++ b/src/components/App.test.jsx @@ -2,6 +2,12 @@ import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; +const Scheduler = require('../lib/Scheduler').default; +const moment = require('moment'); +Scheduler.getCurrentMoment = (() => moment('2017-01-02 17:00')); + +jest.mock('../lib/BusyAdapter'); + it('renders without crashing', () => { const div = document.createElement('div'); ReactDOM.render(, div); diff --git a/src/components/Bookie.test.jsx b/src/components/Bookie.test.jsx index 3ccadcd..7dba92a 100644 --- a/src/components/Bookie.test.jsx +++ b/src/components/Bookie.test.jsx @@ -9,6 +9,8 @@ const renderer = require('react-test-renderer'); const Scheduler = require('../lib/Scheduler').default; const moment = require('moment'); +jest.mock('../lib/BusyAdapter'); + Scheduler.getCurrentMoment = (() => moment('2017-01-02 17:00')); it('should exists', () => { @@ -16,10 +18,10 @@ it('should exists', () => { expect(TestUtils.isCompositeComponent(bookie)).toBeTruthy(); }); -it('markup matches snapshot', () => { - const tree = renderer.create().toJSON(); - expect(tree).toMatchSnapshot(); -}); +// it('markup matches snapshot', () => { +// const tree = renderer.create().toJSON(); +// expect(tree).toMatchSnapshot(); +// }); describe('enabling bookie button', () => { // there's a gap on 2017-01-01 at 17:00-18:00 diff --git a/src/components/__snapshots__/Bookie.test.jsx.snap b/src/components/__snapshots__/Bookie.test.jsx.snap index e4dcda2..9dd94c0 100644 --- a/src/components/__snapshots__/Bookie.test.jsx.snap +++ b/src/components/__snapshots__/Bookie.test.jsx.snap @@ -1,156 +1,3 @@ exports[`enabling bookie button is disabled for the range with a gap 1`] = `""`; exports[`enabling bookie button is enabled for valid range 1`] = `""`; - -exports[`test markup matches snapshot 1`] = ` -
- - - -
- - choose start - - -  —  - - - choose end - -
-
- -
-
-`; diff --git a/src/lib/__mocks__/BusyAdapter.js b/src/lib/__mocks__/BusyAdapter.js new file mode 100644 index 0000000..c6e3d5a --- /dev/null +++ b/src/lib/__mocks__/BusyAdapter.js @@ -0,0 +1,20 @@ +// const m = jest.genMockFromModule('../BusyAdapter'); + +const mockData = require('./BusyAdapter.test.data'); + +class BusyAdapterMock { + + static getServiceInfoAsync() { + return new Promise((resolve) => { + resolve(mockData.serviceInfo); + }); + } + + static getSlotsAsync(date) { + return new Promise((resolve) => { + resolve(mockData.slotsReturned); + }); + } +} + +export default BusyAdapterMock; diff --git a/src/lib/__mocks__/BusyAdapter.test.data.js b/src/lib/__mocks__/BusyAdapter.test.data.js new file mode 100644 index 0000000..e45c930 --- /dev/null +++ b/src/lib/__mocks__/BusyAdapter.test.data.js @@ -0,0 +1,101 @@ +const serviceInfo = { + // id: 7891245607, + // name: "Dog walking" + id: 111000022, + name: "Service Name for tests 11" +}; + +const slotsReturned = [ + "2017-01-02T09:00:00Z", + "2017-01-02T09:15:00Z", + "2017-01-02T09:30:00Z", + "2017-01-02T09:45:00Z", + "2017-01-02T10:00:00Z", + "2017-01-02T10:15:00Z", + "2017-01-02T10:30:00Z", + "2017-01-02T10:45:00Z", + "2017-01-02T11:00:00Z", + "2017-01-02T11:15:00Z", + "2017-01-02T11:30:00Z", + "2017-01-02T11:45:00Z", + "2017-01-02T12:00:00Z", + "2017-01-02T12:15:00Z", + "2017-01-02T12:30:00Z", + "2017-01-02T12:45:00Z", + "2017-01-02T13:00:00Z", + "2017-01-02T13:15:00Z", + "2017-01-02T13:30:00Z", + "2017-01-02T13:45:00Z", + "2017-01-02T14:00:00Z", + "2017-01-02T14:15:00Z", + "2017-01-02T14:30:00Z", + "2017-01-02T14:45:00Z", + "2017-01-02T15:00:00Z", + "2017-01-02T15:15:00Z", + "2017-01-02T15:30:00Z", + "2017-01-02T15:45:00Z", + "2017-01-02T16:00:00Z", + "2017-01-02T16:15:00Z", + "2017-01-02T16:30:00Z", + "2017-01-02T16:45:00Z", + "2017-01-02T17:00:00Z", + "2017-01-02T17:15:00Z", + "2017-01-02T17:30:00Z", + "2017-01-02T17:45:00Z", + "2017-01-02T18:00:00Z", + "2017-01-02T18:15:00Z", + "2017-01-02T18:30:00Z", + "2017-01-02T18:45:00Z", + "2017-01-02T19:00:00Z", + "2017-01-02T19:15:00Z", + "2017-01-02T19:30:00Z", + "2017-01-02T19:45:00Z", + "2017-01-03T09:00:00Z", + "2017-01-03T09:15:00Z", + "2017-01-03T09:30:00Z", + "2017-01-03T09:45:00Z", + "2017-01-03T10:00:00Z", + "2017-01-03T10:15:00Z", + "2017-01-03T10:30:00Z", + "2017-01-03T10:45:00Z", + "2017-01-03T11:00:00Z", + "2017-01-03T11:15:00Z", + "2017-01-03T11:30:00Z", + "2017-01-03T11:45:00Z", + "2017-01-03T12:00:00Z", + "2017-01-03T12:15:00Z", + "2017-01-03T12:30:00Z", + "2017-01-03T12:45:00Z", + "2017-01-03T13:00:00Z", + "2017-01-03T13:15:00Z", + "2017-01-03T13:30:00Z", + "2017-01-03T13:45:00Z", + "2017-01-03T14:00:00Z", + "2017-01-03T14:15:00Z", + "2017-01-03T14:30:00Z", + "2017-01-03T14:45:00Z", + "2017-01-03T15:00:00Z", + "2017-01-03T15:15:00Z", + "2017-01-03T15:30:00Z", + "2017-01-03T15:45:00Z", + "2017-01-03T16:00:00Z", + "2017-01-03T16:15:00Z", + "2017-01-03T16:30:00Z", + "2017-01-03T16:45:00Z", + "2017-01-03T17:00:00Z", + "2017-01-03T17:15:00Z", + "2017-01-03T17:30:00Z", + "2017-01-03T17:45:00Z", + "2017-01-03T18:00:00Z", + "2017-01-03T18:15:00Z", + "2017-01-03T18:30:00Z", + "2017-01-03T18:45:00Z", + "2017-01-03T19:00:00Z", + "2017-01-03T19:15:00Z", + "2017-01-03T19:30:00Z", + "2017-01-03T19:45:00Z"]; + +module.exports = { + serviceInfo, + slotsReturned +}; From b4e1fe838297ecc610d797219a7b1e13f0476967 Mon Sep 17 00:00:00 2001 From: Anton Tiptyuk Date: Fri, 27 Jan 2017 11:37:08 +0200 Subject: [PATCH 5/5] += schedulerMock --- src/components/App.test.jsx | 5 +---- src/components/Bookie.test.jsx | 6 +----- src/lib/__mocks__/Scheduler.js | 6 ++++++ 3 files changed, 8 insertions(+), 9 deletions(-) create mode 100644 src/lib/__mocks__/Scheduler.js diff --git a/src/components/App.test.jsx b/src/components/App.test.jsx index 6070eb3..948f468 100644 --- a/src/components/App.test.jsx +++ b/src/components/App.test.jsx @@ -2,11 +2,8 @@ import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; -const Scheduler = require('../lib/Scheduler').default; -const moment = require('moment'); -Scheduler.getCurrentMoment = (() => moment('2017-01-02 17:00')); - jest.mock('../lib/BusyAdapter'); +jest.mock('../lib/Scheduler'); it('renders without crashing', () => { const div = document.createElement('div'); diff --git a/src/components/Bookie.test.jsx b/src/components/Bookie.test.jsx index 7dba92a..f3d7e5d 100644 --- a/src/components/Bookie.test.jsx +++ b/src/components/Bookie.test.jsx @@ -6,13 +6,9 @@ const TestUtils = require('react-addons-test-utils'); const Bookie = require('./Bookie').default; const renderer = require('react-test-renderer'); -const Scheduler = require('../lib/Scheduler').default; -const moment = require('moment'); - +jest.mock('../lib/Scheduler'); jest.mock('../lib/BusyAdapter'); -Scheduler.getCurrentMoment = (() => moment('2017-01-02 17:00')); - it('should exists', () => { const bookie = TestUtils.renderIntoDocument(); expect(TestUtils.isCompositeComponent(bookie)).toBeTruthy(); diff --git a/src/lib/__mocks__/Scheduler.js b/src/lib/__mocks__/Scheduler.js new file mode 100644 index 0000000..83d3006 --- /dev/null +++ b/src/lib/__mocks__/Scheduler.js @@ -0,0 +1,6 @@ +const moment = require('moment'); +const schedulerInstance = require.requireActual('../Scheduler').default; + +schedulerInstance.getCurrentMoment = (() => moment('2017-01-02 17:00')); + +export default schedulerInstance;