All files / lib/postProcessing filter.js

12.5% Statements 8/64
0% Branches 0/32
0% Functions 0/12
14.04% Lines 8/57
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100  1x   1x       1x   1x                                           1x                                           1x                                       1x                   1x                                
'use strict'
const filter = module.exports = { }
 
const _ = {
  assign: require('lodash.assign'),
  isEqual: require('lodash.isequal')
}
const debug = require('../debugging.js')
 
filter.action = (request, response, callback) => {
  const filters = request.processedFilter
  if (!filters) return callback()
 
  if (Array.isArray(response.data)) {
    for (let j = 0; j < response.data.length; j++) {
      if (!filter._filterKeepObject(response.data[j], filters)) {
        debug.filter('removed', JSON.stringify(filters), JSON.stringify(response.data[j].attributes))
        response.data.splice(j, 1)
        j--
      }
    }
  } else if (response.data instanceof Object) {
    if (!filter._filterKeepObject(response.data, filters)) {
      debug.filter('removed', JSON.stringify(filters), JSON.stringify(response.data.attributes))
      response.data = null
    }
  }
 
  return callback()
}
 
filter._filterMatches = (filterElement, attributeValue) => {
  if (!filterElement.operator) {
    return _.isEqual(attributeValue, filterElement.value)
  }
  const filterFunction = {
    '>': function filterGreaterThan (attrValue, filterValue) {
      return attrValue > filterValue
    },
    '<': function filterLessThan (attrValue, filterValue) {
      return attrValue < filterValue
    },
    '~': function filterCaseInsensitiveEqual (attrValue, filterValue) {
      return attrValue.toLowerCase() === filterValue.toLowerCase()
    },
    ':': function filterCaseInsensitiveContains (attrValue, filterValue) {
      return attrValue.toLowerCase().indexOf(filterValue.toLowerCase()) !== -1
    }
  }[filterElement.operator]
  const result = filterFunction(attributeValue, filterElement.value)
  return result
}
 
filter._filterKeepObject = (someObject, filters) => {
  for (const filterName in filters) {
    const whitelist = filters[filterName]
 
    if (someObject.attributes.hasOwnProperty(filterName) || (filterName === 'id')) {
      let attributeValue = someObject.attributes[filterName]
      if (filterName === 'id') attributeValue = someObject.id
      const attributeMatches = filter._attributesMatchesOR(attributeValue, whitelist)
      if (!attributeMatches) return false
    } else if (someObject.relationships.hasOwnProperty(filterName)) {
      const relationships = someObject.relationships[filterName]
      const relationshipMatches = filter._relationshipMatchesOR(relationships, whitelist)
      if (!relationshipMatches) return false
    } else {
      return false
    }
  }
  return true
}
 
filter._attributesMatchesOR = (attributeValue, whitelist) => {
  let matchOR = false
  whitelist.forEach(filterElement => {
    if (filter._filterMatches(filterElement, attributeValue)) {
      matchOR = true
    }
  })
  return matchOR
}
 
filter._relationshipMatchesOR = (relationships, whitelist) => {
  let matchOR = false
 
  let data = relationships.data
  if (!data) return false
 
  if (!(Array.isArray(data))) data = [ data ]
  data = data.map(relation => relation.id)
 
  whitelist.forEach(filterElement => {
    if (data.indexOf(filterElement.value) !== -1) {
      matchOR = true
    }
  })
  return matchOR
}