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
|
||||
import brandingMiddlewares from './branding/brandingMiddlewares'
|
||||
import categories from './categories'
|
||||
import chatMiddleware from './chatMiddleware'
|
||||
import excerpt from './excerptMiddleware'
|
||||
import hashtags from './hashtags/hashtagsMiddleware'
|
||||
@ -46,6 +47,7 @@ const ocelotMiddlewares: MiddlewareOrder[] = [
|
||||
{ order: -80, name: 'includedFields', middleware: includedFields },
|
||||
{ order: -70, name: 'orderBy', middleware: orderBy },
|
||||
{ order: -60, name: 'chatMiddleware', middleware: chatMiddleware },
|
||||
{ order: -50, name: 'categories', middleware: categories },
|
||||
]
|
||||
|
||||
export default (schema) => {
|
||||
|
||||
@ -5,7 +5,6 @@ GRAPHQL_URI=http://localhost:4000/
|
||||
MAPBOX_TOKEN="pk.eyJ1IjoiYnVzZmFrdG9yIiwiYSI6ImNraDNiM3JxcDBhaWQydG1uczhpZWtpOW4ifQ.7TNRTO-o9aK1Y6MyW_Nd4g"
|
||||
PUBLIC_REGISTRATION=false
|
||||
INVITE_REGISTRATION=true
|
||||
CATEGORIES_ACTIVE=false
|
||||
BADGES_ENABLED=true
|
||||
INVITE_LINK_LIMIT=7
|
||||
NETWORK_NAME="Ocelot.social"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
import CategoriesSelect from './CategoriesSelect'
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
@ -12,7 +12,6 @@ describe('CategoriesSelect.vue', () => {
|
||||
let environmentAndNature
|
||||
let consumptionAndSustainablity
|
||||
|
||||
const propsData = { model: 'categoryIds' }
|
||||
const categories = [
|
||||
{
|
||||
id: 'cat9',
|
||||
@ -35,6 +34,20 @@ describe('CategoriesSelect.vue', () => {
|
||||
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(() => {
|
||||
provide = {
|
||||
$parentForm: {
|
||||
@ -48,7 +61,8 @@ describe('CategoriesSelect.vue', () => {
|
||||
|
||||
describe('shallowMount', () => {
|
||||
const Wrapper = () => {
|
||||
return mount(CategoriesSelect, { propsData, mocks, localVue, provide })
|
||||
const store = new Vuex.Store(storeMocks)
|
||||
return mount(CategoriesSelect, { propsData, mocks, localVue, provide, store })
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
@ -56,9 +70,7 @@ describe('CategoriesSelect.vue', () => {
|
||||
})
|
||||
|
||||
describe('toggleCategory', () => {
|
||||
beforeEach(async () => {
|
||||
wrapper.vm.categories = categories
|
||||
await Vue.nextTick()
|
||||
beforeEach(() => {
|
||||
democracyAndPolitics = wrapper.findAll('button').at(0)
|
||||
democracyAndPolitics.trigger('click')
|
||||
})
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<section class="categories-select">
|
||||
<base-button
|
||||
v-for="category in categories"
|
||||
v-for="category in sortCategories(categories)"
|
||||
:key="category.id"
|
||||
:data-test="categoryButtonsId(category.id)"
|
||||
@click="toggleCategory(category.id)"
|
||||
@ -20,10 +20,10 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CategoryQuery from '~/graphql/CategoryQuery'
|
||||
import { CATEGORIES_MAX } from '~/constants/categories.js'
|
||||
import xor from 'lodash/xor'
|
||||
import SortCategories from '~/mixins/sortCategoriesMixin.js'
|
||||
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||
|
||||
export default {
|
||||
inject: {
|
||||
@ -31,14 +31,13 @@ export default {
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
mixins: [SortCategories],
|
||||
mixins: [SortCategories, GetCategories],
|
||||
props: {
|
||||
existingCategoryIds: { type: Array, default: () => [] },
|
||||
model: { type: String, required: true },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
categories: null,
|
||||
selectedMax: CATEGORIES_MAX,
|
||||
selectedCategoryIds: this.existingCategoryIds,
|
||||
}
|
||||
@ -76,16 +75,6 @@ export default {
|
||||
return `category-buttons-${categoryId}`
|
||||
},
|
||||
},
|
||||
apollo: {
|
||||
Category: {
|
||||
query() {
|
||||
return CategoryQuery()
|
||||
},
|
||||
result({ data: { Category } }) {
|
||||
this.categories = this.sortCategories(Category)
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@ describe('ContributionForm.vue', () => {
|
||||
const image = { sensitive: false, url: '/uploads/1562010976466-avataaars', aspectRatio: 1 }
|
||||
beforeEach(() => {
|
||||
mocks = {
|
||||
$t: jest.fn(),
|
||||
$t: jest.fn((t) => t),
|
||||
$apollo: {
|
||||
mutate: jest.fn().mockResolvedValueOnce({
|
||||
data: {
|
||||
@ -62,9 +62,6 @@ describe('ContributionForm.vue', () => {
|
||||
back: jest.fn(),
|
||||
push: jest.fn(),
|
||||
},
|
||||
$env: {
|
||||
CATEGORIES_ACTIVE: false,
|
||||
},
|
||||
}
|
||||
propsData = {}
|
||||
})
|
||||
@ -82,9 +79,13 @@ describe('ContributionForm.vue', () => {
|
||||
slug: 'you-yourself',
|
||||
}
|
||||
},
|
||||
'categories/categoriesActive': jest.fn(() => false),
|
||||
}
|
||||
const store = new Vuex.Store({
|
||||
getters,
|
||||
actions: {
|
||||
'categories/init': jest.fn(),
|
||||
},
|
||||
})
|
||||
const Wrapper = () => {
|
||||
return mount(ContributionForm, {
|
||||
|
||||
@ -197,8 +197,10 @@ import links from '~/constants/links.js'
|
||||
import PageParamsLink from '~/components/_new/features/PageParamsLink/PageParamsLink.vue'
|
||||
import DatePicker from 'vue2-datepicker'
|
||||
import 'vue2-datepicker/scss/index.scss'
|
||||
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||
|
||||
export default {
|
||||
mixins: [GetCategories],
|
||||
components: {
|
||||
Editor,
|
||||
ImageUploader,
|
||||
@ -240,7 +242,6 @@ export default {
|
||||
type: imageType = null,
|
||||
} = image || {}
|
||||
return {
|
||||
categoriesActive: this.$env.CATEGORIES_ACTIVE,
|
||||
links,
|
||||
formData: {
|
||||
title: title || '',
|
||||
|
||||
@ -13,6 +13,24 @@ describe('CategoriesFilter.vue', () => {
|
||||
}
|
||||
const getters = {
|
||||
'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({
|
||||
@ -31,25 +49,8 @@ describe('CategoriesFilter.vue', () => {
|
||||
}
|
||||
|
||||
const Wrapper = () => {
|
||||
const store = new Vuex.Store({ mutations, getters })
|
||||
const store = new Vuex.Store({ mutations, getters, actions })
|
||||
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
|
||||
}
|
||||
|
||||
@ -75,7 +76,7 @@ describe('CategoriesFilter.vue', () => {
|
||||
it('calls TOGGLE_CATEGORY when clicked', () => {
|
||||
environmentAndNatureButton = wrapper.findAll('.category-filter-list .base-button').at(0)
|
||||
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">
|
||||
<!-- <ds-space margin="small" /> -->
|
||||
<base-button
|
||||
v-for="category in categories"
|
||||
v-for="category in sortCategories(categories)"
|
||||
:key="category.id"
|
||||
@click="saveCategories(category.id)"
|
||||
:filled="filteredCategoryIds.includes(category.id)"
|
||||
@ -35,20 +35,15 @@
|
||||
|
||||
<script>
|
||||
import { mapGetters, mapMutations } from 'vuex'
|
||||
import CategoryQuery from '~/graphql/CategoryQuery.js'
|
||||
import FilterMenuSection from '~/components/FilterMenu/FilterMenuSection'
|
||||
import SortCategories from '~/mixins/sortCategoriesMixin.js'
|
||||
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
FilterMenuSection,
|
||||
},
|
||||
mixins: [SortCategories],
|
||||
data() {
|
||||
return {
|
||||
categories: [],
|
||||
}
|
||||
},
|
||||
mixins: [SortCategories, GetCategories],
|
||||
computed: {
|
||||
...mapGetters({
|
||||
filteredCategoryIds: 'posts/filteredCategoryIds',
|
||||
@ -68,18 +63,6 @@ export default {
|
||||
this.$emit('updateCategories', categoryId)
|
||||
},
|
||||
},
|
||||
apollo: {
|
||||
Category: {
|
||||
query() {
|
||||
return CategoryQuery()
|
||||
},
|
||||
update({ Category }) {
|
||||
if (!Category) return []
|
||||
this.categories = this.sortCategories(Category)
|
||||
},
|
||||
fetchPolicy: 'cache-and-network',
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
|
||||
@ -16,9 +16,11 @@
|
||||
import Dropdown from '~/components/Dropdown'
|
||||
import { mapGetters } from 'vuex'
|
||||
import CategoriesFilter from './CategoriesFilter'
|
||||
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||
|
||||
export default {
|
||||
name: 'CategoriesMenu',
|
||||
mixins: [GetCategories],
|
||||
components: {
|
||||
Dropdown,
|
||||
CategoriesFilter,
|
||||
@ -27,11 +29,6 @@ export default {
|
||||
placement: { type: String },
|
||||
offset: { type: [String, Number] },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
categoriesActive: this.$env.CATEGORIES_ACTIVE,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
// TODO: implement visibility of active filter later on
|
||||
|
||||
@ -8,15 +8,16 @@ let wrapper
|
||||
describe('FilterMenu.vue', () => {
|
||||
const mocks = {
|
||||
$t: jest.fn((string) => string),
|
||||
$env: {
|
||||
CATEGORIES_ACTIVE: true,
|
||||
},
|
||||
}
|
||||
|
||||
const getters = {
|
||||
'posts/isActive': () => false,
|
||||
'posts/filteredPostTypes': () => [],
|
||||
'posts/orderBy': () => 'createdAt_desc',
|
||||
'categories/categoriesActive': () => false,
|
||||
}
|
||||
const actions = {
|
||||
'categories/init': jest.fn(),
|
||||
}
|
||||
|
||||
const stubs = {
|
||||
@ -28,7 +29,7 @@ describe('FilterMenu.vue', () => {
|
||||
}
|
||||
|
||||
const Wrapper = () => {
|
||||
const store = new Vuex.Store({ getters })
|
||||
const store = new Vuex.Store({ getters, actions })
|
||||
return mount(FilterMenu, { mocks, localVue, store, stubs })
|
||||
}
|
||||
|
||||
|
||||
@ -36,8 +36,10 @@ import OrderByFilter from './OrderByFilter'
|
||||
import CategoriesFilter from './CategoriesFilter'
|
||||
import LabeledButton from '~/components/_new/generic/LabeledButton/LabeledButton'
|
||||
import SaveCategories from '~/graphql/SaveCategories.js'
|
||||
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||
|
||||
export default {
|
||||
mixins: [GetCategories],
|
||||
components: {
|
||||
EventsByFilter,
|
||||
FollowingFilter,
|
||||
@ -46,11 +48,6 @@ export default {
|
||||
PostTypeFilter,
|
||||
LabeledButton,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
categoriesActive: this.$env ? this.$env.CATEGORIES_ACTIVE : false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
filteredPostTypes: 'posts/filteredPostTypes',
|
||||
|
||||
@ -19,13 +19,16 @@ describe('FollowingFilter', () => {
|
||||
'posts/filteredByUsersFollowed': jest.fn(),
|
||||
'posts/filteredByPostsInMyGroups': jest.fn(),
|
||||
}
|
||||
const actions = {
|
||||
'categories/init': jest.fn(),
|
||||
}
|
||||
|
||||
const mocks = {
|
||||
$t: jest.fn((string) => string),
|
||||
}
|
||||
|
||||
const Wrapper = () => {
|
||||
const store = new Vuex.Store({ mutations, getters })
|
||||
const store = new Vuex.Store({ mutations, getters, actions })
|
||||
const wrapper = mount(FollowingFilter, { mocks, localVue, store })
|
||||
return wrapper
|
||||
}
|
||||
|
||||
@ -15,13 +15,16 @@ describe('OrderByFilter', () => {
|
||||
'posts/orderedByCreationDate': () => true,
|
||||
'posts/orderBy': () => 'createdAt_desc',
|
||||
}
|
||||
const actions = {
|
||||
'categories/init': jest.fn(),
|
||||
}
|
||||
|
||||
const mocks = {
|
||||
$t: jest.fn((string) => string),
|
||||
}
|
||||
|
||||
const Wrapper = () => {
|
||||
const store = new Vuex.Store({ mutations, getters })
|
||||
const store = new Vuex.Store({ mutations, getters, actions })
|
||||
const wrapper = mount(OrderByFilter, { mocks, localVue, store })
|
||||
return wrapper
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
import GroupForm from './GroupForm.vue'
|
||||
import Vuex from 'vuex'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
@ -15,19 +16,27 @@ const propsData = {
|
||||
describe('GroupForm', () => {
|
||||
let wrapper
|
||||
let mocks
|
||||
let storeMocks
|
||||
let store
|
||||
|
||||
beforeEach(() => {
|
||||
mocks = {
|
||||
$t: jest.fn(),
|
||||
$env: {
|
||||
CATEGORIES_ACTIVE: true,
|
||||
}
|
||||
storeMocks = {
|
||||
getters: {
|
||||
'categories/categoriesActive': () => false,
|
||||
},
|
||||
actions: {
|
||||
'categories/init': jest.fn(),
|
||||
},
|
||||
}
|
||||
store = new Vuex.Store(storeMocks)
|
||||
})
|
||||
|
||||
describe('mount', () => {
|
||||
const Wrapper = () => {
|
||||
return mount(GroupForm, { propsData, mocks, localVue, stubs })
|
||||
return mount(GroupForm, { propsData, mocks, localVue, stubs, store })
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@ -177,11 +177,13 @@ import {
|
||||
import Editor from '~/components/Editor/Editor'
|
||||
import ActionRadiusSelect from '~/components/Select/ActionRadiusSelect'
|
||||
import { queryLocations } from '~/graphql/location'
|
||||
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||
|
||||
let timeout
|
||||
|
||||
export default {
|
||||
name: 'GroupForm',
|
||||
mixins: [GetCategories],
|
||||
components: {
|
||||
CategoriesSelect,
|
||||
Editor,
|
||||
@ -203,7 +205,6 @@ export default {
|
||||
const { name, slug, groupType, about, description, actionRadius, locationName, categories } =
|
||||
this.group
|
||||
return {
|
||||
categoriesActive: this.$env.CATEGORIES_ACTIVE,
|
||||
disabled: false,
|
||||
groupTypeOptions: ['public', 'closed', 'hidden'],
|
||||
loadingGeo: false,
|
||||
|
||||
@ -79,9 +79,11 @@
|
||||
<script>
|
||||
import Category from '~/components/Category'
|
||||
import GroupContentMenu from '~/components/ContentMenu/GroupContentMenu'
|
||||
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||
|
||||
export default {
|
||||
name: 'GroupTeaser',
|
||||
mixins: [GetCategories],
|
||||
components: {
|
||||
Category,
|
||||
GroupContentMenu,
|
||||
@ -96,11 +98,6 @@ export default {
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
categoriesActive: this.$env.CATEGORIES_ACTIVE,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
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 links from '~/constants/links.js'
|
||||
import PageParamsLink from '~/components/_new/features/PageParamsLink/PageParamsLink.vue'
|
||||
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||
|
||||
export default {
|
||||
mixins: [GetCategories],
|
||||
components: {
|
||||
AvatarMenu,
|
||||
ChatNotificationMenu,
|
||||
@ -327,7 +329,6 @@ export default {
|
||||
mobileSearchVisible: 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,
|
||||
categoriesActive: this.$env.CATEGORIES_ACTIVE,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
@ -15,11 +15,9 @@ const stubs = {
|
||||
}
|
||||
|
||||
const authUserMock = jest.fn().mockReturnValue({ activeCategories: [] })
|
||||
const apolloQueryMock = jest.fn().mockResolvedValue({
|
||||
data: {
|
||||
Category: [{ id: 'cat0' }, { id: 'cat1' }, { id: 'cat2' }, { id: 'cat3' }, { id: 'cat4' }],
|
||||
},
|
||||
})
|
||||
const categoriesMock = jest
|
||||
.fn()
|
||||
.mockReturnValue([{ id: 'cat0' }, { id: 'cat1' }, { id: 'cat2' }, { id: 'cat3' }, { id: 'cat4' }])
|
||||
|
||||
describe('LoginForm', () => {
|
||||
let mocks
|
||||
@ -36,6 +34,7 @@ describe('LoginForm', () => {
|
||||
getters: {
|
||||
'auth/pending': () => false,
|
||||
'auth/user': authUserMock,
|
||||
'categories/categories': categoriesMock,
|
||||
},
|
||||
actions: {
|
||||
'auth/login': jest.fn(),
|
||||
@ -52,9 +51,6 @@ describe('LoginForm', () => {
|
||||
success: jest.fn(),
|
||||
error: jest.fn(),
|
||||
},
|
||||
$apollo: {
|
||||
query: apolloQueryMock,
|
||||
},
|
||||
}
|
||||
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 ShowPassword from '../ShowPassword/ShowPassword.vue'
|
||||
import { mapGetters, mapMutations } from 'vuex'
|
||||
import CategoryQuery from '~/graphql/CategoryQuery'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@ -88,6 +87,7 @@ export default {
|
||||
},
|
||||
...mapGetters({
|
||||
currentUser: 'auth/user',
|
||||
categories: 'categories/categories',
|
||||
}),
|
||||
},
|
||||
methods: {
|
||||
@ -99,13 +99,9 @@ export default {
|
||||
const { email, password } = this.form
|
||||
try {
|
||||
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) {
|
||||
this.resetCategories()
|
||||
if (this.currentUser.activeCategories.length < categories.length) {
|
||||
if (this.currentUser.activeCategories.length < this.categories.length) {
|
||||
this.currentUser.activeCategories.forEach((categoryId) => {
|
||||
this.toggleCategory(categoryId)
|
||||
})
|
||||
|
||||
@ -12,6 +12,7 @@ describe('PostTeaser', () => {
|
||||
let mocks
|
||||
let propsData
|
||||
let getters
|
||||
let actions
|
||||
let Wrapper
|
||||
let wrapper
|
||||
|
||||
@ -47,21 +48,22 @@ describe('PostTeaser', () => {
|
||||
data: { DeletePost: { id: 'deleted-post-id' } },
|
||||
}),
|
||||
},
|
||||
$env: {
|
||||
CATEGORIES_ACTIVE: false,
|
||||
},
|
||||
}
|
||||
getters = {
|
||||
'auth/isModerator': () => false,
|
||||
'auth/user': () => {
|
||||
return {}
|
||||
},
|
||||
'categories/categoriesActive': () => false,
|
||||
}
|
||||
actions = {
|
||||
'categories/init': jest.fn(),
|
||||
}
|
||||
})
|
||||
|
||||
describe('shallowMount', () => {
|
||||
Wrapper = () => {
|
||||
store = new Vuex.Store({ getters })
|
||||
store = new Vuex.Store({ getters, actions })
|
||||
return shallowMount(PostTeaser, {
|
||||
store,
|
||||
propsData,
|
||||
@ -114,6 +116,7 @@ describe('PostTeaser', () => {
|
||||
Wrapper = () => {
|
||||
const store = new Vuex.Store({
|
||||
getters,
|
||||
actions,
|
||||
})
|
||||
return mount(PostTeaser, {
|
||||
stubs,
|
||||
|
||||
@ -137,9 +137,11 @@ import UserTeaser from '~/components/UserTeaser/UserTeaser'
|
||||
import { mapGetters } from 'vuex'
|
||||
import PostMutations from '~/graphql/PostMutations'
|
||||
import { postMenuModalsData, deletePostMutation } from '~/components/utils/PostHelpers'
|
||||
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||
|
||||
export default {
|
||||
name: 'PostTeaser',
|
||||
mixins: [GetCategories],
|
||||
components: {
|
||||
Category,
|
||||
ContentMenu,
|
||||
@ -164,11 +166,6 @@ export default {
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
categoriesActive: this.$env.CATEGORIES_ACTIVE,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const { image } = this.post
|
||||
if (!image) return
|
||||
|
||||
@ -26,15 +26,13 @@ describe('SearchResults', () => {
|
||||
beforeEach(() => {
|
||||
mocks = {
|
||||
$t: jest.fn(),
|
||||
$env: {
|
||||
CATEGORIES_ACTIVE: false,
|
||||
},
|
||||
}
|
||||
getters = {
|
||||
'auth/user': () => {
|
||||
return { id: 'u343', name: 'Matt' }
|
||||
},
|
||||
'auth/isModerator': () => false,
|
||||
'categories/categoriesActive': () => false,
|
||||
}
|
||||
propsData = {
|
||||
pageSize: 12,
|
||||
|
||||
@ -34,7 +34,6 @@ const options = {
|
||||
// Cookies
|
||||
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
|
||||
CATEGORIES_ACTIVE: process.env.CATEGORIES_ACTIVE === 'true' || false,
|
||||
BADGES_ENABLED: process.env.BADGES_ENABLED === 'true' || false,
|
||||
INVITE_LINK_LIMIT: process.env.INVITE_LINK_LIMIT || 7,
|
||||
NETWORK_NAME: process.env.NETWORK_NAME || 'Ocelot.social',
|
||||
|
||||
@ -17,7 +17,7 @@ module.exports = {
|
||||
],
|
||||
coverageThreshold: {
|
||||
global: {
|
||||
lines: 83,
|
||||
lines: 82,
|
||||
},
|
||||
},
|
||||
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 { render, screen, fireEvent } from '@testing-library/vue'
|
||||
import Vuex from 'vuex'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
@ -32,11 +33,26 @@ describe('GroupProfileSlug', () => {
|
||||
let bobDerBaumeister
|
||||
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(() => {
|
||||
mocks = {
|
||||
$env: {
|
||||
CATEGORIES_ACTIVE: true,
|
||||
},
|
||||
// post: {
|
||||
// id: 'p23',
|
||||
// name: 'It is a post',
|
||||
@ -213,6 +229,7 @@ describe('GroupProfileSlug', () => {
|
||||
localVue,
|
||||
data,
|
||||
stubs,
|
||||
store,
|
||||
})
|
||||
}
|
||||
|
||||
@ -220,12 +237,7 @@ describe('GroupProfileSlug', () => {
|
||||
describe('given a current user', () => {
|
||||
describe('as group owner – "peter-lustig"', () => {
|
||||
beforeEach(() => {
|
||||
mocks.$store = {
|
||||
getters: {
|
||||
'auth/user': peterLustig,
|
||||
'auth/isModerator': () => false,
|
||||
},
|
||||
}
|
||||
currentUserMock.mockReturnValue(peterLustig)
|
||||
wrapper = Wrapper(() => {
|
||||
return {
|
||||
Group: [
|
||||
@ -265,12 +277,7 @@ describe('GroupProfileSlug', () => {
|
||||
|
||||
describe('as usual member – "jenny-rostock"', () => {
|
||||
beforeEach(() => {
|
||||
mocks.$store = {
|
||||
getters: {
|
||||
'auth/user': jennyRostock,
|
||||
'auth/isModerator': () => false,
|
||||
},
|
||||
}
|
||||
currentUserMock.mockReturnValue(jennyRostock)
|
||||
wrapper = Wrapper(() => {
|
||||
return {
|
||||
Group: [
|
||||
@ -291,12 +298,7 @@ describe('GroupProfileSlug', () => {
|
||||
|
||||
describe('as pending member – "bob-der-baumeister"', () => {
|
||||
beforeEach(() => {
|
||||
mocks.$store = {
|
||||
getters: {
|
||||
'auth/user': bobDerBaumeister,
|
||||
'auth/isModerator': () => false,
|
||||
},
|
||||
}
|
||||
currentUserMock.mockReturnValue(bobDerBaumeister)
|
||||
wrapper = Wrapper(() => {
|
||||
return {
|
||||
Group: [
|
||||
@ -317,12 +319,7 @@ describe('GroupProfileSlug', () => {
|
||||
|
||||
describe('as none(!) member – "huey"', () => {
|
||||
beforeEach(() => {
|
||||
mocks.$store = {
|
||||
getters: {
|
||||
'auth/user': huey,
|
||||
'auth/isModerator': () => false,
|
||||
},
|
||||
}
|
||||
currentUserMock.mockReturnValue(huey)
|
||||
wrapper = Wrapper(() => {
|
||||
return {
|
||||
Group: [
|
||||
@ -346,12 +343,7 @@ describe('GroupProfileSlug', () => {
|
||||
describe('given a current user', () => {
|
||||
describe('as group owner – "peter-lustig"', () => {
|
||||
beforeEach(() => {
|
||||
mocks.$store = {
|
||||
getters: {
|
||||
'auth/user': peterLustig,
|
||||
'auth/isModerator': () => false,
|
||||
},
|
||||
}
|
||||
currentUserMock.mockReturnValue(peterLustig)
|
||||
wrapper = Wrapper(() => {
|
||||
return {
|
||||
Group: [
|
||||
@ -372,12 +364,7 @@ describe('GroupProfileSlug', () => {
|
||||
|
||||
describe('as usual member – "jenny-rostock"', () => {
|
||||
beforeEach(() => {
|
||||
mocks.$store = {
|
||||
getters: {
|
||||
'auth/user': jennyRostock,
|
||||
'auth/isModerator': () => false,
|
||||
},
|
||||
}
|
||||
currentUserMock.mockReturnValue(jennyRostock)
|
||||
wrapper = Wrapper(() => {
|
||||
return {
|
||||
Group: [
|
||||
@ -421,12 +408,7 @@ describe('GroupProfileSlug', () => {
|
||||
|
||||
describe('as pending member – "bob-der-baumeister"', () => {
|
||||
beforeEach(() => {
|
||||
mocks.$store = {
|
||||
getters: {
|
||||
'auth/user': bobDerBaumeister,
|
||||
'auth/isModerator': () => false,
|
||||
},
|
||||
}
|
||||
currentUserMock.mockReturnValue(bobDerBaumeister)
|
||||
wrapper = Wrapper(() => {
|
||||
return {
|
||||
Group: [
|
||||
@ -447,12 +429,7 @@ describe('GroupProfileSlug', () => {
|
||||
|
||||
describe('as none(!) member – "huey"', () => {
|
||||
beforeEach(() => {
|
||||
mocks.$store = {
|
||||
getters: {
|
||||
'auth/user': huey,
|
||||
'auth/isModerator': () => false,
|
||||
},
|
||||
}
|
||||
currentUserMock.mockReturnValue(huey)
|
||||
wrapper = Wrapper(() => {
|
||||
return {
|
||||
Group: [
|
||||
@ -477,12 +454,7 @@ describe('GroupProfileSlug', () => {
|
||||
describe('given a current user', () => {
|
||||
describe('as group owner – "peter-lustig"', () => {
|
||||
beforeEach(() => {
|
||||
mocks.$store = {
|
||||
getters: {
|
||||
'auth/user': peterLustig,
|
||||
'auth/isModerator': () => false,
|
||||
},
|
||||
}
|
||||
currentUserMock.mockReturnValue(peterLustig)
|
||||
wrapper = Wrapper(() => {
|
||||
return {
|
||||
Group: [
|
||||
@ -503,12 +475,7 @@ describe('GroupProfileSlug', () => {
|
||||
|
||||
describe('as usual member – "jenny-rostock"', () => {
|
||||
beforeEach(() => {
|
||||
mocks.$store = {
|
||||
getters: {
|
||||
'auth/user': jennyRostock,
|
||||
'auth/isModerator': () => false,
|
||||
},
|
||||
}
|
||||
currentUserMock.mockReturnValue(jennyRostock)
|
||||
wrapper = Wrapper(() => {
|
||||
return {
|
||||
Group: [
|
||||
@ -529,12 +496,7 @@ describe('GroupProfileSlug', () => {
|
||||
|
||||
describe('as pending member – "bob-der-baumeister"', () => {
|
||||
beforeEach(() => {
|
||||
mocks.$store = {
|
||||
getters: {
|
||||
'auth/user': bobDerBaumeister,
|
||||
'auth/isModerator': () => false,
|
||||
},
|
||||
}
|
||||
currentUserMock.mockReturnValue(bobDerBaumeister)
|
||||
wrapper = Wrapper(() => {
|
||||
return {
|
||||
Group: [
|
||||
@ -555,12 +517,7 @@ describe('GroupProfileSlug', () => {
|
||||
|
||||
describe('as none(!) member – "huey"', () => {
|
||||
beforeEach(() => {
|
||||
mocks.$store = {
|
||||
getters: {
|
||||
'auth/user': huey,
|
||||
'auth/isModerator': () => false,
|
||||
},
|
||||
}
|
||||
currentUserMock.mockReturnValue(huey)
|
||||
wrapper = Wrapper(() => {
|
||||
return {
|
||||
Group: [
|
||||
|
||||
@ -316,6 +316,8 @@ import PostTeaser from '~/components/PostTeaser/PostTeaser.vue'
|
||||
import ProfileAvatar from '~/components/_new/generic/ProfileAvatar/ProfileAvatar'
|
||||
import ProfileList from '~/components/features/ProfileList/ProfileList'
|
||||
import SortCategories from '~/mixins/sortCategoriesMixin.js'
|
||||
import { mapGetters } from 'vuex'
|
||||
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||
// import SocialMedia from '~/components/SocialMedia/SocialMedia'
|
||||
// import TabNavigation from '~/components/_new/generic/TabNavigation/TabNavigation'
|
||||
|
||||
@ -346,7 +348,7 @@ export default {
|
||||
// SocialMedia,
|
||||
// TabNavigation,
|
||||
},
|
||||
mixins: [postListActions, SortCategories],
|
||||
mixins: [postListActions, SortCategories, GetCategories],
|
||||
transition: {
|
||||
name: 'slide-up',
|
||||
mode: 'out-in',
|
||||
@ -360,7 +362,6 @@ export default {
|
||||
// const filter = tabToFilterMapping({ tab: 'post', id: this.$route.params.id })
|
||||
const filter = { group: { id: this.$route.params.id } }
|
||||
return {
|
||||
categoriesActive: this.$env.CATEGORIES_ACTIVE,
|
||||
loadGroupMembers: false,
|
||||
posts: [],
|
||||
hasMore: true,
|
||||
@ -378,9 +379,9 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
currentUser() {
|
||||
return this.$store.getters['auth/user']
|
||||
},
|
||||
...mapGetters({
|
||||
currentUser: 'auth/user',
|
||||
}),
|
||||
group() {
|
||||
return this.Group && this.Group[0] ? this.Group[0] : {}
|
||||
},
|
||||
|
||||
@ -36,8 +36,13 @@ describe('PostIndex', () => {
|
||||
'auth/user': () => {
|
||||
return { id: 'u23' }
|
||||
},
|
||||
'categories/categoriesActive': () => true,
|
||||
'categories/categories': () => ['cat1', 'cat2', 'cat3'],
|
||||
},
|
||||
mutations,
|
||||
actions: {
|
||||
'categories/init': jest.fn(),
|
||||
},
|
||||
})
|
||||
mocks = {
|
||||
$t: (key) => key,
|
||||
@ -79,9 +84,6 @@ describe('PostIndex', () => {
|
||||
$route: {
|
||||
query: {},
|
||||
},
|
||||
$env: {
|
||||
CATEGORIES_ACTIVE: true,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@ -155,6 +155,7 @@ import UpdateQuery from '~/components/utils/UpdateQuery'
|
||||
import FilterMenuComponent from '~/components/FilterMenu/FilterMenuComponent'
|
||||
import { SHOW_CONTENT_FILTER_MASONRY_GRID } from '~/constants/filter.js'
|
||||
import { POST_ADD_BUTTON_POSITION_TOP } from '~/constants/posts.js'
|
||||
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@ -167,7 +168,7 @@ export default {
|
||||
FilterMenuComponent,
|
||||
HeaderButton,
|
||||
},
|
||||
mixins: [postListActions, mobile()],
|
||||
mixins: [postListActions, mobile(), GetCategories],
|
||||
data() {
|
||||
const { hashtag = null } = this.$route.query
|
||||
return {
|
||||
@ -184,7 +185,6 @@ export default {
|
||||
offset: 0,
|
||||
pageSize: 12,
|
||||
hashtag,
|
||||
categoriesActive: this.$env.CATEGORIES_ACTIVE,
|
||||
SHOW_CONTENT_FILTER_MASONRY_GRID,
|
||||
POST_ADD_BUTTON_POSITION_TOP,
|
||||
}
|
||||
|
||||
@ -42,6 +42,10 @@ describe('PostSlug', () => {
|
||||
return { id: '1stUser' }
|
||||
},
|
||||
'auth/isModerator': () => false,
|
||||
'categories/categoriesActive': () => false,
|
||||
},
|
||||
actions: {
|
||||
'categories/init': jest.fn(),
|
||||
},
|
||||
})
|
||||
const propsData = {}
|
||||
@ -73,9 +77,6 @@ describe('PostSlug', () => {
|
||||
query: jest.fn().mockResolvedValue({ data: { PostEmotionsCountByEmotion: {} } }),
|
||||
},
|
||||
$scrollTo: jest.fn(),
|
||||
$env: {
|
||||
CATEGORIES_ACTIVE: false,
|
||||
},
|
||||
}
|
||||
stubs = {
|
||||
'client-only': true,
|
||||
|
||||
@ -182,6 +182,7 @@ import { groupQuery } from '~/graphql/groups'
|
||||
import PostMutations from '~/graphql/PostMutations'
|
||||
import links from '~/constants/links.js'
|
||||
import SortCategories from '~/mixins/sortCategoriesMixin.js'
|
||||
import GetCategories from '~/mixins/getCategoriesMixin.js'
|
||||
|
||||
export default {
|
||||
name: 'PostSlug',
|
||||
@ -203,7 +204,7 @@ export default {
|
||||
PageParamsLink,
|
||||
UserTeaser,
|
||||
},
|
||||
mixins: [SortCategories],
|
||||
mixins: [SortCategories, GetCategories],
|
||||
head() {
|
||||
return {
|
||||
title: this.title,
|
||||
@ -219,7 +220,6 @@ export default {
|
||||
blurred: false,
|
||||
blocked: null,
|
||||
postAuthor: null,
|
||||
categoriesActive: this.$env.CATEGORIES_ACTIVE,
|
||||
group: null,
|
||||
}
|
||||
},
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
import create from './create.vue'
|
||||
import Vuex from 'vuex'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
@ -8,9 +9,6 @@ describe('create.vue', () => {
|
||||
|
||||
const mocks = {
|
||||
$t: jest.fn(),
|
||||
$env: {
|
||||
CATEGORIES_ACTIVE: false,
|
||||
},
|
||||
$route: {
|
||||
query: {
|
||||
groupId: null,
|
||||
@ -23,8 +21,14 @@ describe('create.vue', () => {
|
||||
}
|
||||
|
||||
describe('mount', () => {
|
||||
const store = new Vuex.Store({
|
||||
getters: {
|
||||
'categories/categoriesActive': () => false,
|
||||
},
|
||||
})
|
||||
|
||||
const Wrapper = () => {
|
||||
return mount(create, { mocks, localVue, stubs })
|
||||
return mount(create, { mocks, localVue, stubs, store })
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@ -39,15 +39,17 @@ describe('post/_id.vue', () => {
|
||||
}),
|
||||
},
|
||||
},
|
||||
$env: {
|
||||
CATEGORIES_ACTIVE: false,
|
||||
},
|
||||
}
|
||||
store = new Vuex.Store({
|
||||
getters: {
|
||||
'auth/user': () => {
|
||||
return { id: userId }
|
||||
},
|
||||
'categories/categories': jest.fn(() => []),
|
||||
'categories/categoriesActive': () => false,
|
||||
},
|
||||
actions: {
|
||||
'categories/init': jest.fn(),
|
||||
},
|
||||
})
|
||||
if (asyncData) {
|
||||
|
||||
@ -106,6 +106,7 @@ export const actions = {
|
||||
await this.app.$apolloHelpers.onLogin(login)
|
||||
commit('SET_TOKEN', login)
|
||||
await dispatch('fetchCurrentUser')
|
||||
await dispatch('categories/init', null, { root: true })
|
||||
if (cookies.get(metadata.COOKIE_NAME) === undefined) {
|
||||
throw new Error('no-cookie')
|
||||
}
|
||||
|
||||
@ -175,8 +175,11 @@ describe('actions', () => {
|
||||
expect(commit.mock.calls).toEqual(expect.arrayContaining([['SET_TOKEN', token]]))
|
||||
})
|
||||
|
||||
it('fetches the user', () => {
|
||||
expect(dispatch.mock.calls).toEqual([['fetchCurrentUser']])
|
||||
it('fetches the user and initializes categories', () => {
|
||||
expect(dispatch.mock.calls).toEqual([
|
||||
['fetchCurrentUser'],
|
||||
['categories/init', null, { root: true }],
|
||||
])
|
||||
})
|
||||
|
||||
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