Implement+test postsFilter

I think it's much cleaner to have just the filter object in the store
and to implement convenience methods to safely update the filter object.
This commit is contained in:
Robert Schäfer 2019-08-10 01:41:47 +02:00
parent a8cfe96f60
commit 196cced8cf
2 changed files with 176 additions and 0 deletions

View File

@ -0,0 +1,50 @@
import get from 'lodash/get'
import update from 'lodash/update'
import xor from 'lodash/xor'
import isEmpty from 'lodash/isEmpty'
import clone from 'lodash/clone'
export const state = () => {
return {
filter: {},
}
}
export const mutations = {
TOGGLE_FILTER_BY_FOLLOWED(state, currentUserId) {
const filter = clone(state.filter)
const id = get(filter, 'author.followedBy_some.id')
if (id) {
delete filter.author
state.filter = filter
} else {
state.filter = {
...filter,
author: { followedBy_some: { id: currentUserId } },
}
}
},
RESET_CATEGORIES(state) {
const filter = clone(state.filter)
delete filter.categories_some
state.filter = filter
},
TOGGLE_CATEGORY(state, categoryId) {
const filter = clone(state.filter)
update(filter, 'categories_some.id_in', categoryIds => xor(categoryIds, [categoryId]))
if (isEmpty(get(filter, 'categories_some.id_in'))) delete filter.categories_some
state.filter = filter
},
}
export const getters = {
postsFilter(state) {
return state.filter
},
filteredCategoryIds(state) {
return get(state.filter, 'categories_some.id_in') || []
},
filteredByUsersFollowed(state) {
return !!get(state.filter, 'author.followedBy_some.id')
},
}

View File

@ -0,0 +1,126 @@
import { getters, mutations } from './postsFilter.js'
let state
let testAction
describe('getters', () => {
describe('filteredCategoryIds', () => {
it('returns category ids if filter is set', () => {
state = { filter: { categories_some: { id_in: [24] } } }
expect(getters.filteredCategoryIds(state)).toEqual([24])
})
it('returns empty array if filter is not set', () => {
state = { filter: { author: { followedBy_some: { id: 7 } } } }
expect(getters.filteredCategoryIds(state)).toEqual([])
})
})
describe('postsFilter', () => {
it('returns filter', () => {
state = { filter: { author: { followedBy_some: { id: 7 } } } }
expect(getters.postsFilter(state)).toEqual({ author: { followedBy_some: { id: 7 } } })
})
})
describe('filteredByUsersFollowed', () => {
it('returns true if filter is set', () => {
state = { filter: { author: { followedBy_some: { id: 7 } } } }
expect(getters.filteredByUsersFollowed(state)).toBe(true)
})
it('returns false if filter is not set', () => {
state = { filter: { categories_some: { id_in: [23] } } }
expect(getters.filteredByUsersFollowed(state)).toBe(false)
})
})
})
describe('mutations', () => {
describe('RESET_CATEGORIES', () => {
beforeEach(() => {
testAction = categoryId => {
mutations.RESET_CATEGORIES(state, categoryId)
return getters.postsFilter(state)
}
})
it('resets the categories filter', () => {
state = {
filter: {
author: { followedBy_some: { id: 7 } },
categories_some: { id_in: [23] },
},
}
expect(testAction(23)).toEqual({ author: { followedBy_some: { id: 7 } } })
})
})
describe('TOGGLE_CATEGORY', () => {
beforeEach(() => {
testAction = categoryId => {
mutations.TOGGLE_CATEGORY(state, categoryId)
return getters.postsFilter(state)
}
})
it('creates category filter if empty', () => {
state = { filter: {} }
expect(testAction(23)).toEqual({ categories_some: { id_in: [23] } })
})
it('adds category id not present', () => {
state = { filter: { categories_some: { id_in: [24] } } }
expect(testAction(23)).toEqual({ categories_some: { id_in: [24, 23] } })
})
it('removes category id if present', () => {
state = { filter: { categories_some: { id_in: [23, 24] } } }
const result = testAction(23)
expect(result).toEqual({ categories_some: { id_in: [24] } })
})
it('removes category filter if empty', () => {
state = { filter: { categories_some: { id_in: [23] } } }
expect(testAction(23)).toEqual({})
})
it('does not get in the way of other filters', () => {
state = {
filter: {
author: { followedBy_some: { id: 7 } },
categories_some: { id_in: [23] },
},
}
expect(testAction(23)).toEqual({ author: { followedBy_some: { id: 7 } } })
})
})
describe('TOGGLE_FILTER_BY_FOLLOWED', () => {
beforeEach(() => {
testAction = userId => {
mutations.TOGGLE_FILTER_BY_FOLLOWED(state, userId)
return getters.postsFilter(state)
}
})
describe('given empty filter', () => {
beforeEach(() => {
state = { filter: {} }
})
it('attaches the id of the current user to the filter object', () => {
expect(testAction(4711)).toEqual({ author: { followedBy_some: { id: 4711 } } })
})
})
describe('already filtered', () => {
beforeEach(() => {
state = { filter: { author: { followedBy_some: { id: 4711 } } } }
})
it('remove the id of the current user from the filter object', () => {
expect(testAction(4711)).toEqual({})
})
})
})
})