From 91d797dcfa5817dbfa5eae6d2fb4228b4522b284 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Mon, 22 Aug 2022 12:14:54 +0200 Subject: [PATCH 01/18] Copy profile Vue pages for the group profile --- webapp/pages/group/_id.spec.js | 33 ++ webapp/pages/group/_id.vue | 34 ++ webapp/pages/group/_id/_slug.spec.js | 95 ++++++ webapp/pages/group/_id/_slug.vue | 443 +++++++++++++++++++++++++++ 4 files changed, 605 insertions(+) create mode 100644 webapp/pages/group/_id.spec.js create mode 100644 webapp/pages/group/_id.vue create mode 100644 webapp/pages/group/_id/_slug.spec.js create mode 100644 webapp/pages/group/_id/_slug.vue diff --git a/webapp/pages/group/_id.spec.js b/webapp/pages/group/_id.spec.js new file mode 100644 index 000000000..aab216569 --- /dev/null +++ b/webapp/pages/group/_id.spec.js @@ -0,0 +1,33 @@ +import { config, mount } from '@vue/test-utils' +import _id from './_id.vue' + +const localVue = global.localVue + +config.stubs['nuxt-child'] = '' + +describe('Profile _id.vue', () => { + let wrapper + let Wrapper + let mocks + + beforeEach(() => { + mocks = {} + }) + + describe('mount', () => { + Wrapper = () => { + return mount(_id, { + mocks, + localVue, + }) + } + + beforeEach(() => { + wrapper = Wrapper() + }) + + it('renders', () => { + expect(wrapper.findAll('.nuxt-child')).toHaveLength(1) + }) + }) +}) diff --git a/webapp/pages/group/_id.vue b/webapp/pages/group/_id.vue new file mode 100644 index 000000000..b9bbef83e --- /dev/null +++ b/webapp/pages/group/_id.vue @@ -0,0 +1,34 @@ + + + diff --git a/webapp/pages/group/_id/_slug.spec.js b/webapp/pages/group/_id/_slug.spec.js new file mode 100644 index 000000000..477174485 --- /dev/null +++ b/webapp/pages/group/_id/_slug.spec.js @@ -0,0 +1,95 @@ +import { config, mount } from '@vue/test-utils' +import ProfileSlug from './_slug.vue' + +const localVue = global.localVue + +localVue.filter('date', (d) => d) + +config.stubs['client-only'] = '' +config.stubs['v-popover'] = '' +config.stubs['nuxt-link'] = '' +config.stubs['infinite-loading'] = '' +config.stubs['follow-list'] = '' + +describe('ProfileSlug', () => { + let wrapper + let Wrapper + let mocks + + beforeEach(() => { + mocks = { + post: { + id: 'p23', + name: 'It is a post', + }, + $t: jest.fn(), + // If you're mocking router, then don't use VueRouter with localVue: https://vue-test-utils.vuejs.org/guides/using-with-vue-router.html + $route: { + params: { + id: '4711', + slug: 'john-doe', + }, + }, + $router: { + history: { + push: jest.fn(), + }, + }, + $toast: { + success: jest.fn(), + error: jest.fn(), + }, + $apollo: { + loading: false, + mutate: jest.fn().mockResolvedValue(), + }, + } + }) + + describe('mount', () => { + Wrapper = () => { + return mount(ProfileSlug, { + mocks, + localVue, + }) + } + + describe('given an authenticated user', () => { + beforeEach(() => { + mocks.$filters = { + removeLinks: (c) => c, + truncate: (a) => a, + } + mocks.$store = { + getters: { + 'auth/isModerator': () => false, + 'auth/user': { + id: 'u23', + }, + }, + } + }) + + describe('given a user for the profile', () => { + beforeEach(() => { + wrapper = Wrapper() + wrapper.setData({ + User: [ + { + id: 'u3', + name: 'Bob the builder', + contributionsCount: 6, + shoutedCount: 7, + commentedCount: 8, + }, + ], + }) + }) + + it('displays name of the user', () => { + expect(wrapper.text()).toContain('Bob the builder') + }) + }) + }) + }) +}) diff --git a/webapp/pages/group/_id/_slug.vue b/webapp/pages/group/_id/_slug.vue new file mode 100644 index 000000000..4fef7d3aa --- /dev/null +++ b/webapp/pages/group/_id/_slug.vue @@ -0,0 +1,443 @@ + + + + + From e1f4609c25cdb48bea6053fbdfd43f1035827139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Tue, 23 Aug 2022 04:48:38 +0200 Subject: [PATCH 02/18] !!! Temp !!! --- webapp/graphql/groups.js | 95 ++++++++++++++++++++++++++++++++++ webapp/locales/de.json | 19 +++---- webapp/locales/en.json | 19 +++---- webapp/pages/group/_id.spec.js | 2 +- webapp/pages/group/_id.vue | 8 +-- 5 files changed, 120 insertions(+), 23 deletions(-) create mode 100644 webapp/graphql/groups.js diff --git a/webapp/graphql/groups.js b/webapp/graphql/groups.js new file mode 100644 index 000000000..2a611f324 --- /dev/null +++ b/webapp/graphql/groups.js @@ -0,0 +1,95 @@ +import gql from 'graphql-tag' + +// ------ mutations + +export const createGroupMutation = gql` + mutation ( + $id: ID + $name: String! + $slug: String + $about: String + $description: String! + $groupType: GroupType! + $actionRadius: GroupActionRadius! + $categoryIds: [ID] + ) { + CreateGroup( + id: $id + name: $name + slug: $slug + about: $about + description: $description + groupType: $groupType + actionRadius: $actionRadius + categoryIds: $categoryIds + ) { + id + name + slug + createdAt + updatedAt + disabled + deleted + about + description + groupType + actionRadius + myRole + } + } +` + +// ------ queries + +export const groupQuery = gql` + query ( + $isMember: Boolean + $id: ID + $name: String + $slug: String + $createdAt: String + $updatedAt: String + $about: String + $description: String + $locationName: String + $first: Int + $offset: Int + $orderBy: [_GroupOrdering] + $filter: _GroupFilter + ) { + Group( + isMember: $isMember + id: $id + name: $name + slug: $slug + createdAt: $createdAt + updatedAt: $updatedAt + about: $about + description: $description + locationName: $locationName + first: $first + offset: $offset + orderBy: $orderBy + filter: $filter + ) { + id + name + slug + createdAt + updatedAt + disabled + deleted + about + description + groupType + actionRadius + myRole + categories { + id + slug + name + icon + } + } + } +` diff --git a/webapp/locales/de.json b/webapp/locales/de.json index 297daa511..07a71dfcf 100644 --- a/webapp/locales/de.json +++ b/webapp/locales/de.json @@ -333,15 +333,16 @@ "placeholder": "Schreib etwas Inspirierendes …" }, "error-pages": { - "403-default": "Kein Zugang zu dieser Seite", - "404-default": "Diese Seite konnte nicht gefunden werden", - "500-default": "Internal Server Error", - "503-default": "Dienst steht nicht zur Verfügung", - "back-to-index": "Zurück zur Startseite", - "cannot-edit-post": "Dieser Beitrag kann nicht editiert werden", - "default": "Ein Fehler ist aufgetreten", - "post-not-found": "Dieser Beitrag konnte nicht gefunden werden", - "profile-not-found": "Dieses Profil konnte nicht gefunden werden" + "403-default": "Kein Zugang zu dieser Seite!", + "404-default": "Diese Seite konnte nicht gefunden werden!", + "500-default": "Internal Server Error!", + "503-default": "Dienst steht nicht zur Verfügung!", + "back-to-index": "Zurück zur Startseite!", + "cannot-edit-post": "Dieser Beitrag kann nicht editiert werden!", + "default": "Ein Fehler ist aufgetreten!", + "group-not-found": "Dieses Gruppenprofil konnte nicht gefunden werden!", + "post-not-found": "Dieser Beitrag konnte nicht gefunden werden!", + "profile-not-found": "Dieses Profil konnte nicht gefunden werden!" }, "filter-menu": { "all": "Alle", diff --git a/webapp/locales/en.json b/webapp/locales/en.json index 8499b0290..1b16431e3 100644 --- a/webapp/locales/en.json +++ b/webapp/locales/en.json @@ -333,15 +333,16 @@ "placeholder": "Leave your inspirational thoughts …" }, "error-pages": { - "403-default": "Not authorized to this page", - "404-default": "This page could not be found", - "500-default": "Internal Server Error", - "503-default": "Service Unavailable", - "back-to-index": "Back to index page", - "cannot-edit-post": "This post cannot be edited", - "default": "An error occurred", - "post-not-found": "This post could not be found", - "profile-not-found": "This profile could not be found" + "403-default": "Not authorized to this page!", + "404-default": "This page could not be found!", + "500-default": "Internal Server Error!", + "503-default": "Service Unavailable!", + "back-to-index": "Back to index page!", + "cannot-edit-post": "This post cannot be edited!", + "default": "An error occurred!", + "group-not-found": "This group profile could not be found!", + "post-not-found": "This post could not be found!", + "profile-not-found": "This profile could not be found!" }, "filter-menu": { "all": "All", diff --git a/webapp/pages/group/_id.spec.js b/webapp/pages/group/_id.spec.js index aab216569..bafd5c392 100644 --- a/webapp/pages/group/_id.spec.js +++ b/webapp/pages/group/_id.spec.js @@ -5,7 +5,7 @@ const localVue = global.localVue config.stubs['nuxt-child'] = '' -describe('Profile _id.vue', () => { +describe('Group profile _id.vue', () => { let wrapper let Wrapper let mocks diff --git a/webapp/pages/group/_id.vue b/webapp/pages/group/_id.vue index b9bbef83e..047d12d7f 100644 --- a/webapp/pages/group/_id.vue +++ b/webapp/pages/group/_id.vue @@ -9,7 +9,7 @@ import PersistentLinks from '~/mixins/persistentLinks.js' const options = { queryId: gql` query($idOrSlug: ID) { - User(id: $idOrSlug) { + Group(id: $idOrSlug) { id slug } @@ -17,14 +17,14 @@ const options = { `, querySlug: gql` query($idOrSlug: String) { - User(slug: $idOrSlug) { + Group(slug: $idOrSlug) { id slug } } `, - message: 'error-pages.profile-not-found', - path: 'profile', + message: 'error-pages.group-not-found', + path: 'group', } const persistentLinks = PersistentLinks(options) From 623af5f47ba11fc71abda14848c1fffbde38bc0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Mon, 29 Aug 2022 11:18:40 +0200 Subject: [PATCH 03/18] Query for group 'id' directly in resolver --- backend/src/schema/resolvers/groups.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/backend/src/schema/resolvers/groups.js b/backend/src/schema/resolvers/groups.js index 5737f5505..2d9dde1ff 100644 --- a/backend/src/schema/resolvers/groups.js +++ b/backend/src/schema/resolvers/groups.js @@ -9,25 +9,26 @@ import Resolver from './helpers/Resolver' export default { Query: { Group: async (_object, params, context, _resolveInfo) => { - const { isMember } = params + const { id: groupId, isMember } = params const session = context.driver.session() const readTxResultPromise = session.readTransaction(async (txc) => { + const groupIdCypher = groupId ? ` {id: "${groupId}"}` : '' let groupCypher if (isMember === true) { groupCypher = ` - MATCH (:User {id: $userId})-[membership:MEMBER_OF]->(group:Group) + MATCH (:User {id: $userId})-[membership:MEMBER_OF]->(group:Group${groupIdCypher}) RETURN group {.*, myRole: membership.role} ` } else { if (isMember === false) { groupCypher = ` - MATCH (group:Group) + MATCH (group:Group${groupIdCypher}) WHERE NOT (:User {id: $userId})-[:MEMBER_OF]->(group) RETURN group {.*, myRole: NULL} ` } else { groupCypher = ` - MATCH (group:Group) + MATCH (group:Group${groupIdCypher}) OPTIONAL MATCH (:User {id: $userId})-[membership:MEMBER_OF]->(group) RETURN group {.*, myRole: membership.role} ` From 39487778bf096fe4c3ad068c5bec0e311d2058d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Mon, 29 Aug 2022 11:26:27 +0200 Subject: [PATCH 04/18] Implement group profile, first step --- webapp/graphql/groups.js | 95 ++++++++ webapp/locales/de.json | 19 +- webapp/locales/en.json | 19 +- webapp/pages/group/_id.spec.js | 2 +- webapp/pages/group/_id.vue | 8 +- webapp/pages/group/_id/_slug.vue | 401 ++++++++++++++++--------------- 6 files changed, 325 insertions(+), 219 deletions(-) create mode 100644 webapp/graphql/groups.js diff --git a/webapp/graphql/groups.js b/webapp/graphql/groups.js new file mode 100644 index 000000000..579380b24 --- /dev/null +++ b/webapp/graphql/groups.js @@ -0,0 +1,95 @@ +import gql from 'graphql-tag' + +// ------ mutations + +export const createGroupMutation = gql` + mutation( + $id: ID + $name: String! + $slug: String + $about: String + $description: String! + $groupType: GroupType! + $actionRadius: GroupActionRadius! + $categoryIds: [ID] + ) { + CreateGroup( + id: $id + name: $name + slug: $slug + about: $about + description: $description + groupType: $groupType + actionRadius: $actionRadius + categoryIds: $categoryIds + ) { + id + name + slug + createdAt + updatedAt + disabled + deleted + about + description + groupType + actionRadius + myRole + } + } +` + +// ------ queries + +export const groupQuery = gql` + query( + $isMember: Boolean + $id: ID + $name: String + $slug: String + $createdAt: String + $updatedAt: String + $about: String + $description: String + $locationName: String + $first: Int + $offset: Int + $orderBy: [_GroupOrdering] + $filter: _GroupFilter + ) { + Group( + isMember: $isMember + id: $id + name: $name + slug: $slug + createdAt: $createdAt + updatedAt: $updatedAt + about: $about + description: $description + locationName: $locationName + first: $first + offset: $offset + orderBy: $orderBy + filter: $filter + ) { + id + name + slug + createdAt + updatedAt + disabled + deleted + about + description + groupType + actionRadius + myRole + categories { + id + slug + name + icon + } + } + } +` diff --git a/webapp/locales/de.json b/webapp/locales/de.json index 297daa511..07a71dfcf 100644 --- a/webapp/locales/de.json +++ b/webapp/locales/de.json @@ -333,15 +333,16 @@ "placeholder": "Schreib etwas Inspirierendes …" }, "error-pages": { - "403-default": "Kein Zugang zu dieser Seite", - "404-default": "Diese Seite konnte nicht gefunden werden", - "500-default": "Internal Server Error", - "503-default": "Dienst steht nicht zur Verfügung", - "back-to-index": "Zurück zur Startseite", - "cannot-edit-post": "Dieser Beitrag kann nicht editiert werden", - "default": "Ein Fehler ist aufgetreten", - "post-not-found": "Dieser Beitrag konnte nicht gefunden werden", - "profile-not-found": "Dieses Profil konnte nicht gefunden werden" + "403-default": "Kein Zugang zu dieser Seite!", + "404-default": "Diese Seite konnte nicht gefunden werden!", + "500-default": "Internal Server Error!", + "503-default": "Dienst steht nicht zur Verfügung!", + "back-to-index": "Zurück zur Startseite!", + "cannot-edit-post": "Dieser Beitrag kann nicht editiert werden!", + "default": "Ein Fehler ist aufgetreten!", + "group-not-found": "Dieses Gruppenprofil konnte nicht gefunden werden!", + "post-not-found": "Dieser Beitrag konnte nicht gefunden werden!", + "profile-not-found": "Dieses Profil konnte nicht gefunden werden!" }, "filter-menu": { "all": "Alle", diff --git a/webapp/locales/en.json b/webapp/locales/en.json index 8499b0290..1b16431e3 100644 --- a/webapp/locales/en.json +++ b/webapp/locales/en.json @@ -333,15 +333,16 @@ "placeholder": "Leave your inspirational thoughts …" }, "error-pages": { - "403-default": "Not authorized to this page", - "404-default": "This page could not be found", - "500-default": "Internal Server Error", - "503-default": "Service Unavailable", - "back-to-index": "Back to index page", - "cannot-edit-post": "This post cannot be edited", - "default": "An error occurred", - "post-not-found": "This post could not be found", - "profile-not-found": "This profile could not be found" + "403-default": "Not authorized to this page!", + "404-default": "This page could not be found!", + "500-default": "Internal Server Error!", + "503-default": "Service Unavailable!", + "back-to-index": "Back to index page!", + "cannot-edit-post": "This post cannot be edited!", + "default": "An error occurred!", + "group-not-found": "This group profile could not be found!", + "post-not-found": "This post could not be found!", + "profile-not-found": "This profile could not be found!" }, "filter-menu": { "all": "All", diff --git a/webapp/pages/group/_id.spec.js b/webapp/pages/group/_id.spec.js index aab216569..bafd5c392 100644 --- a/webapp/pages/group/_id.spec.js +++ b/webapp/pages/group/_id.spec.js @@ -5,7 +5,7 @@ const localVue = global.localVue config.stubs['nuxt-child'] = '' -describe('Profile _id.vue', () => { +describe('Group profile _id.vue', () => { let wrapper let Wrapper let mocks diff --git a/webapp/pages/group/_id.vue b/webapp/pages/group/_id.vue index b9bbef83e..047d12d7f 100644 --- a/webapp/pages/group/_id.vue +++ b/webapp/pages/group/_id.vue @@ -9,7 +9,7 @@ import PersistentLinks from '~/mixins/persistentLinks.js' const options = { queryId: gql` query($idOrSlug: ID) { - User(id: $idOrSlug) { + Group(id: $idOrSlug) { id slug } @@ -17,14 +17,14 @@ const options = { `, querySlug: gql` query($idOrSlug: String) { - User(slug: $idOrSlug) { + Group(slug: $idOrSlug) { id slug } } `, - message: 'error-pages.profile-not-found', - path: 'profile', + message: 'error-pages.group-not-found', + path: 'group', } const persistentLinks = PersistentLinks(options) diff --git a/webapp/pages/group/_id/_slug.vue b/webapp/pages/group/_id/_slug.vue index 4fef7d3aa..365fcc557 100644 --- a/webapp/pages/group/_id/_slug.vue +++ b/webapp/pages/group/_id/_slug.vue @@ -1,23 +1,24 @@