Skip to content

Commit

Permalink
Cast iso date strings to actual dates in query objects
Browse files Browse the repository at this point in the history
  • Loading branch information
kjellmorten committed Apr 5, 2018
1 parent a842d03 commit 91084ea
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 2 deletions.
169 changes: 169 additions & 0 deletions lib/adapter/prepareFilter-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
import test from 'ava'

import prepareFilter from './prepareFilter'

test('should return type filter', (t) => {
const params = {type: 'entry'}
const endpoint = {
collection: 'documents',
db: 'database'
}
const expected = {type: 'entry'}

const ret = prepareFilter(params, endpoint, params)

t.deepEqual(ret, expected)
})

test('should return _id filter', (t) => {
const params = {type: 'entry', id: 'ent1'}
const endpoint = {
collection: 'documents',
db: 'database'
}
const expected = {_id: 'entry:ent1'}

const ret = prepareFilter(params, endpoint, params)

t.deepEqual(ret, expected)
})

test('should use endpoint.query as filter', (t) => {
const params = {type: 'entry', id: 'ent1'}
const endpoint = {
collection: 'documents',
db: 'database',
query: [
{path: 'type', value: 'other'},
{path: 'attributes\\.parentType', param: 'type'}
]
}
const expected = {
type: 'other',
'attributes.parentType': 'entry'
}

const ret = prepareFilter(params, endpoint, params)

t.deepEqual(ret, expected)
})

test('should add params query to endpoint query filter', (t) => {
const params = {
type: 'entry',
query: {'attributes.section': 'news'}
}
const endpoint = {
collection: 'documents',
db: 'database',
query: [
{path: 'type', value: 'other'},
{path: 'attributes\\.parentType', param: 'type'}
]
}
const expected = {
type: 'other',
'attributes.parentType': 'entry',
'attributes.section': 'news'
}

const ret = prepareFilter(params, endpoint, params)

t.deepEqual(ret, expected)
})

test('should add params query to type filter', (t) => {
const params = {
type: 'entry',
query: {'attributes.section': 'news'}
}
const endpoint = {
collection: 'documents',
db: 'database'
}
const expected = {
type: 'entry',
'attributes.section': 'news'
}

const ret = prepareFilter(params, endpoint, params)

t.deepEqual(ret, expected)
})

test('should add params query to id filter', (t) => {
const params = {
id: 'ent1',
type: 'entry',
query: {'attributes.section': 'news'}
}
const endpoint = {
collection: 'documents',
db: 'database'
}
const expected = {
_id: 'entry:ent1',
'attributes.section': 'news'
}

const ret = prepareFilter(params, endpoint, params)

t.deepEqual(ret, expected)
})

test('should cast date strings as Date', (t) => {
const params = {
type: 'entry',
query: {'attributes.updatedAt': '2017-11-13T18:43:01.000Z'}
}
const endpoint = {
collection: 'documents',
db: 'database'
}
const expected = {
type: 'entry',
'attributes.updatedAt': new Date('2017-11-13T18:43:01.000Z')
}

const ret = prepareFilter(params, endpoint, params)

t.deepEqual(ret, expected)
})

test('should cast date strings without microseconds as Date', (t) => {
const params = {
type: 'entry',
query: {'attributes.updatedAt': '2017-11-13T18:43:01Z'}
}
const endpoint = {
collection: 'documents',
db: 'database'
}
const expected = {
type: 'entry',
'attributes.updatedAt': new Date('2017-11-13T18:43:01Z')
}

const ret = prepareFilter(params, endpoint, params)

t.deepEqual(ret, expected)
})

test('should cast date strings with other time zone as Date', (t) => {
const params = {
type: 'entry',
query: {'attributes.updatedAt': '2017-11-13T18:43:01.000+01:00'}
}
const endpoint = {
collection: 'documents',
db: 'database'
}
const expected = {
type: 'entry',
'attributes.updatedAt': new Date('2017-11-13T18:43:01.000+01:00')
}

const ret = prepareFilter(params, endpoint, params)

t.deepEqual(ret, expected)
})
19 changes: 18 additions & 1 deletion lib/adapter/prepareFilter.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,23 @@ const setTypeOrId = (query, type, id) => {
}
}

const dateStringRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?([+-]\d{2}:\d{2}|Z)$/
const isDateString = (value) => typeof value === 'string' && dateStringRegex.test(value)
const castValueIfDate = (value) => (isDateString(value)) ? new Date(value) : value

const castDates = (query) => Object.keys(query).reduce(
(casted, key) => ({...casted, [key]: castValueIfDate(query[key])}),
{}
)

/**
* Generate the right query object as a filter for finding docs in the database.
*
* @param {Object} item - Any object with type and optionally id
* @param {Object} endpiont - The endpoint object
* @param {Object} params - The params object
* @returns {Object} A query object for MongoDB's find() method
*/
const prepareFilter = ({type, id}, {query: queryProps = []}, params) => {
// Create query object from array of props
const query = queryProps.reduce((filter, prop) => {
Expand All @@ -25,7 +42,7 @@ const prepareFilter = ({type, id}, {query: queryProps = []}, params) => {
Object.assign(query, params.query)
}

return query
return castDates(query)
}

module.exports = prepareFilter
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "integreat-adapter-mongodb",
"version": "0.1.4",
"version": "0.1.5",
"description": "Integreat adapter for mongodb",
"main": "index.js",
"author": "Kjell-Morten Bratsberg Thorsen <post@kjellmorten.no>",
Expand Down

0 comments on commit 91084ea

Please sign in to comment.