Skip to content

Commit

Permalink
Test Coverage (fetch, updateMany/createMany, addAction(s)) (#56)
Browse files Browse the repository at this point in the history
* Fix addAction to pass through opts into _opts on functional call
 * Adds tests for #action(<id>) and #action(<params>) queries

* Add addActions test

* Setup store and adapter in start.js

* Sum and count tests

* Tests for createMany and updateMany

* Add fetch test
  • Loading branch information
pik authored and jmdobry committed Aug 19, 2016
1 parent 9d8ca3a commit 1b7b107
Show file tree
Hide file tree
Showing 15 changed files with 247 additions and 40 deletions.
1 change: 1 addition & 0 deletions fetch/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ module.exports = function (config) {
browsers: browsers,
files: [
'node_modules/babel-polyfill/dist/polyfill.js',
'node_modules/whatwg-fetch/fetch.js',
'node_modules/js-data/dist/js-data.js',
'fetch/dist/js-data-fetch.js',
'fetch/karma.start.js',
Expand Down
14 changes: 11 additions & 3 deletions fetch/karma.start.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/* global JSData:true, JSDataHttp:true, sinon:true, chai:true */

before(function () {
var Test = this
Test.TEST_FETCH = true
Test.fail = function (msg) {
if (msg instanceof Error) {
console.log(msg.stack)
Expand All @@ -14,7 +16,14 @@ before(function () {
}
Test.sinon = sinon
Test.JSData = JSData
Test.addAction = JSDataHttp.addAction
Test.addActions = JSDataHttp.addActions
Test.HttpAdapter = JSDataHttp.HttpAdapter

Test.store = new JSData.DataStore()
Test.adapter = new Test.HttpAdapter()
Test.store.registerAdapter('http', Test.adapter, { default: true })

Test.User = new JSData.Mapper({
name: 'user'
})
Expand All @@ -24,14 +33,13 @@ before(function () {
basePath: 'api'
})

Test.User.registerAdapter('http', Test.adapter, { default: true })
Test.Post.registerAdapter('http', Test.adapter, { default: true })
console.log('Testing against js-data ' + JSData.version.full)
})

beforeEach(function () {
var Test = this
Test.adapter = new Test.HttpAdapter()
Test.User.registerAdapter('http', Test.adapter, { default: true })
Test.Post.registerAdapter('http', Test.adapter, { default: true })

Test.p1 = { author: 'John', age: 30, id: 5 }
Test.p2 = { author: 'Sally', age: 31, id: 6 }
Expand Down
3 changes: 1 addition & 2 deletions fetch/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@
"axios",
"rest",
"adapter",
"http",
"fetch"
"http"
],
"dependencies": {
"js-data-adapter": "~0.8.1"
Expand Down
1 change: 1 addition & 0 deletions karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ module.exports = function (config) {
browsers: browsers,
files: [
'node_modules/babel-polyfill/dist/polyfill.js',
'node_modules/whatwg-fetch/fetch.js',
'node_modules/js-data/dist/js-data.js',
'dist/js-data-http.js',
'karma.start.js',
Expand Down
15 changes: 12 additions & 3 deletions karma.start.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/* global JSData:true, JSDataHttp:true, sinon:true, chai:true */

before(function () {
var Test = this
Test.TEST_FETCH = false
Test.fail = function (msg) {
if (msg instanceof Error) {
console.log(msg.stack)
Expand All @@ -14,7 +16,15 @@ before(function () {
}
Test.sinon = sinon
Test.JSData = JSData
Test.addAction = JSDataHttp.addAction
Test.addActions = JSDataHttp.addActions
Test.HttpAdapter = JSDataHttp.HttpAdapter

Test.store = new JSData.DataStore()
Test.adapter = new Test.HttpAdapter()

Test.store.registerAdapter('http', Test.adapter, { default: true })

Test.User = new JSData.Mapper({
name: 'user'
})
Expand All @@ -24,14 +34,13 @@ before(function () {
basePath: 'api'
})

Test.User.registerAdapter('http', Test.adapter, { default: true })
Test.Post.registerAdapter('http', Test.adapter, { default: true })
console.log('Testing against js-data ' + JSData.version.full)
})

beforeEach(function () {
var Test = this
Test.adapter = new Test.HttpAdapter()
Test.User.registerAdapter('http', Test.adapter, { default: true })
Test.Post.registerAdapter('http', Test.adapter, { default: true })

Test.p1 = { author: 'John', age: 30, id: 5 }
Test.p2 = { author: 'Sally', age: 31, id: 6 }
Expand Down
12 changes: 8 additions & 4 deletions node/mocha.start.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ before(function () {
}
Test.sinon = require('sinon')
Test.JSData = require('js-data')
Test.addAction = require('./dist/js-data-http-node').addAction
Test.addActions = require('./dist/js-data-http-node').addActions
Test.HttpAdapter = require('./dist/js-data-http-node').HttpAdapter
Test.store = new Test.JSData.DataStore()
Test.adapter = new Test.HttpAdapter()
Test.store.registerAdapter('http', Test.adapter, { default: true })

Test.User = new Test.JSData.Mapper({
name: 'user'
})
Expand All @@ -28,15 +34,13 @@ before(function () {
basePath: 'api'
})

Test.User.registerAdapter('http', Test.adapter, { default: true })
Test.Post.registerAdapter('http', Test.adapter, { default: true })
console.log('Testing against js-data ' + Test.JSData.version.full)
})

beforeEach(function () {
var Test = this
Test.adapter = new Test.HttpAdapter()
Test.User.registerAdapter('http', Test.adapter, { default: true })
Test.Post.registerAdapter('http', Test.adapter, { default: true })

Test.p1 = { author: 'John', age: 30, id: 5 }
Test.p2 = { author: 'Sally', age: 31, id: 6 }
Test.p3 = { author: 'Mike', age: 32, id: 7 }
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
"phantomjs-prebuilt": "2.1.12",
"rollup-plugin-commonjs": "3.3.1",
"rollup-plugin-replace": "1.1.1",
"uglify-js": "2.7.0"
"uglify-js": "2.7.0",
"whatwg-fetch": "^1.0.0"
}
}
38 changes: 17 additions & 21 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* global fetch:true Headers:true Request:true */
/* global fetch:true Headers:true */

import {utils} from 'js-data'
import axios from '../node_modules/axios/dist/axios'
Expand Down Expand Up @@ -53,7 +53,7 @@ function buildUrl (url, params) {
}

val.forEach(function (v) {
if (window.toString.call(v) === '[object Date]') {
if (toString.call(v) === '[object Date]') {
v = v.toISOString()
} else if (utils.isObject(v)) {
v = utils.toJson(v)
Expand Down Expand Up @@ -558,20 +558,19 @@ Adapter.extend({
* @param {Object} config.headers Headers for the request.
* @param {Object} config.params Querystring for the request.
* @param {string} config.url Url for the request.
* @param {Object} [opts] Configuration options.
*/
fetch (config, opts) {
fetch (config) {
const requestConfig = {
method: config.method,
// turn the plain headers object into the Fetch Headers object
headers: new Headers(config.headers)
headers: new Headers(config.headers || {})
}

if (config.data) {
requestConfig.body = utils.toJson(config.data)
}

return fetch(new Request(buildUrl(config.url, config.params), requestConfig))
return fetch(buildUrl(config.url, config.params), requestConfig)
.then((response) => {
response.config = {
method: config.method,
Expand Down Expand Up @@ -969,7 +968,7 @@ Adapter.extend({
sum (mapper, field, query, opts) {
query || (query = {})
opts || (opts = {})
if (!utils.utils.isString(field)) {
if (!utils.isString(field)) {
throw new Error('field must be a string!')
}
opts.params = this.getParams(opts)
Expand Down Expand Up @@ -1064,7 +1063,7 @@ Adapter.extend({
*
* // GET /reports/schools/:school_id/teachers
* addAction('getTeacherReports', {
* basePath: 'reports/schools',
* endpoint: 'reports/schools',
* pathname: 'teachers',
* method: 'GET'
* })(store.getMapper('school'))
Expand Down Expand Up @@ -1098,42 +1097,39 @@ export function addAction (name, opts) {
opts.response = opts.response || function (response) { return response }
opts.responseError = opts.responseError || function (err) { return utils.reject(err) }
mapper[name] = function (id, _opts) {
_opts = _opts || {}
if (utils.isObject(id)) {
_opts = id
}
_opts = _opts || {}
let adapter = this.getAdapter(opts.adapter || this.defaultAdapter || 'http')
let config = {}
utils.fillIn(config, opts)
if (!_opts.hasOwnProperty('endpoint') && config.endpoint) {
_opts.endpoint = config.endpoint
}
utils.fillIn(_opts, opts)
let adapter = this.getAdapter(_opts.adapter || this.defaultAdapter || 'http')
const config = {}
config.mapper = this.name
utils.deepMixIn(config, _opts)
config.method = config.method || 'GET'
if (typeof _opts.getEndpoint === 'function') {
config.url = _opts.getEndpoint(this, _opts)
} else {
let args = [
_opts.basePath || this.basePath || adapter.basePath,
adapter.getEndpoint(this, utils.isSorN(id) ? id : null, _opts)
adapter.getEndpoint(this, id, _opts)
]
if (utils.isSorN(id)) {
args.push(id)
}
args.push(opts.pathname || name)
config.url = makePath.apply(null, args)
}
config.method = config.method || 'GET'
config.mapper = this.name
utils.deepMixIn(config, _opts)
return utils.resolve(config)
.then(_opts.request || opts.request)
.then(_opts.request)
.then((config) => adapter.HTTP(config))
.then((data) => {
if (data && data.config) {
data.config.mapper = this.name
}
return data
})
.then(_opts.response || opts.response, _opts.responseError || opts.responseError)
.then(_opts.response, _opts.responseError)
}
return mapper
}
Expand Down
14 changes: 14 additions & 0 deletions test/count.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
describe('sum', function () {
it('should include count=true in query_params', function (done) {
var Test = this

setTimeout(function () {
Test.requests[0].respond(200, { 'Content-Type': 'application/json' }, '{"count": 5}')
}, 5)

Test.adapter.count(Test.Post).then(function (result) {
Test.assert.equal(Test.requests[0].url, 'api/posts?count=true')
done()
})
})
})
16 changes: 15 additions & 1 deletion test/createMany.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
describe('createMany', function () {
it('should createMany')
it('should createMany', function (done) {
var Test = this

setTimeout(function () {
Test.requests[0].respond(200, { 'Content-Type': 'application/json' }, '')
}, 5)

var many = [{ author_id: 2, text: 'bar' }, { author_id: 2, text: 'foo' }]
Test.Post.createMany(many).then(function (result) {
Test.assert.equal(Test.requests[0].url, 'api/posts')
Test.assert.equal(Test.requests[0].method, 'POST')
Test.assert.equal(Test.requests[0].requestBody, JSON.stringify(many))
done()
})
})
})
35 changes: 34 additions & 1 deletion test/fetch.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,36 @@
describe('fetch', function () {
it('should fetch')
it('should fetch from a URL', function (done) {
var Test = this
// Don't test fetch for Node
try {
fetch // eslint-disable-line
} catch (e) {
return this.skip()
}
if (Test.TEST_FETCH) {
Test.xhr = Test.sinon.useFakeXMLHttpRequest()
Test.requests = []
Test.xhr.onCreate = function (xhr) {
Test.requests.push(xhr)
}
}

setTimeout(function () {
Test.requests[0].respond(200, { 'Content-Type': 'application/json' }, '{}')
}, 300)

Test.adapter.fetch({
method: 'get',
params: { active: true },
url: '/api/foos'
}).then(function (response) {
var request = Test.requests[0]
Test.assert.equal(request.method, 'GET')
Test.assert.equal(request.url, '/api/foos?active=true')
if (Test.TEST_FETCH) {
Test.xhr.restore()
}
done()
})
})
})
56 changes: 55 additions & 1 deletion test/static.addAction.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,57 @@
describe('static addAction', function () {
it('should addAction')
it('should addAction', function (done) {
var Test = this
var SchoolMapper = Test.store.defineMapper('school', {})

// GET async/reports/schools/:school_id/teachers
Test.addAction('getTeacherReportsAsync', {
basePath: 'async/',
endpoint: 'reports/schools',
pathname: 'teachers',
method: 'GET'
})(SchoolMapper)

setTimeout(function () {
Test.requests[0].respond(200, { 'Content-Type': 'text/plain' }, '')
}, 5)

SchoolMapper.getTeacherReportsAsync(1234).then(function (response) {
Test.assert.equal(1, Test.requests.length)
Test.assert.equal(Test.requests[0].url, 'async/reports/schools/1234/teachers', 'Add action configures basePath, endpoint and pathname')
Test.assert.equal(Test.requests[0].method, 'GET')
done()
})
})

it('addAction action is callable with params instead of id', function (done) {
var Test = this
var adapter = Test.adapter
var store = new Test.JSData.DataStore()
store.registerAdapter('http', adapter, { default: true })
var SchoolMapper = store.defineMapper('school', {})

// GET async/reports/schools/teachers
Test.addAction('getAllTeacherReportsAsync', {
basePath: 'async/',
endpoint: 'reports/schools',
pathname: 'teachers',
method: 'GET'
})(SchoolMapper)

setTimeout(function () {
Test.requests[0].respond(200, { 'Content-Type': 'text/plain' }, '')
}, 5)

// GET async/reports/schools/teachers?<key>=<value>
SchoolMapper.getAllTeacherReportsAsync({
params: {
subject: 'esperanto'
}
}).then(function (response) {
Test.assert.equal(1, Test.requests.length)
Test.assert.equal(Test.requests[0].url, 'async/reports/schools/teachers?subject=esperanto', 'Add action configures basePath, endpoint, pathname, and querystring')
Test.assert.equal(Test.requests[0].method, 'GET')
done()
})
})
})
Loading

0 comments on commit 1b7b107

Please sign in to comment.