Fix this annoying bug with a tested helper

I don't know where the bug originates. But it can only be that either
`previousResult` or `fetchMore` result is sometimes undefined. This
should make the function bullet-proof for these situations.
This commit is contained in:
roschaefer 2019-12-10 21:47:34 +01:00
parent a348c5dc9c
commit e24d8035b1
4 changed files with 107 additions and 42 deletions

View File

@ -0,0 +1,17 @@
import unionBy from 'lodash/unionBy'
export default function UpdateQuery(component, { $state, pageKey }) {
if (!pageKey) throw new Error('No key given for the graphql query { data } object')
return (previousResult, { fetchMoreResult }) => {
const oldData = (previousResult && previousResult[pageKey]) || []
const newData = (fetchMoreResult && fetchMoreResult[pageKey]) || []
if (newData.length < component.pageSize) {
component.hasMore = false
$state.complete()
}
const result = {}
result[pageKey] = unionBy(oldData, newData, item => item.id)
$state.loaded()
return result
}
}

View File

@ -0,0 +1,86 @@
import UpdateQuery from './UpdateQuery'
let $state
let component
let pageKey
let updateQuery
let previousResult
let fetchMoreResult
beforeEach(() => {
component = {
hasMore: true,
pageSize: 1,
}
$state = {
complete: jest.fn(),
loaded: jest.fn(),
}
previousResult = { Post: [{ id: 1, foo: 'bar' }] }
fetchMoreResult = { Post: [{ id: 2, foo: 'baz' }] }
updateQuery = () => UpdateQuery(component, { $state, pageKey })
})
describe('UpdateQuery', () => {
it('throws error because no key is given', () => {
expect(() => {
updateQuery()({ Post: [] }, { fetchMoreResult: { Post: [] } })
}).toThrow(/No key given/)
})
describe('with a page key', () => {
beforeEach(() => (pageKey = 'Post'))
describe('given two arrays of things', () => {
it('merges the arrays', () => {
expect(updateQuery()(previousResult, { fetchMoreResult })).toEqual({
Post: [
{ id: 1, foo: 'bar' },
{ id: 2, foo: 'baz' },
],
})
})
it('does not create duplicates', () => {
fetchMoreResult = { Post: [{ id: 1, foo: 'baz' }] }
expect(updateQuery()(previousResult, { fetchMoreResult })).toEqual({
Post: [{ id: 1, foo: 'bar' }],
})
})
it('does not call $state.complete()', () => {
expect(updateQuery()(previousResult, { fetchMoreResult }))
expect($state.complete).not.toHaveBeenCalled()
})
describe('in case of fewer records than pageSize', () => {
beforeEach(() => (component.pageSize = 10))
it('calls $state.complete()', () => {
expect(updateQuery()(previousResult, { fetchMoreResult }))
expect($state.complete).toHaveBeenCalled()
})
it('changes component.hasMore to `false`', () => {
expect(component.hasMore).toBe(true)
expect(updateQuery()(previousResult, { fetchMoreResult }))
expect(component.hasMore).toBe(false)
})
})
})
describe('given one array is undefined', () => {
describe('does not crash', () => {
it('neither if the previous data was undefined', () => {
expect(updateQuery()(undefined, { fetchMoreResult })).toEqual({
Post: [{ id: 2, foo: 'baz' }],
})
})
it('not if the new data is undefined', () => {
expect(updateQuery()(previousResult, {})).toEqual({ Post: [{ id: 1, foo: 'bar' }] })
})
})
})
})
})

View File

@ -68,6 +68,7 @@ import MasonryGridItem from '~/components/MasonryGrid/MasonryGridItem.vue'
import { mapGetters, mapMutations } from 'vuex'
import { filterPosts } from '~/graphql/PostQuery.js'
import PostMutations from '~/graphql/PostMutations'
import UpdateQuery from '~/components/utils/UpdateQuery'
export default {
components: {
@ -151,27 +152,7 @@ export default {
first: this.pageSize,
orderBy: ['pinned_asc', this.orderBy],
},
updateQuery: (previousResult, { fetchMoreResult }) => {
if (!fetchMoreResult || fetchMoreResult.Post.length < this.pageSize) {
this.hasMore = false
$state.complete()
}
const { Post = [] } = previousResult
const result = {
...previousResult,
Post: [
...Post.filter(prevPost => {
return (
fetchMoreResult.Post.filter(newPost => newPost.id === prevPost.id).length === 0
)
}),
...fetchMoreResult.Post,
],
}
$state.loaded()
return result
},
updateQuery: UpdateQuery(this, { $state, pageKey: 'Post' }),
})
},
deletePost(deletedPost) {

View File

@ -283,6 +283,7 @@ import { profilePagePosts } from '~/graphql/PostQuery'
import UserQuery from '~/graphql/User'
import { Block, Unblock } from '~/graphql/settings/BlockedUsers'
import PostMutations from '~/graphql/PostMutations'
import UpdateQuery from '~/components/utils/UpdateQuery'
const tabToFilterMapping = ({ tab, id }) => {
return {
@ -385,27 +386,7 @@ export default {
first: this.pageSize,
orderBy: 'createdAt_desc',
},
updateQuery: (previousResult, { fetchMoreResult }) => {
if (!fetchMoreResult || fetchMoreResult.profilePagePosts.length < this.pageSize) {
this.hasMore = false
$state.complete()
}
const { profilePagePosts = [] } = previousResult
const result = {
...previousResult,
profilePagePosts: [
...profilePagePosts.filter(prevPost => {
return (
fetchMoreResult.profilePagePosts.filter(newPost => newPost.id === prevPost.id)
.length === 0
)
}),
...fetchMoreResult.profilePagePosts,
],
}
$state.loaded()
return result
},
updateQuery: UpdateQuery(this, { $state, pageKey: 'profilePagePosts' }),
})
},
resetPostList() {