mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2025-12-13 07:45:56 +00:00
refactor(webapp): store for categories (#8551)
* after authentification, query the categories if active and store them * get categories from store * use category store to get categories * get categories from store * mock store to have access to categories * to get rid of the active categories config variable in the frontend, the Category query returns an empty array when categories are not active * remove CATEGORIES_ACTIVE from .env * should return string to avoid warnings in console * replace all env calls for categories active by getter from store * use categoriesActive getter * ignore order of returned categories * mixin to get the category infos from the store, to ensure, that the quey has been called * fix misspelling --------- Co-authored-by: Wolfgang Huß <wolle.huss@pjannto.com>
This commit is contained in:
parent
5bec51ad5d
commit
a3178a91b4
97
backend/src/middleware/categories.spec.ts
Normal file
97
backend/src/middleware/categories.spec.ts
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
|
import { ApolloServer } from 'apollo-server-express'
|
||||||
|
import { createTestClient } from 'apollo-server-testing'
|
||||||
|
import gql from 'graphql-tag'
|
||||||
|
|
||||||
|
import databaseContext from '@context/database'
|
||||||
|
import Factory, { cleanDatabase } from '@db/factories'
|
||||||
|
import CONFIG from '@src/config'
|
||||||
|
import { categories } from '@src/constants/categories'
|
||||||
|
import createServer, { getContext } from '@src/server'
|
||||||
|
|
||||||
|
const database = databaseContext()
|
||||||
|
|
||||||
|
let server: ApolloServer
|
||||||
|
let query
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
await cleanDatabase()
|
||||||
|
const authenticatedUser = null
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/require-await
|
||||||
|
const contextUser = async (_req) => authenticatedUser
|
||||||
|
const context = getContext({ user: contextUser, database })
|
||||||
|
|
||||||
|
server = createServer({ context }).server
|
||||||
|
|
||||||
|
const createTestClientResult = createTestClient(server)
|
||||||
|
query = createTestClientResult.query
|
||||||
|
|
||||||
|
for (const category of categories) {
|
||||||
|
await Factory.build('category', {
|
||||||
|
id: category.id,
|
||||||
|
slug: category.slug,
|
||||||
|
name: category.name,
|
||||||
|
icon: category.icon,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
void server.stop()
|
||||||
|
void database.driver.close()
|
||||||
|
database.neode.close()
|
||||||
|
})
|
||||||
|
|
||||||
|
const categoriesQuery = gql`
|
||||||
|
query {
|
||||||
|
Category {
|
||||||
|
id
|
||||||
|
slug
|
||||||
|
name
|
||||||
|
icon
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
describe('categroeis middleware', () => {
|
||||||
|
describe('categories are active', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
CONFIG.CATEGORIES_ACTIVE = true
|
||||||
|
})
|
||||||
|
|
||||||
|
it('returns the categories', async () => {
|
||||||
|
await expect(
|
||||||
|
query({
|
||||||
|
query: categoriesQuery,
|
||||||
|
}),
|
||||||
|
).resolves.toMatchObject({
|
||||||
|
data: {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
|
Category: expect.arrayContaining(categories),
|
||||||
|
},
|
||||||
|
errors: undefined,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('categories are not active', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
CONFIG.CATEGORIES_ACTIVE = false
|
||||||
|
})
|
||||||
|
|
||||||
|
it('returns an empty array though there are categories in the db', async () => {
|
||||||
|
await expect(
|
||||||
|
query({
|
||||||
|
query: categoriesQuery,
|
||||||
|
}),
|
||||||
|
).resolves.toMatchObject({
|
||||||
|
data: {
|
||||||
|
Category: [],
|
||||||
|
},
|
||||||
|
errors: undefined,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
16
backend/src/middleware/categories.ts
Normal file
16
backend/src/middleware/categories.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
|
import CONFIG from '@src/config'
|
||||||
|
|
||||||
|
const checkCategoriesActive = (resolve, root, args, context, resolveInfo) => {
|
||||||
|
if (CONFIG.CATEGORIES_ACTIVE) {
|
||||||
|
return resolve(root, args, context, resolveInfo)
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
Query: {
|
||||||
|
Category: checkCategoriesActive,
|
||||||
|
},
|
||||||
|
}
|
||||||
@ -7,6 +7,7 @@ import CONFIG from '@config/index'
|
|||||||
|
|
||||||
// eslint-disable-next-line import/no-cycle
|
// eslint-disable-next-line import/no-cycle
|
||||||
import brandingMiddlewares from './branding/brandingMiddlewares'
|
import brandingMiddlewares from './branding/brandingMiddlewares'
|
||||||
|
import categories from './categories'
|
||||||
import chatMiddleware from './chatMiddleware'
|
import chatMiddleware from './chatMiddleware'
|
||||||
import excerpt from './excerptMiddleware'
|
import excerpt from './excerptMiddleware'
|
||||||
import hashtags from './hashtags/hashtagsMiddleware'
|
import hashtags from './hashtags/hashtagsMiddleware'
|
||||||
@ -46,6 +47,7 @@ const ocelotMiddlewares: MiddlewareOrder[] = [
|
|||||||
{ order: -80, name: 'includedFields', middleware: includedFields },
|
{ order: -80, name: 'includedFields', middleware: includedFields },
|
||||||
{ order: -70, name: 'orderBy', middleware: orderBy },
|
{ order: -70, name: 'orderBy', middleware: orderBy },
|
||||||
{ order: -60, name: 'chatMiddleware', middleware: chatMiddleware },
|
{ order: -60, name: 'chatMiddleware', middleware: chatMiddleware },
|
||||||
|
{ order: -50, name: 'categories', middleware: categories },
|
||||||
]
|
]
|
||||||
|
|
||||||
export default (schema) => {
|
export default (schema) => {
|
||||||
|
|||||||
@ -5,7 +5,6 @@ GRAPHQL_URI=http://localhost:4000/
|
|||||||
MAPBOX_TOKEN="pk.eyJ1IjoiYnVzZmFrdG9yIiwiYSI6ImNraDNiM3JxcDBhaWQydG1uczhpZWtpOW4ifQ.7TNRTO-o9aK1Y6MyW_Nd4g"
|
MAPBOX_TOKEN="pk.eyJ1IjoiYnVzZmFrdG9yIiwiYSI6ImNraDNiM3JxcDBhaWQydG1uczhpZWtpOW4ifQ.7TNRTO-o9aK1Y6MyW_Nd4g"
|
||||||
PUBLIC_REGISTRATION=false
|
PUBLIC_REGISTRATION=false
|
||||||
INVITE_REGISTRATION=true
|
INVITE_REGISTRATION=true
|
||||||
CATEGORIES_ACTIVE=false
|
|
||||||
BADGES_ENABLED=true
|
BADGES_ENABLED=true
|
||||||
INVITE_LINK_LIMIT=7
|
INVITE_LINK_LIMIT=7
|
||||||
NETWORK_NAME="Ocelot.social"
|
NETWORK_NAME="Ocelot.social"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
import CategoriesSelect from './CategoriesSelect'
|
import CategoriesSelect from './CategoriesSelect'
|
||||||
import Vue from 'vue'
|
import Vuex from 'vuex'
|
||||||
|
|
||||||
const localVue = global.localVue
|
const localVue = global.localVue
|
||||||
|
|
||||||
@ -12,7 +12,6 @@ describe('CategoriesSelect.vue', () => {
|
|||||||
let environmentAndNature
|
let environmentAndNature
|
||||||
let consumptionAndSustainablity
|
let consumptionAndSustainablity
|
||||||
|
|
||||||
const propsData = { model: 'categoryIds' }
|
|
||||||
const categories = [
|
const categories = [
|
||||||
{
|
{
|
||||||
id: 'cat9',
|
id: 'cat9',
|
||||||
@ -35,6 +34,20 @@ describe('CategoriesSelect.vue', () => {
|
|||||||
id: 'cat8',
|
id: 'cat8',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const propsData = { model: 'categoryIds' }
|
||||||
|
const categoriesMock = jest.fn().mockReturnValue(categories)
|
||||||
|
|
||||||
|
const storeMocks = {
|
||||||
|
getters: {
|
||||||
|
'categories/categories': categoriesMock,
|
||||||
|
'categories/isInitialized': jest.fn(() => true),
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
'categories/init': jest.fn(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
provide = {
|
provide = {
|
||||||
$parentForm: {
|
$parentForm: {
|
||||||
@ -48,7 +61,8 @@ describe('CategoriesSelect.vue', () => {
|
|||||||
|
|
||||||
describe('shallowMount', () => {
|
describe('shallowMount', () => {
|
||||||
const Wrapper = () => {
|
const Wrapper = () => {
|
||||||
return mount(CategoriesSelect, { propsData, mocks, localVue, provide })
|
const store = new Vuex.Store(storeMocks)
|
||||||
|
return mount(CategoriesSelect, { propsData, mocks, localVue, provide, store })
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -56,9 +70,7 @@ describe('CategoriesSelect.vue', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('toggleCategory', () => {
|
describe('toggleCategory', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(() => {
|
||||||
wrapper.vm.categories = categories
|
|
||||||
await Vue.nextTick()
|
|
||||||
democracyAndPolitics = wrapper.findAll('button').at(0)
|
democracyAndPolitics = wrapper.findAll('button').at(0)
|
||||||
democracyAndPolitics.trigger('click')
|
democracyAndPolitics.trigger('click')
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<section class="categories-select">
|
<section class="categories-select">
|
||||||
<base-button
|
<base-button
|
||||||
v-for="category in categories"
|
v-for="category in sortCategories(categories)"
|
||||||
:key="category.id"
|
:key="category.id"
|
||||||
:data-test="categoryButtonsId(category.id)"
|
:data-test="categoryButtonsId(category.id)"
|
||||||
@click="toggleCategory(category.id)"
|
@click="toggleCategory(category.id)"
|
||||||
@ -20,10 +20,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import CategoryQuery from '~/graphql/CategoryQuery'
|
|
||||||
import { CATEGORIES_MAX } from '~/constants/categories.js'
|
import { CATEGORIES_MAX } from '~/constants/categories.js'
|
||||||
import xor from 'lodash/xor'
|
import xor from 'lodash/xor'
|
||||||
import SortCategories from '~/mixins/sortCategoriesMixin.js'
|
import SortCategories from '~/mixins/sortCategoriesMixin.js'
|
||||||
|
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
inject: {
|
inject: {
|
||||||
@ -31,14 +31,13 @@ export default {
|
|||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mixins: [SortCategories],
|
mixins: [SortCategories, GetCategories],
|
||||||
props: {
|
props: {
|
||||||
existingCategoryIds: { type: Array, default: () => [] },
|
existingCategoryIds: { type: Array, default: () => [] },
|
||||||
model: { type: String, required: true },
|
model: { type: String, required: true },
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
categories: null,
|
|
||||||
selectedMax: CATEGORIES_MAX,
|
selectedMax: CATEGORIES_MAX,
|
||||||
selectedCategoryIds: this.existingCategoryIds,
|
selectedCategoryIds: this.existingCategoryIds,
|
||||||
}
|
}
|
||||||
@ -76,16 +75,6 @@ export default {
|
|||||||
return `category-buttons-${categoryId}`
|
return `category-buttons-${categoryId}`
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
apollo: {
|
|
||||||
Category: {
|
|
||||||
query() {
|
|
||||||
return CategoryQuery()
|
|
||||||
},
|
|
||||||
result({ data: { Category } }) {
|
|
||||||
this.categories = this.sortCategories(Category)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -37,7 +37,7 @@ describe('ContributionForm.vue', () => {
|
|||||||
const image = { sensitive: false, url: '/uploads/1562010976466-avataaars', aspectRatio: 1 }
|
const image = { sensitive: false, url: '/uploads/1562010976466-avataaars', aspectRatio: 1 }
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mocks = {
|
mocks = {
|
||||||
$t: jest.fn(),
|
$t: jest.fn((t) => t),
|
||||||
$apollo: {
|
$apollo: {
|
||||||
mutate: jest.fn().mockResolvedValueOnce({
|
mutate: jest.fn().mockResolvedValueOnce({
|
||||||
data: {
|
data: {
|
||||||
@ -62,9 +62,6 @@ describe('ContributionForm.vue', () => {
|
|||||||
back: jest.fn(),
|
back: jest.fn(),
|
||||||
push: jest.fn(),
|
push: jest.fn(),
|
||||||
},
|
},
|
||||||
$env: {
|
|
||||||
CATEGORIES_ACTIVE: false,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
propsData = {}
|
propsData = {}
|
||||||
})
|
})
|
||||||
@ -82,9 +79,13 @@ describe('ContributionForm.vue', () => {
|
|||||||
slug: 'you-yourself',
|
slug: 'you-yourself',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
'categories/categoriesActive': jest.fn(() => false),
|
||||||
}
|
}
|
||||||
const store = new Vuex.Store({
|
const store = new Vuex.Store({
|
||||||
getters,
|
getters,
|
||||||
|
actions: {
|
||||||
|
'categories/init': jest.fn(),
|
||||||
|
},
|
||||||
})
|
})
|
||||||
const Wrapper = () => {
|
const Wrapper = () => {
|
||||||
return mount(ContributionForm, {
|
return mount(ContributionForm, {
|
||||||
|
|||||||
@ -197,8 +197,10 @@ import links from '~/constants/links.js'
|
|||||||
import PageParamsLink from '~/components/_new/features/PageParamsLink/PageParamsLink.vue'
|
import PageParamsLink from '~/components/_new/features/PageParamsLink/PageParamsLink.vue'
|
||||||
import DatePicker from 'vue2-datepicker'
|
import DatePicker from 'vue2-datepicker'
|
||||||
import 'vue2-datepicker/scss/index.scss'
|
import 'vue2-datepicker/scss/index.scss'
|
||||||
|
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
mixins: [GetCategories],
|
||||||
components: {
|
components: {
|
||||||
Editor,
|
Editor,
|
||||||
ImageUploader,
|
ImageUploader,
|
||||||
@ -240,7 +242,6 @@ export default {
|
|||||||
type: imageType = null,
|
type: imageType = null,
|
||||||
} = image || {}
|
} = image || {}
|
||||||
return {
|
return {
|
||||||
categoriesActive: this.$env.CATEGORIES_ACTIVE,
|
|
||||||
links,
|
links,
|
||||||
formData: {
|
formData: {
|
||||||
title: title || '',
|
title: title || '',
|
||||||
|
|||||||
@ -13,6 +13,24 @@ describe('CategoriesFilter.vue', () => {
|
|||||||
}
|
}
|
||||||
const getters = {
|
const getters = {
|
||||||
'posts/filteredCategoryIds': jest.fn(() => []),
|
'posts/filteredCategoryIds': jest.fn(() => []),
|
||||||
|
'categories/categories': jest.fn().mockReturnValue([
|
||||||
|
{ id: 'cat4', name: 'Environment & Nature', icon: 'tree', slug: 'environment-nature' },
|
||||||
|
{
|
||||||
|
id: 'cat15',
|
||||||
|
name: 'Consumption & Sustainability',
|
||||||
|
icon: 'shopping-cart',
|
||||||
|
slug: 'consumption-sustainability',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'cat9',
|
||||||
|
name: 'Democracy & Politics',
|
||||||
|
icon: 'university',
|
||||||
|
slug: 'democracy-politics',
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
}
|
||||||
|
const actions = {
|
||||||
|
'categories/init': jest.fn(),
|
||||||
}
|
}
|
||||||
|
|
||||||
const apolloMutationMock = jest.fn().mockResolvedValue({
|
const apolloMutationMock = jest.fn().mockResolvedValue({
|
||||||
@ -31,25 +49,8 @@ describe('CategoriesFilter.vue', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Wrapper = () => {
|
const Wrapper = () => {
|
||||||
const store = new Vuex.Store({ mutations, getters })
|
const store = new Vuex.Store({ mutations, getters, actions })
|
||||||
const wrapper = mount(CategoriesFilter, { mocks, localVue, store })
|
const wrapper = mount(CategoriesFilter, { mocks, localVue, store })
|
||||||
wrapper.setData({
|
|
||||||
categories: [
|
|
||||||
{ id: 'cat4', name: 'Environment & Nature', icon: 'tree', slug: 'environment-nature' },
|
|
||||||
{
|
|
||||||
id: 'cat15',
|
|
||||||
name: 'Consumption & Sustainability',
|
|
||||||
icon: 'shopping-cart',
|
|
||||||
slug: 'consumption-sustainability',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'cat9',
|
|
||||||
name: 'Democracy & Politics',
|
|
||||||
icon: 'university',
|
|
||||||
slug: 'democracy-politics',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
return wrapper
|
return wrapper
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +76,7 @@ describe('CategoriesFilter.vue', () => {
|
|||||||
it('calls TOGGLE_CATEGORY when clicked', () => {
|
it('calls TOGGLE_CATEGORY when clicked', () => {
|
||||||
environmentAndNatureButton = wrapper.findAll('.category-filter-list .base-button').at(0)
|
environmentAndNatureButton = wrapper.findAll('.category-filter-list .base-button').at(0)
|
||||||
environmentAndNatureButton.trigger('click')
|
environmentAndNatureButton.trigger('click')
|
||||||
expect(mutations['posts/TOGGLE_CATEGORY']).toHaveBeenCalledWith({}, 'cat4')
|
expect(mutations['posts/TOGGLE_CATEGORY']).toHaveBeenCalledWith({}, 'cat15')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
<div class="category-filter-list">
|
<div class="category-filter-list">
|
||||||
<!-- <ds-space margin="small" /> -->
|
<!-- <ds-space margin="small" /> -->
|
||||||
<base-button
|
<base-button
|
||||||
v-for="category in categories"
|
v-for="category in sortCategories(categories)"
|
||||||
:key="category.id"
|
:key="category.id"
|
||||||
@click="saveCategories(category.id)"
|
@click="saveCategories(category.id)"
|
||||||
:filled="filteredCategoryIds.includes(category.id)"
|
:filled="filteredCategoryIds.includes(category.id)"
|
||||||
@ -35,20 +35,15 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters, mapMutations } from 'vuex'
|
import { mapGetters, mapMutations } from 'vuex'
|
||||||
import CategoryQuery from '~/graphql/CategoryQuery.js'
|
|
||||||
import FilterMenuSection from '~/components/FilterMenu/FilterMenuSection'
|
import FilterMenuSection from '~/components/FilterMenu/FilterMenuSection'
|
||||||
import SortCategories from '~/mixins/sortCategoriesMixin.js'
|
import SortCategories from '~/mixins/sortCategoriesMixin.js'
|
||||||
|
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
FilterMenuSection,
|
FilterMenuSection,
|
||||||
},
|
},
|
||||||
mixins: [SortCategories],
|
mixins: [SortCategories, GetCategories],
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
categories: [],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
...mapGetters({
|
||||||
filteredCategoryIds: 'posts/filteredCategoryIds',
|
filteredCategoryIds: 'posts/filteredCategoryIds',
|
||||||
@ -68,18 +63,6 @@ export default {
|
|||||||
this.$emit('updateCategories', categoryId)
|
this.$emit('updateCategories', categoryId)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
apollo: {
|
|
||||||
Category: {
|
|
||||||
query() {
|
|
||||||
return CategoryQuery()
|
|
||||||
},
|
|
||||||
update({ Category }) {
|
|
||||||
if (!Category) return []
|
|
||||||
this.categories = this.sortCategories(Category)
|
|
||||||
},
|
|
||||||
fetchPolicy: 'cache-and-network',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
@ -16,9 +16,11 @@
|
|||||||
import Dropdown from '~/components/Dropdown'
|
import Dropdown from '~/components/Dropdown'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import CategoriesFilter from './CategoriesFilter'
|
import CategoriesFilter from './CategoriesFilter'
|
||||||
|
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CategoriesMenu',
|
name: 'CategoriesMenu',
|
||||||
|
mixins: [GetCategories],
|
||||||
components: {
|
components: {
|
||||||
Dropdown,
|
Dropdown,
|
||||||
CategoriesFilter,
|
CategoriesFilter,
|
||||||
@ -27,11 +29,6 @@ export default {
|
|||||||
placement: { type: String },
|
placement: { type: String },
|
||||||
offset: { type: [String, Number] },
|
offset: { type: [String, Number] },
|
||||||
},
|
},
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
categoriesActive: this.$env.CATEGORIES_ACTIVE,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
...mapGetters({
|
||||||
// TODO: implement visibility of active filter later on
|
// TODO: implement visibility of active filter later on
|
||||||
|
|||||||
@ -8,15 +8,16 @@ let wrapper
|
|||||||
describe('FilterMenu.vue', () => {
|
describe('FilterMenu.vue', () => {
|
||||||
const mocks = {
|
const mocks = {
|
||||||
$t: jest.fn((string) => string),
|
$t: jest.fn((string) => string),
|
||||||
$env: {
|
|
||||||
CATEGORIES_ACTIVE: true,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const getters = {
|
const getters = {
|
||||||
'posts/isActive': () => false,
|
'posts/isActive': () => false,
|
||||||
'posts/filteredPostTypes': () => [],
|
'posts/filteredPostTypes': () => [],
|
||||||
'posts/orderBy': () => 'createdAt_desc',
|
'posts/orderBy': () => 'createdAt_desc',
|
||||||
|
'categories/categoriesActive': () => false,
|
||||||
|
}
|
||||||
|
const actions = {
|
||||||
|
'categories/init': jest.fn(),
|
||||||
}
|
}
|
||||||
|
|
||||||
const stubs = {
|
const stubs = {
|
||||||
@ -28,7 +29,7 @@ describe('FilterMenu.vue', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Wrapper = () => {
|
const Wrapper = () => {
|
||||||
const store = new Vuex.Store({ getters })
|
const store = new Vuex.Store({ getters, actions })
|
||||||
return mount(FilterMenu, { mocks, localVue, store, stubs })
|
return mount(FilterMenu, { mocks, localVue, store, stubs })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -36,8 +36,10 @@ import OrderByFilter from './OrderByFilter'
|
|||||||
import CategoriesFilter from './CategoriesFilter'
|
import CategoriesFilter from './CategoriesFilter'
|
||||||
import LabeledButton from '~/components/_new/generic/LabeledButton/LabeledButton'
|
import LabeledButton from '~/components/_new/generic/LabeledButton/LabeledButton'
|
||||||
import SaveCategories from '~/graphql/SaveCategories.js'
|
import SaveCategories from '~/graphql/SaveCategories.js'
|
||||||
|
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
mixins: [GetCategories],
|
||||||
components: {
|
components: {
|
||||||
EventsByFilter,
|
EventsByFilter,
|
||||||
FollowingFilter,
|
FollowingFilter,
|
||||||
@ -46,11 +48,6 @@ export default {
|
|||||||
PostTypeFilter,
|
PostTypeFilter,
|
||||||
LabeledButton,
|
LabeledButton,
|
||||||
},
|
},
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
categoriesActive: this.$env ? this.$env.CATEGORIES_ACTIVE : false,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
...mapGetters({
|
||||||
filteredPostTypes: 'posts/filteredPostTypes',
|
filteredPostTypes: 'posts/filteredPostTypes',
|
||||||
|
|||||||
@ -19,13 +19,16 @@ describe('FollowingFilter', () => {
|
|||||||
'posts/filteredByUsersFollowed': jest.fn(),
|
'posts/filteredByUsersFollowed': jest.fn(),
|
||||||
'posts/filteredByPostsInMyGroups': jest.fn(),
|
'posts/filteredByPostsInMyGroups': jest.fn(),
|
||||||
}
|
}
|
||||||
|
const actions = {
|
||||||
|
'categories/init': jest.fn(),
|
||||||
|
}
|
||||||
|
|
||||||
const mocks = {
|
const mocks = {
|
||||||
$t: jest.fn((string) => string),
|
$t: jest.fn((string) => string),
|
||||||
}
|
}
|
||||||
|
|
||||||
const Wrapper = () => {
|
const Wrapper = () => {
|
||||||
const store = new Vuex.Store({ mutations, getters })
|
const store = new Vuex.Store({ mutations, getters, actions })
|
||||||
const wrapper = mount(FollowingFilter, { mocks, localVue, store })
|
const wrapper = mount(FollowingFilter, { mocks, localVue, store })
|
||||||
return wrapper
|
return wrapper
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,13 +15,16 @@ describe('OrderByFilter', () => {
|
|||||||
'posts/orderedByCreationDate': () => true,
|
'posts/orderedByCreationDate': () => true,
|
||||||
'posts/orderBy': () => 'createdAt_desc',
|
'posts/orderBy': () => 'createdAt_desc',
|
||||||
}
|
}
|
||||||
|
const actions = {
|
||||||
|
'categories/init': jest.fn(),
|
||||||
|
}
|
||||||
|
|
||||||
const mocks = {
|
const mocks = {
|
||||||
$t: jest.fn((string) => string),
|
$t: jest.fn((string) => string),
|
||||||
}
|
}
|
||||||
|
|
||||||
const Wrapper = () => {
|
const Wrapper = () => {
|
||||||
const store = new Vuex.Store({ mutations, getters })
|
const store = new Vuex.Store({ mutations, getters, actions })
|
||||||
const wrapper = mount(OrderByFilter, { mocks, localVue, store })
|
const wrapper = mount(OrderByFilter, { mocks, localVue, store })
|
||||||
return wrapper
|
return wrapper
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
import GroupForm from './GroupForm.vue'
|
import GroupForm from './GroupForm.vue'
|
||||||
|
import Vuex from 'vuex'
|
||||||
|
|
||||||
const localVue = global.localVue
|
const localVue = global.localVue
|
||||||
|
|
||||||
@ -15,19 +16,27 @@ const propsData = {
|
|||||||
describe('GroupForm', () => {
|
describe('GroupForm', () => {
|
||||||
let wrapper
|
let wrapper
|
||||||
let mocks
|
let mocks
|
||||||
|
let storeMocks
|
||||||
|
let store
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mocks = {
|
mocks = {
|
||||||
$t: jest.fn(),
|
$t: jest.fn(),
|
||||||
$env: {
|
}
|
||||||
CATEGORIES_ACTIVE: true,
|
storeMocks = {
|
||||||
|
getters: {
|
||||||
|
'categories/categoriesActive': () => false,
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
'categories/init': jest.fn(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
store = new Vuex.Store(storeMocks)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('mount', () => {
|
describe('mount', () => {
|
||||||
const Wrapper = () => {
|
const Wrapper = () => {
|
||||||
return mount(GroupForm, { propsData, mocks, localVue, stubs })
|
return mount(GroupForm, { propsData, mocks, localVue, stubs, store })
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|||||||
@ -177,11 +177,13 @@ import {
|
|||||||
import Editor from '~/components/Editor/Editor'
|
import Editor from '~/components/Editor/Editor'
|
||||||
import ActionRadiusSelect from '~/components/Select/ActionRadiusSelect'
|
import ActionRadiusSelect from '~/components/Select/ActionRadiusSelect'
|
||||||
import { queryLocations } from '~/graphql/location'
|
import { queryLocations } from '~/graphql/location'
|
||||||
|
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||||
|
|
||||||
let timeout
|
let timeout
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'GroupForm',
|
name: 'GroupForm',
|
||||||
|
mixins: [GetCategories],
|
||||||
components: {
|
components: {
|
||||||
CategoriesSelect,
|
CategoriesSelect,
|
||||||
Editor,
|
Editor,
|
||||||
@ -203,7 +205,6 @@ export default {
|
|||||||
const { name, slug, groupType, about, description, actionRadius, locationName, categories } =
|
const { name, slug, groupType, about, description, actionRadius, locationName, categories } =
|
||||||
this.group
|
this.group
|
||||||
return {
|
return {
|
||||||
categoriesActive: this.$env.CATEGORIES_ACTIVE,
|
|
||||||
disabled: false,
|
disabled: false,
|
||||||
groupTypeOptions: ['public', 'closed', 'hidden'],
|
groupTypeOptions: ['public', 'closed', 'hidden'],
|
||||||
loadingGeo: false,
|
loadingGeo: false,
|
||||||
|
|||||||
@ -79,9 +79,11 @@
|
|||||||
<script>
|
<script>
|
||||||
import Category from '~/components/Category'
|
import Category from '~/components/Category'
|
||||||
import GroupContentMenu from '~/components/ContentMenu/GroupContentMenu'
|
import GroupContentMenu from '~/components/ContentMenu/GroupContentMenu'
|
||||||
|
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'GroupTeaser',
|
name: 'GroupTeaser',
|
||||||
|
mixins: [GetCategories],
|
||||||
components: {
|
components: {
|
||||||
Category,
|
Category,
|
||||||
GroupContentMenu,
|
GroupContentMenu,
|
||||||
@ -96,11 +98,6 @@ export default {
|
|||||||
default: () => {},
|
default: () => {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
categoriesActive: this.$env.CATEGORIES_ACTIVE,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
descriptionExcerpt() {
|
descriptionExcerpt() {
|
||||||
return this.$filters.removeLinks(this.group.descriptionExcerpt)
|
return this.$filters.removeLinks(this.group.descriptionExcerpt)
|
||||||
|
|||||||
@ -293,8 +293,10 @@ import SearchField from '~/components/features/SearchField/SearchField.vue'
|
|||||||
import NotificationMenu from '~/components/NotificationMenu/NotificationMenu'
|
import NotificationMenu from '~/components/NotificationMenu/NotificationMenu'
|
||||||
import links from '~/constants/links.js'
|
import links from '~/constants/links.js'
|
||||||
import PageParamsLink from '~/components/_new/features/PageParamsLink/PageParamsLink.vue'
|
import PageParamsLink from '~/components/_new/features/PageParamsLink/PageParamsLink.vue'
|
||||||
|
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
mixins: [GetCategories],
|
||||||
components: {
|
components: {
|
||||||
AvatarMenu,
|
AvatarMenu,
|
||||||
ChatNotificationMenu,
|
ChatNotificationMenu,
|
||||||
@ -327,7 +329,6 @@ export default {
|
|||||||
mobileSearchVisible: false,
|
mobileSearchVisible: false,
|
||||||
toggleMobileMenu: false,
|
toggleMobileMenu: false,
|
||||||
inviteRegistration: this.$env.INVITE_REGISTRATION === true, // for 'false' in .env INVITE_REGISTRATION is of type undefined and not(!) boolean false, because of internal handling,
|
inviteRegistration: this.$env.INVITE_REGISTRATION === true, // for 'false' in .env INVITE_REGISTRATION is of type undefined and not(!) boolean false, because of internal handling,
|
||||||
categoriesActive: this.$env.CATEGORIES_ACTIVE,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|||||||
@ -15,11 +15,9 @@ const stubs = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const authUserMock = jest.fn().mockReturnValue({ activeCategories: [] })
|
const authUserMock = jest.fn().mockReturnValue({ activeCategories: [] })
|
||||||
const apolloQueryMock = jest.fn().mockResolvedValue({
|
const categoriesMock = jest
|
||||||
data: {
|
.fn()
|
||||||
Category: [{ id: 'cat0' }, { id: 'cat1' }, { id: 'cat2' }, { id: 'cat3' }, { id: 'cat4' }],
|
.mockReturnValue([{ id: 'cat0' }, { id: 'cat1' }, { id: 'cat2' }, { id: 'cat3' }, { id: 'cat4' }])
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('LoginForm', () => {
|
describe('LoginForm', () => {
|
||||||
let mocks
|
let mocks
|
||||||
@ -36,6 +34,7 @@ describe('LoginForm', () => {
|
|||||||
getters: {
|
getters: {
|
||||||
'auth/pending': () => false,
|
'auth/pending': () => false,
|
||||||
'auth/user': authUserMock,
|
'auth/user': authUserMock,
|
||||||
|
'categories/categories': categoriesMock,
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
'auth/login': jest.fn(),
|
'auth/login': jest.fn(),
|
||||||
@ -52,9 +51,6 @@ describe('LoginForm', () => {
|
|||||||
success: jest.fn(),
|
success: jest.fn(),
|
||||||
error: jest.fn(),
|
error: jest.fn(),
|
||||||
},
|
},
|
||||||
$apollo: {
|
|
||||||
query: apolloQueryMock,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
return mount(LoginForm, { mocks, localVue, propsData, store, stubs })
|
return mount(LoginForm, { mocks, localVue, propsData, store, stubs })
|
||||||
}
|
}
|
||||||
|
|||||||
@ -59,7 +59,6 @@ import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch'
|
|||||||
import Logo from '~/components/Logo/Logo'
|
import Logo from '~/components/Logo/Logo'
|
||||||
import ShowPassword from '../ShowPassword/ShowPassword.vue'
|
import ShowPassword from '../ShowPassword/ShowPassword.vue'
|
||||||
import { mapGetters, mapMutations } from 'vuex'
|
import { mapGetters, mapMutations } from 'vuex'
|
||||||
import CategoryQuery from '~/graphql/CategoryQuery'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -88,6 +87,7 @@ export default {
|
|||||||
},
|
},
|
||||||
...mapGetters({
|
...mapGetters({
|
||||||
currentUser: 'auth/user',
|
currentUser: 'auth/user',
|
||||||
|
categories: 'categories/categories',
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -99,13 +99,9 @@ export default {
|
|||||||
const { email, password } = this.form
|
const { email, password } = this.form
|
||||||
try {
|
try {
|
||||||
await this.$store.dispatch('auth/login', { email, password })
|
await this.$store.dispatch('auth/login', { email, password })
|
||||||
const result = await this.$apollo.query({
|
|
||||||
query: CategoryQuery(),
|
|
||||||
})
|
|
||||||
const categories = result.data.Category
|
|
||||||
if (this.currentUser && this.currentUser.activeCategories) {
|
if (this.currentUser && this.currentUser.activeCategories) {
|
||||||
this.resetCategories()
|
this.resetCategories()
|
||||||
if (this.currentUser.activeCategories.length < categories.length) {
|
if (this.currentUser.activeCategories.length < this.categories.length) {
|
||||||
this.currentUser.activeCategories.forEach((categoryId) => {
|
this.currentUser.activeCategories.forEach((categoryId) => {
|
||||||
this.toggleCategory(categoryId)
|
this.toggleCategory(categoryId)
|
||||||
})
|
})
|
||||||
|
|||||||
@ -12,6 +12,7 @@ describe('PostTeaser', () => {
|
|||||||
let mocks
|
let mocks
|
||||||
let propsData
|
let propsData
|
||||||
let getters
|
let getters
|
||||||
|
let actions
|
||||||
let Wrapper
|
let Wrapper
|
||||||
let wrapper
|
let wrapper
|
||||||
|
|
||||||
@ -47,21 +48,22 @@ describe('PostTeaser', () => {
|
|||||||
data: { DeletePost: { id: 'deleted-post-id' } },
|
data: { DeletePost: { id: 'deleted-post-id' } },
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
$env: {
|
|
||||||
CATEGORIES_ACTIVE: false,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
getters = {
|
getters = {
|
||||||
'auth/isModerator': () => false,
|
'auth/isModerator': () => false,
|
||||||
'auth/user': () => {
|
'auth/user': () => {
|
||||||
return {}
|
return {}
|
||||||
},
|
},
|
||||||
|
'categories/categoriesActive': () => false,
|
||||||
|
}
|
||||||
|
actions = {
|
||||||
|
'categories/init': jest.fn(),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('shallowMount', () => {
|
describe('shallowMount', () => {
|
||||||
Wrapper = () => {
|
Wrapper = () => {
|
||||||
store = new Vuex.Store({ getters })
|
store = new Vuex.Store({ getters, actions })
|
||||||
return shallowMount(PostTeaser, {
|
return shallowMount(PostTeaser, {
|
||||||
store,
|
store,
|
||||||
propsData,
|
propsData,
|
||||||
@ -114,6 +116,7 @@ describe('PostTeaser', () => {
|
|||||||
Wrapper = () => {
|
Wrapper = () => {
|
||||||
const store = new Vuex.Store({
|
const store = new Vuex.Store({
|
||||||
getters,
|
getters,
|
||||||
|
actions,
|
||||||
})
|
})
|
||||||
return mount(PostTeaser, {
|
return mount(PostTeaser, {
|
||||||
stubs,
|
stubs,
|
||||||
|
|||||||
@ -137,9 +137,11 @@ import UserTeaser from '~/components/UserTeaser/UserTeaser'
|
|||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import PostMutations from '~/graphql/PostMutations'
|
import PostMutations from '~/graphql/PostMutations'
|
||||||
import { postMenuModalsData, deletePostMutation } from '~/components/utils/PostHelpers'
|
import { postMenuModalsData, deletePostMutation } from '~/components/utils/PostHelpers'
|
||||||
|
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PostTeaser',
|
name: 'PostTeaser',
|
||||||
|
mixins: [GetCategories],
|
||||||
components: {
|
components: {
|
||||||
Category,
|
Category,
|
||||||
ContentMenu,
|
ContentMenu,
|
||||||
@ -164,11 +166,6 @@ export default {
|
|||||||
default: () => {},
|
default: () => {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
categoriesActive: this.$env.CATEGORIES_ACTIVE,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
mounted() {
|
||||||
const { image } = this.post
|
const { image } = this.post
|
||||||
if (!image) return
|
if (!image) return
|
||||||
|
|||||||
@ -26,15 +26,13 @@ describe('SearchResults', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mocks = {
|
mocks = {
|
||||||
$t: jest.fn(),
|
$t: jest.fn(),
|
||||||
$env: {
|
|
||||||
CATEGORIES_ACTIVE: false,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
getters = {
|
getters = {
|
||||||
'auth/user': () => {
|
'auth/user': () => {
|
||||||
return { id: 'u343', name: 'Matt' }
|
return { id: 'u343', name: 'Matt' }
|
||||||
},
|
},
|
||||||
'auth/isModerator': () => false,
|
'auth/isModerator': () => false,
|
||||||
|
'categories/categoriesActive': () => false,
|
||||||
}
|
}
|
||||||
propsData = {
|
propsData = {
|
||||||
pageSize: 12,
|
pageSize: 12,
|
||||||
|
|||||||
@ -34,7 +34,6 @@ const options = {
|
|||||||
// Cookies
|
// Cookies
|
||||||
COOKIE_EXPIRE_TIME: process.env.COOKIE_EXPIRE_TIME || 730, // Two years by default
|
COOKIE_EXPIRE_TIME: process.env.COOKIE_EXPIRE_TIME || 730, // Two years by default
|
||||||
COOKIE_HTTPS_ONLY: process.env.COOKIE_HTTPS_ONLY || process.env.NODE_ENV === 'production', // ensure true in production if not set explicitly
|
COOKIE_HTTPS_ONLY: process.env.COOKIE_HTTPS_ONLY || process.env.NODE_ENV === 'production', // ensure true in production if not set explicitly
|
||||||
CATEGORIES_ACTIVE: process.env.CATEGORIES_ACTIVE === 'true' || false,
|
|
||||||
BADGES_ENABLED: process.env.BADGES_ENABLED === 'true' || false,
|
BADGES_ENABLED: process.env.BADGES_ENABLED === 'true' || false,
|
||||||
INVITE_LINK_LIMIT: process.env.INVITE_LINK_LIMIT || 7,
|
INVITE_LINK_LIMIT: process.env.INVITE_LINK_LIMIT || 7,
|
||||||
NETWORK_NAME: process.env.NETWORK_NAME || 'Ocelot.social',
|
NETWORK_NAME: process.env.NETWORK_NAME || 'Ocelot.social',
|
||||||
|
|||||||
@ -17,7 +17,7 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
coverageThreshold: {
|
coverageThreshold: {
|
||||||
global: {
|
global: {
|
||||||
lines: 83,
|
lines: 82,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
coverageProvider: 'v8',
|
coverageProvider: 'v8',
|
||||||
|
|||||||
19
webapp/mixins/getCategoriesMixin.js
Normal file
19
webapp/mixins/getCategoriesMixin.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { mapGetters, mapActions } from 'vuex'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
...mapGetters({
|
||||||
|
categories: 'categories/categories',
|
||||||
|
isInitialized: 'categories/isInitialized',
|
||||||
|
categoriesActive: 'categories/categoriesActive',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions({
|
||||||
|
storeInit: 'categories/init',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
async created() {
|
||||||
|
if (!this.storeIsInizialized) await this.storeInit()
|
||||||
|
},
|
||||||
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
import GroupProfileSlug from './_slug.vue'
|
import GroupProfileSlug from './_slug.vue'
|
||||||
import { render, screen, fireEvent } from '@testing-library/vue'
|
import { render, screen, fireEvent } from '@testing-library/vue'
|
||||||
|
import Vuex from 'vuex'
|
||||||
|
|
||||||
const localVue = global.localVue
|
const localVue = global.localVue
|
||||||
|
|
||||||
@ -32,11 +33,26 @@ describe('GroupProfileSlug', () => {
|
|||||||
let bobDerBaumeister
|
let bobDerBaumeister
|
||||||
let huey
|
let huey
|
||||||
|
|
||||||
|
const currentUserMock = jest.fn()
|
||||||
|
|
||||||
|
const getters = {
|
||||||
|
'auth/user': currentUserMock,
|
||||||
|
'auth/isModerator': () => false,
|
||||||
|
'categories/categoriesActive': () => true,
|
||||||
|
'categories/categories': () => [{ id: 'cat1' }],
|
||||||
|
}
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
'categories/init': jest.fn(),
|
||||||
|
}
|
||||||
|
|
||||||
|
const store = new Vuex.Store({
|
||||||
|
getters,
|
||||||
|
actions,
|
||||||
|
})
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mocks = {
|
mocks = {
|
||||||
$env: {
|
|
||||||
CATEGORIES_ACTIVE: true,
|
|
||||||
},
|
|
||||||
// post: {
|
// post: {
|
||||||
// id: 'p23',
|
// id: 'p23',
|
||||||
// name: 'It is a post',
|
// name: 'It is a post',
|
||||||
@ -213,6 +229,7 @@ describe('GroupProfileSlug', () => {
|
|||||||
localVue,
|
localVue,
|
||||||
data,
|
data,
|
||||||
stubs,
|
stubs,
|
||||||
|
store,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,12 +237,7 @@ describe('GroupProfileSlug', () => {
|
|||||||
describe('given a current user', () => {
|
describe('given a current user', () => {
|
||||||
describe('as group owner – "peter-lustig"', () => {
|
describe('as group owner – "peter-lustig"', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mocks.$store = {
|
currentUserMock.mockReturnValue(peterLustig)
|
||||||
getters: {
|
|
||||||
'auth/user': peterLustig,
|
|
||||||
'auth/isModerator': () => false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
wrapper = Wrapper(() => {
|
wrapper = Wrapper(() => {
|
||||||
return {
|
return {
|
||||||
Group: [
|
Group: [
|
||||||
@ -265,12 +277,7 @@ describe('GroupProfileSlug', () => {
|
|||||||
|
|
||||||
describe('as usual member – "jenny-rostock"', () => {
|
describe('as usual member – "jenny-rostock"', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mocks.$store = {
|
currentUserMock.mockReturnValue(jennyRostock)
|
||||||
getters: {
|
|
||||||
'auth/user': jennyRostock,
|
|
||||||
'auth/isModerator': () => false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
wrapper = Wrapper(() => {
|
wrapper = Wrapper(() => {
|
||||||
return {
|
return {
|
||||||
Group: [
|
Group: [
|
||||||
@ -291,12 +298,7 @@ describe('GroupProfileSlug', () => {
|
|||||||
|
|
||||||
describe('as pending member – "bob-der-baumeister"', () => {
|
describe('as pending member – "bob-der-baumeister"', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mocks.$store = {
|
currentUserMock.mockReturnValue(bobDerBaumeister)
|
||||||
getters: {
|
|
||||||
'auth/user': bobDerBaumeister,
|
|
||||||
'auth/isModerator': () => false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
wrapper = Wrapper(() => {
|
wrapper = Wrapper(() => {
|
||||||
return {
|
return {
|
||||||
Group: [
|
Group: [
|
||||||
@ -317,12 +319,7 @@ describe('GroupProfileSlug', () => {
|
|||||||
|
|
||||||
describe('as none(!) member – "huey"', () => {
|
describe('as none(!) member – "huey"', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mocks.$store = {
|
currentUserMock.mockReturnValue(huey)
|
||||||
getters: {
|
|
||||||
'auth/user': huey,
|
|
||||||
'auth/isModerator': () => false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
wrapper = Wrapper(() => {
|
wrapper = Wrapper(() => {
|
||||||
return {
|
return {
|
||||||
Group: [
|
Group: [
|
||||||
@ -346,12 +343,7 @@ describe('GroupProfileSlug', () => {
|
|||||||
describe('given a current user', () => {
|
describe('given a current user', () => {
|
||||||
describe('as group owner – "peter-lustig"', () => {
|
describe('as group owner – "peter-lustig"', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mocks.$store = {
|
currentUserMock.mockReturnValue(peterLustig)
|
||||||
getters: {
|
|
||||||
'auth/user': peterLustig,
|
|
||||||
'auth/isModerator': () => false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
wrapper = Wrapper(() => {
|
wrapper = Wrapper(() => {
|
||||||
return {
|
return {
|
||||||
Group: [
|
Group: [
|
||||||
@ -372,12 +364,7 @@ describe('GroupProfileSlug', () => {
|
|||||||
|
|
||||||
describe('as usual member – "jenny-rostock"', () => {
|
describe('as usual member – "jenny-rostock"', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mocks.$store = {
|
currentUserMock.mockReturnValue(jennyRostock)
|
||||||
getters: {
|
|
||||||
'auth/user': jennyRostock,
|
|
||||||
'auth/isModerator': () => false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
wrapper = Wrapper(() => {
|
wrapper = Wrapper(() => {
|
||||||
return {
|
return {
|
||||||
Group: [
|
Group: [
|
||||||
@ -421,12 +408,7 @@ describe('GroupProfileSlug', () => {
|
|||||||
|
|
||||||
describe('as pending member – "bob-der-baumeister"', () => {
|
describe('as pending member – "bob-der-baumeister"', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mocks.$store = {
|
currentUserMock.mockReturnValue(bobDerBaumeister)
|
||||||
getters: {
|
|
||||||
'auth/user': bobDerBaumeister,
|
|
||||||
'auth/isModerator': () => false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
wrapper = Wrapper(() => {
|
wrapper = Wrapper(() => {
|
||||||
return {
|
return {
|
||||||
Group: [
|
Group: [
|
||||||
@ -447,12 +429,7 @@ describe('GroupProfileSlug', () => {
|
|||||||
|
|
||||||
describe('as none(!) member – "huey"', () => {
|
describe('as none(!) member – "huey"', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mocks.$store = {
|
currentUserMock.mockReturnValue(huey)
|
||||||
getters: {
|
|
||||||
'auth/user': huey,
|
|
||||||
'auth/isModerator': () => false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
wrapper = Wrapper(() => {
|
wrapper = Wrapper(() => {
|
||||||
return {
|
return {
|
||||||
Group: [
|
Group: [
|
||||||
@ -477,12 +454,7 @@ describe('GroupProfileSlug', () => {
|
|||||||
describe('given a current user', () => {
|
describe('given a current user', () => {
|
||||||
describe('as group owner – "peter-lustig"', () => {
|
describe('as group owner – "peter-lustig"', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mocks.$store = {
|
currentUserMock.mockReturnValue(peterLustig)
|
||||||
getters: {
|
|
||||||
'auth/user': peterLustig,
|
|
||||||
'auth/isModerator': () => false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
wrapper = Wrapper(() => {
|
wrapper = Wrapper(() => {
|
||||||
return {
|
return {
|
||||||
Group: [
|
Group: [
|
||||||
@ -503,12 +475,7 @@ describe('GroupProfileSlug', () => {
|
|||||||
|
|
||||||
describe('as usual member – "jenny-rostock"', () => {
|
describe('as usual member – "jenny-rostock"', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mocks.$store = {
|
currentUserMock.mockReturnValue(jennyRostock)
|
||||||
getters: {
|
|
||||||
'auth/user': jennyRostock,
|
|
||||||
'auth/isModerator': () => false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
wrapper = Wrapper(() => {
|
wrapper = Wrapper(() => {
|
||||||
return {
|
return {
|
||||||
Group: [
|
Group: [
|
||||||
@ -529,12 +496,7 @@ describe('GroupProfileSlug', () => {
|
|||||||
|
|
||||||
describe('as pending member – "bob-der-baumeister"', () => {
|
describe('as pending member – "bob-der-baumeister"', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mocks.$store = {
|
currentUserMock.mockReturnValue(bobDerBaumeister)
|
||||||
getters: {
|
|
||||||
'auth/user': bobDerBaumeister,
|
|
||||||
'auth/isModerator': () => false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
wrapper = Wrapper(() => {
|
wrapper = Wrapper(() => {
|
||||||
return {
|
return {
|
||||||
Group: [
|
Group: [
|
||||||
@ -555,12 +517,7 @@ describe('GroupProfileSlug', () => {
|
|||||||
|
|
||||||
describe('as none(!) member – "huey"', () => {
|
describe('as none(!) member – "huey"', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mocks.$store = {
|
currentUserMock.mockReturnValue(huey)
|
||||||
getters: {
|
|
||||||
'auth/user': huey,
|
|
||||||
'auth/isModerator': () => false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
wrapper = Wrapper(() => {
|
wrapper = Wrapper(() => {
|
||||||
return {
|
return {
|
||||||
Group: [
|
Group: [
|
||||||
|
|||||||
@ -316,6 +316,8 @@ import PostTeaser from '~/components/PostTeaser/PostTeaser.vue'
|
|||||||
import ProfileAvatar from '~/components/_new/generic/ProfileAvatar/ProfileAvatar'
|
import ProfileAvatar from '~/components/_new/generic/ProfileAvatar/ProfileAvatar'
|
||||||
import ProfileList from '~/components/features/ProfileList/ProfileList'
|
import ProfileList from '~/components/features/ProfileList/ProfileList'
|
||||||
import SortCategories from '~/mixins/sortCategoriesMixin.js'
|
import SortCategories from '~/mixins/sortCategoriesMixin.js'
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||||
// import SocialMedia from '~/components/SocialMedia/SocialMedia'
|
// import SocialMedia from '~/components/SocialMedia/SocialMedia'
|
||||||
// import TabNavigation from '~/components/_new/generic/TabNavigation/TabNavigation'
|
// import TabNavigation from '~/components/_new/generic/TabNavigation/TabNavigation'
|
||||||
|
|
||||||
@ -346,7 +348,7 @@ export default {
|
|||||||
// SocialMedia,
|
// SocialMedia,
|
||||||
// TabNavigation,
|
// TabNavigation,
|
||||||
},
|
},
|
||||||
mixins: [postListActions, SortCategories],
|
mixins: [postListActions, SortCategories, GetCategories],
|
||||||
transition: {
|
transition: {
|
||||||
name: 'slide-up',
|
name: 'slide-up',
|
||||||
mode: 'out-in',
|
mode: 'out-in',
|
||||||
@ -360,7 +362,6 @@ export default {
|
|||||||
// const filter = tabToFilterMapping({ tab: 'post', id: this.$route.params.id })
|
// const filter = tabToFilterMapping({ tab: 'post', id: this.$route.params.id })
|
||||||
const filter = { group: { id: this.$route.params.id } }
|
const filter = { group: { id: this.$route.params.id } }
|
||||||
return {
|
return {
|
||||||
categoriesActive: this.$env.CATEGORIES_ACTIVE,
|
|
||||||
loadGroupMembers: false,
|
loadGroupMembers: false,
|
||||||
posts: [],
|
posts: [],
|
||||||
hasMore: true,
|
hasMore: true,
|
||||||
@ -378,9 +379,9 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
currentUser() {
|
...mapGetters({
|
||||||
return this.$store.getters['auth/user']
|
currentUser: 'auth/user',
|
||||||
},
|
}),
|
||||||
group() {
|
group() {
|
||||||
return this.Group && this.Group[0] ? this.Group[0] : {}
|
return this.Group && this.Group[0] ? this.Group[0] : {}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -36,8 +36,13 @@ describe('PostIndex', () => {
|
|||||||
'auth/user': () => {
|
'auth/user': () => {
|
||||||
return { id: 'u23' }
|
return { id: 'u23' }
|
||||||
},
|
},
|
||||||
|
'categories/categoriesActive': () => true,
|
||||||
|
'categories/categories': () => ['cat1', 'cat2', 'cat3'],
|
||||||
},
|
},
|
||||||
mutations,
|
mutations,
|
||||||
|
actions: {
|
||||||
|
'categories/init': jest.fn(),
|
||||||
|
},
|
||||||
})
|
})
|
||||||
mocks = {
|
mocks = {
|
||||||
$t: (key) => key,
|
$t: (key) => key,
|
||||||
@ -79,9 +84,6 @@ describe('PostIndex', () => {
|
|||||||
$route: {
|
$route: {
|
||||||
query: {},
|
query: {},
|
||||||
},
|
},
|
||||||
$env: {
|
|
||||||
CATEGORIES_ACTIVE: true,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -155,6 +155,7 @@ import UpdateQuery from '~/components/utils/UpdateQuery'
|
|||||||
import FilterMenuComponent from '~/components/FilterMenu/FilterMenuComponent'
|
import FilterMenuComponent from '~/components/FilterMenu/FilterMenuComponent'
|
||||||
import { SHOW_CONTENT_FILTER_MASONRY_GRID } from '~/constants/filter.js'
|
import { SHOW_CONTENT_FILTER_MASONRY_GRID } from '~/constants/filter.js'
|
||||||
import { POST_ADD_BUTTON_POSITION_TOP } from '~/constants/posts.js'
|
import { POST_ADD_BUTTON_POSITION_TOP } from '~/constants/posts.js'
|
||||||
|
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -167,7 +168,7 @@ export default {
|
|||||||
FilterMenuComponent,
|
FilterMenuComponent,
|
||||||
HeaderButton,
|
HeaderButton,
|
||||||
},
|
},
|
||||||
mixins: [postListActions, mobile()],
|
mixins: [postListActions, mobile(), GetCategories],
|
||||||
data() {
|
data() {
|
||||||
const { hashtag = null } = this.$route.query
|
const { hashtag = null } = this.$route.query
|
||||||
return {
|
return {
|
||||||
@ -184,7 +185,6 @@ export default {
|
|||||||
offset: 0,
|
offset: 0,
|
||||||
pageSize: 12,
|
pageSize: 12,
|
||||||
hashtag,
|
hashtag,
|
||||||
categoriesActive: this.$env.CATEGORIES_ACTIVE,
|
|
||||||
SHOW_CONTENT_FILTER_MASONRY_GRID,
|
SHOW_CONTENT_FILTER_MASONRY_GRID,
|
||||||
POST_ADD_BUTTON_POSITION_TOP,
|
POST_ADD_BUTTON_POSITION_TOP,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,6 +42,10 @@ describe('PostSlug', () => {
|
|||||||
return { id: '1stUser' }
|
return { id: '1stUser' }
|
||||||
},
|
},
|
||||||
'auth/isModerator': () => false,
|
'auth/isModerator': () => false,
|
||||||
|
'categories/categoriesActive': () => false,
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
'categories/init': jest.fn(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
const propsData = {}
|
const propsData = {}
|
||||||
@ -73,9 +77,6 @@ describe('PostSlug', () => {
|
|||||||
query: jest.fn().mockResolvedValue({ data: { PostEmotionsCountByEmotion: {} } }),
|
query: jest.fn().mockResolvedValue({ data: { PostEmotionsCountByEmotion: {} } }),
|
||||||
},
|
},
|
||||||
$scrollTo: jest.fn(),
|
$scrollTo: jest.fn(),
|
||||||
$env: {
|
|
||||||
CATEGORIES_ACTIVE: false,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
stubs = {
|
stubs = {
|
||||||
'client-only': true,
|
'client-only': true,
|
||||||
|
|||||||
@ -182,6 +182,7 @@ import { groupQuery } from '~/graphql/groups'
|
|||||||
import PostMutations from '~/graphql/PostMutations'
|
import PostMutations from '~/graphql/PostMutations'
|
||||||
import links from '~/constants/links.js'
|
import links from '~/constants/links.js'
|
||||||
import SortCategories from '~/mixins/sortCategoriesMixin.js'
|
import SortCategories from '~/mixins/sortCategoriesMixin.js'
|
||||||
|
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PostSlug',
|
name: 'PostSlug',
|
||||||
@ -203,7 +204,7 @@ export default {
|
|||||||
PageParamsLink,
|
PageParamsLink,
|
||||||
UserTeaser,
|
UserTeaser,
|
||||||
},
|
},
|
||||||
mixins: [SortCategories],
|
mixins: [SortCategories, GetCategories],
|
||||||
head() {
|
head() {
|
||||||
return {
|
return {
|
||||||
title: this.title,
|
title: this.title,
|
||||||
@ -219,7 +220,6 @@ export default {
|
|||||||
blurred: false,
|
blurred: false,
|
||||||
blocked: null,
|
blocked: null,
|
||||||
postAuthor: null,
|
postAuthor: null,
|
||||||
categoriesActive: this.$env.CATEGORIES_ACTIVE,
|
|
||||||
group: null,
|
group: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
import create from './create.vue'
|
import create from './create.vue'
|
||||||
|
import Vuex from 'vuex'
|
||||||
|
|
||||||
const localVue = global.localVue
|
const localVue = global.localVue
|
||||||
|
|
||||||
@ -8,9 +9,6 @@ describe('create.vue', () => {
|
|||||||
|
|
||||||
const mocks = {
|
const mocks = {
|
||||||
$t: jest.fn(),
|
$t: jest.fn(),
|
||||||
$env: {
|
|
||||||
CATEGORIES_ACTIVE: false,
|
|
||||||
},
|
|
||||||
$route: {
|
$route: {
|
||||||
query: {
|
query: {
|
||||||
groupId: null,
|
groupId: null,
|
||||||
@ -23,8 +21,14 @@ describe('create.vue', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe('mount', () => {
|
describe('mount', () => {
|
||||||
|
const store = new Vuex.Store({
|
||||||
|
getters: {
|
||||||
|
'categories/categoriesActive': () => false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
const Wrapper = () => {
|
const Wrapper = () => {
|
||||||
return mount(create, { mocks, localVue, stubs })
|
return mount(create, { mocks, localVue, stubs, store })
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|||||||
@ -39,15 +39,17 @@ describe('post/_id.vue', () => {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
$env: {
|
|
||||||
CATEGORIES_ACTIVE: false,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
store = new Vuex.Store({
|
store = new Vuex.Store({
|
||||||
getters: {
|
getters: {
|
||||||
'auth/user': () => {
|
'auth/user': () => {
|
||||||
return { id: userId }
|
return { id: userId }
|
||||||
},
|
},
|
||||||
|
'categories/categories': jest.fn(() => []),
|
||||||
|
'categories/categoriesActive': () => false,
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
'categories/init': jest.fn(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if (asyncData) {
|
if (asyncData) {
|
||||||
|
|||||||
@ -106,6 +106,7 @@ export const actions = {
|
|||||||
await this.app.$apolloHelpers.onLogin(login)
|
await this.app.$apolloHelpers.onLogin(login)
|
||||||
commit('SET_TOKEN', login)
|
commit('SET_TOKEN', login)
|
||||||
await dispatch('fetchCurrentUser')
|
await dispatch('fetchCurrentUser')
|
||||||
|
await dispatch('categories/init', null, { root: true })
|
||||||
if (cookies.get(metadata.COOKIE_NAME) === undefined) {
|
if (cookies.get(metadata.COOKIE_NAME) === undefined) {
|
||||||
throw new Error('no-cookie')
|
throw new Error('no-cookie')
|
||||||
}
|
}
|
||||||
|
|||||||
@ -175,8 +175,11 @@ describe('actions', () => {
|
|||||||
expect(commit.mock.calls).toEqual(expect.arrayContaining([['SET_TOKEN', token]]))
|
expect(commit.mock.calls).toEqual(expect.arrayContaining([['SET_TOKEN', token]]))
|
||||||
})
|
})
|
||||||
|
|
||||||
it('fetches the user', () => {
|
it('fetches the user and initializes categories', () => {
|
||||||
expect(dispatch.mock.calls).toEqual([['fetchCurrentUser']])
|
expect(dispatch.mock.calls).toEqual([
|
||||||
|
['fetchCurrentUser'],
|
||||||
|
['categories/init', null, { root: true }],
|
||||||
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
it('saves pending flags in order', () => {
|
it('saves pending flags in order', () => {
|
||||||
|
|||||||
44
webapp/store/categories.js
Normal file
44
webapp/store/categories.js
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import CategoryQuery from '~/graphql/CategoryQuery'
|
||||||
|
|
||||||
|
export const state = () => {
|
||||||
|
return {
|
||||||
|
categories: [],
|
||||||
|
isInitialized: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mutations = {
|
||||||
|
SET_CATEGORIES(state, categories) {
|
||||||
|
state.categories = categories || []
|
||||||
|
},
|
||||||
|
SET_INIZIALIZED(state) {
|
||||||
|
state.isInitialized = true
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getters = {
|
||||||
|
categories(state) {
|
||||||
|
return state.categories
|
||||||
|
},
|
||||||
|
categoriesActive(state) {
|
||||||
|
return !!state.categories.length
|
||||||
|
},
|
||||||
|
isInitialized(state) {
|
||||||
|
return state.isInitialized
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export const actions = {
|
||||||
|
async init({ commit }) {
|
||||||
|
try {
|
||||||
|
const client = this.app.apolloProvider.defaultClient
|
||||||
|
const {
|
||||||
|
data: { Category: categories },
|
||||||
|
} = await client.query({ query: CategoryQuery() })
|
||||||
|
commit('SET_CATEGORIES', categories)
|
||||||
|
commit('SET_INIZIALIZED')
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error('Could not query categories')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
105
webapp/store/categories.spec.js
Normal file
105
webapp/store/categories.spec.js
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
import { state, mutations, getters, actions } from './categories'
|
||||||
|
import CategoryQuery from '~/graphql/CategoryQuery'
|
||||||
|
|
||||||
|
describe('categories store', () => {
|
||||||
|
describe('initial state', () => {
|
||||||
|
it('sets no categories and is not inizialized', () => {
|
||||||
|
expect(state()).toEqual({
|
||||||
|
categories: [],
|
||||||
|
isInitialized: false,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('getters', () => {
|
||||||
|
describe('categoriesActive', () => {
|
||||||
|
it('returns true if there are categories', () => {
|
||||||
|
const state = { categories: ['cat1', 'cat2'] }
|
||||||
|
expect(getters.categoriesActive(state)).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('returns false if there are no categories', () => {
|
||||||
|
const state = { categories: [] }
|
||||||
|
expect(getters.categoriesActive(state)).toBe(false)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('mutations', () => {
|
||||||
|
let testMutation
|
||||||
|
|
||||||
|
describe('SET_CATEGORIES', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
testMutation = (categories) => {
|
||||||
|
mutations.SET_CATEGORIES(state, categories)
|
||||||
|
return getters.categories(state)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('sets categories to [] if value is undefined', () => {
|
||||||
|
expect(testMutation(undefined)).toEqual([])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('sets categories correctly', () => {
|
||||||
|
expect(testMutation(['cat1', 'cat2', 'cat3'])).toEqual(['cat1', 'cat2', 'cat3'])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('SET_INIZIALIZED', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
testMutation = () => {
|
||||||
|
mutations.SET_INIZIALIZED(state)
|
||||||
|
return getters.isInitialized(state)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('sets isInitialized to true', () => {
|
||||||
|
expect(testMutation()).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('actions', () => {
|
||||||
|
const queryMock = jest.fn().mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
Category: ['cat1', 'cat2', 'cat3'],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const commit = jest.fn()
|
||||||
|
|
||||||
|
let action
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
const module = {
|
||||||
|
app: {
|
||||||
|
apolloProvider: {
|
||||||
|
defaultClient: {
|
||||||
|
query: queryMock,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
action = actions.init.bind(module)
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('init', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await action({ commit })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('calls apollo', () => {
|
||||||
|
expect(queryMock).toBeCalledWith({
|
||||||
|
query: CategoryQuery(),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('commits SET_CATEGORIES', () => {
|
||||||
|
expect(commit).toBeCalledWith('SET_CATEGORIES', ['cat1', 'cat2', 'cat3'])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('commits SET_INIZIALIZED', () => {
|
||||||
|
expect(commit).toBeCalledWith('SET_INIZIALIZED')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
Loading…
x
Reference in New Issue
Block a user