From bed693b073ffb5c07e2d907eff6696459d775f1b Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 24 Apr 2023 15:49:24 +0200 Subject: [PATCH 1/3] feat(backend): filter posts by post type --- .../src/schema/resolvers/filter-posts.spec.js | 159 ++++++++++++++++++ backend/src/schema/types/type/Post.gql | 1 + 2 files changed, 160 insertions(+) create mode 100644 backend/src/schema/resolvers/filter-posts.spec.js diff --git a/backend/src/schema/resolvers/filter-posts.spec.js b/backend/src/schema/resolvers/filter-posts.spec.js new file mode 100644 index 000000000..b3109dbe4 --- /dev/null +++ b/backend/src/schema/resolvers/filter-posts.spec.js @@ -0,0 +1,159 @@ +import { createTestClient } from 'apollo-server-testing' +import Factory, { cleanDatabase } from '../../db/factories' +import { getNeode, getDriver } from '../../db/neo4j' +import createServer from '../../server' +import CONFIG from '../../config' +import { filterPosts, createPostMutation } from '../../graphql/posts' + +CONFIG.CATEGORIES_ACTIVE = false + +const driver = getDriver() +const neode = getNeode() + +let query +let mutate +let authenticatedUser +let user + +beforeAll(async () => { + await cleanDatabase() + + const { server } = createServer({ + context: () => { + return { + driver, + neode, + user: authenticatedUser, + } + }, + }) + query = createTestClient(server).query + mutate = createTestClient(server).mutate +}) + +afterAll(async () => { + await cleanDatabase() + driver.close() +}) + +describe('Filter Posts', () => { + const now = new Date() + + beforeAll(async () => { + user = await Factory.build('user', { + id: 'user', + name: 'User', + about: 'I am a user.', + }) + authenticatedUser = await user.toJson() + await mutate({ + mutation: createPostMutation(), + variables: { + id: 'a1', + title: 'I am an article', + content: 'I am an article written by user.', + }, + }) + await mutate({ + mutation: createPostMutation(), + variables: { + id: 'a2', + title: 'I am anonther article', + content: 'I am another article written by user.', + }, + }) + await mutate({ + mutation: createPostMutation(), + variables: { + id: 'e1', + title: 'Illegaler Kindergeburtstag', + content: 'Elli wird fünf. Wir feiern ihren Geburtstag.', + postType: 'Event', + eventInput: { + eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(), + eventVenue: 'Garten der Familie Maier', + }, + }, + }) + await mutate({ + mutation: createPostMutation(), + variables: { + id: 'e2', + title: 'Räuber-Treffen', + content: 'Planung der nächsten Räuberereien', + postType: 'Event', + eventInput: { + eventStart: new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1).toISOString(), + eventVenue: 'Wirtshaus im Spessart', + }, + }, + }) + }) + + describe('no filters set', () => { + it('finds all posts', async () => { + const { + data: { Post: result }, + } = await query({ query: filterPosts() }) + expect(result).toHaveLength(4) + expect(result).toEqual( + expect.arrayContaining([ + expect.objectContaining({ id: 'a1' }), + expect.objectContaining({ id: 'a2' }), + expect.objectContaining({ id: 'e1' }), + expect.objectContaining({ id: 'e2' }), + ]), + ) + }) + }) + + describe('post type filter set to ["Article"]', () => { + it('finds the articles', async () => { + const { + data: { Post: result }, + } = await query({ query: filterPosts(), variables: { filter: { postType_in: ['Article'] } } }) + expect(result).toHaveLength(2) + expect(result).toEqual( + expect.arrayContaining([ + expect.objectContaining({ id: 'a1' }), + expect.objectContaining({ id: 'a2' }), + ]), + ) + }) + }) + + describe('post type filter set to ["Event"]', () => { + it('finds the articles', async () => { + const { + data: { Post: result }, + } = await query({ query: filterPosts(), variables: { filter: { postType_in: ['Event'] } } }) + expect(result).toHaveLength(2) + expect(result).toEqual( + expect.arrayContaining([ + expect.objectContaining({ id: 'e1' }), + expect.objectContaining({ id: 'e2' }), + ]), + ) + }) + }) + + describe('post type filter set to ["Article", "Event"]', () => { + it('finds the articles', async () => { + const { + data: { Post: result }, + } = await query({ + query: filterPosts(), + variables: { filter: { postType_in: ['Article', 'Event'] } }, + }) + expect(result).toHaveLength(4) + expect(result).toEqual( + expect.arrayContaining([ + expect.objectContaining({ id: 'a1' }), + expect.objectContaining({ id: 'a2' }), + expect.objectContaining({ id: 'e1' }), + expect.objectContaining({ id: 'e2' }), + ]), + ) + }) + }) +}) diff --git a/backend/src/schema/types/type/Post.gql b/backend/src/schema/types/type/Post.gql index 22d7c1d5c..988e2b81d 100644 --- a/backend/src/schema/types/type/Post.gql +++ b/backend/src/schema/types/type/Post.gql @@ -83,6 +83,7 @@ input _PostFilter { emotions_every: _PostEMOTEDFilter group: _GroupFilter postsInMyGroups: Boolean + postType_in: [PostType] } enum _PostOrdering { From e69c036c8036da19d75981f54c7fb1c277128a00 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 24 Apr 2023 16:21:50 +0200 Subject: [PATCH 2/3] order events by event date, filter outdated events --- backend/src/graphql/posts.js | 1 + .../src/schema/resolvers/filter-posts.spec.js | 73 ++++++++++++++++++- backend/src/schema/types/type/Post.gql | 3 + 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/backend/src/graphql/posts.js b/backend/src/graphql/posts.js index 7d57b8510..d1dc3ee45 100644 --- a/backend/src/graphql/posts.js +++ b/backend/src/graphql/posts.js @@ -72,6 +72,7 @@ export const filterPosts = () => { id title content + eventStart } } ` diff --git a/backend/src/schema/resolvers/filter-posts.spec.js b/backend/src/schema/resolvers/filter-posts.spec.js index b3109dbe4..0b96e001f 100644 --- a/backend/src/schema/resolvers/filter-posts.spec.js +++ b/backend/src/schema/resolvers/filter-posts.spec.js @@ -138,7 +138,7 @@ describe('Filter Posts', () => { }) describe('post type filter set to ["Article", "Event"]', () => { - it('finds the articles', async () => { + it('finds all posts', async () => { const { data: { Post: result }, } = await query({ @@ -156,4 +156,75 @@ describe('Filter Posts', () => { ) }) }) + + describe('order events by event start descending', () => { + it('finds the events orderd accordingly', async () => { + const { + data: { Post: result }, + } = await query({ + query: filterPosts(), + variables: { filter: { postType_in: ['Event'] }, orderBy: ['eventStart_desc'] }, + }) + expect(result).toHaveLength(2) + expect(result).toEqual([ + expect.objectContaining({ + id: 'e1', + eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(), + }), + expect.objectContaining({ + id: 'e2', + eventStart: new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1).toISOString(), + }), + ]) + }) + }) + + describe('order events by event start ascending', () => { + it('finds the events orderd accordingly', async () => { + const { + data: { Post: result }, + } = await query({ + query: filterPosts(), + variables: { filter: { postType_in: ['Event'] }, orderBy: ['eventStart_asc'] }, + }) + expect(result).toHaveLength(2) + expect(result).toEqual([ + expect.objectContaining({ + id: 'e2', + eventStart: new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1).toISOString(), + }), + expect.objectContaining({ + id: 'e1', + eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(), + }), + ]) + }) + }) + + describe('filter events by event start date', () => { + it('finds only events after given date', async () => { + const { + data: { Post: result }, + } = await query({ + query: filterPosts(), + variables: { + filter: { + postType_in: ['Event'], + eventStart_gte: new Date( + now.getFullYear(), + now.getMonth(), + now.getDate() + 2, + ).toISOString(), + }, + }, + }) + expect(result).toHaveLength(1) + expect(result).toEqual([ + expect.objectContaining({ + id: 'e1', + eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(), + }), + ]) + }) + }) }) diff --git a/backend/src/schema/types/type/Post.gql b/backend/src/schema/types/type/Post.gql index 988e2b81d..548f3d5aa 100644 --- a/backend/src/schema/types/type/Post.gql +++ b/backend/src/schema/types/type/Post.gql @@ -84,6 +84,7 @@ input _PostFilter { group: _GroupFilter postsInMyGroups: Boolean postType_in: [PostType] + eventStart_gte: String } enum _PostOrdering { @@ -105,6 +106,8 @@ enum _PostOrdering { language_desc pinned_asc pinned_desc + eventStart_asc + eventStart_desc } From 4091045de6db35f05bb60682760d4a07869418b9 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 24 Apr 2023 17:12:56 +0200 Subject: [PATCH 3/3] fix tests (include eventStart) --- .../schema/resolvers/postsInGroups.spec.js | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/backend/src/schema/resolvers/postsInGroups.spec.js b/backend/src/schema/resolvers/postsInGroups.spec.js index 86a278207..ba9041090 100644 --- a/backend/src/schema/resolvers/postsInGroups.spec.js +++ b/backend/src/schema/resolvers/postsInGroups.spec.js @@ -818,11 +818,13 @@ describe('Posts in Groups', () => { id: 'post-to-public-group', title: 'A post to a public group', content: 'I am posting into a public group as a member of the group', + eventStart: null, }, { id: 'post-without-group', title: 'A post without a group', content: 'I am a user who does not belong to a group yet.', + eventStart: null, }, ]), }, @@ -846,11 +848,13 @@ describe('Posts in Groups', () => { id: 'post-to-public-group', title: 'A post to a public group', content: 'I am posting into a public group as a member of the group', + eventStart: null, }, { id: 'post-without-group', title: 'A post without a group', content: 'I am a user who does not belong to a group yet.', + eventStart: null, }, ]), }, @@ -874,11 +878,13 @@ describe('Posts in Groups', () => { id: 'post-to-public-group', title: 'A post to a public group', content: 'I am posting into a public group as a member of the group', + eventStart: null, }, { id: 'post-without-group', title: 'A post without a group', content: 'I am a user who does not belong to a group yet.', + eventStart: null, }, ]), }, @@ -902,11 +908,13 @@ describe('Posts in Groups', () => { id: 'post-to-public-group', title: 'A post to a public group', content: 'I am posting into a public group as a member of the group', + eventStart: null, }, { id: 'post-without-group', title: 'A post without a group', content: 'I am a user who does not belong to a group yet.', + eventStart: null, }, ]), }, @@ -930,21 +938,25 @@ describe('Posts in Groups', () => { id: 'post-to-public-group', title: 'A post to a public group', content: 'I am posting into a public group as a member of the group', + eventStart: null, }, { id: 'post-without-group', title: 'A post without a group', content: 'I am a user who does not belong to a group yet.', + eventStart: null, }, { id: 'post-to-closed-group', title: 'A post to a closed group', content: 'I am posting into a closed group as a member of the group', + eventStart: null, }, { id: 'post-to-hidden-group', title: 'A post to a hidden group', content: 'I am posting into a hidden group as a member of the group', + eventStart: null, }, ]), }, @@ -1319,16 +1331,19 @@ describe('Posts in Groups', () => { id: 'post-to-public-group', title: 'A post to a public group', content: 'I am posting into a public group as a member of the group', + eventStart: null, }, { id: 'post-without-group', title: 'A post without a group', content: 'I am a user who does not belong to a group yet.', + eventStart: null, }, { id: 'post-to-closed-group', title: 'A post to a closed group', content: 'I am posting into a closed group as a member of the group', + eventStart: null, }, ]), }, @@ -1361,21 +1376,25 @@ describe('Posts in Groups', () => { id: 'post-to-public-group', title: 'A post to a public group', content: 'I am posting into a public group as a member of the group', + eventStart: null, }, { id: 'post-without-group', title: 'A post without a group', content: 'I am a user who does not belong to a group yet.', + eventStart: null, }, { id: 'post-to-closed-group', title: 'A post to a closed group', content: 'I am posting into a closed group as a member of the group', + eventStart: null, }, { id: 'post-to-hidden-group', title: 'A post to a hidden group', content: 'I am posting into a hidden group as a member of the group', + eventStart: null, }, ]), }, @@ -1410,16 +1429,19 @@ describe('Posts in Groups', () => { id: 'post-to-public-group', title: 'A post to a public group', content: 'I am posting into a public group as a member of the group', + eventStart: null, }, { id: 'post-without-group', title: 'A post without a group', content: 'I am a user who does not belong to a group yet.', + eventStart: null, }, { id: 'post-to-hidden-group', title: 'A post to a hidden group', content: 'I am posting into a hidden group as a member of the group', + eventStart: null, }, ]), }, @@ -1452,11 +1474,13 @@ describe('Posts in Groups', () => { id: 'post-to-public-group', title: 'A post to a public group', content: 'I am posting into a public group as a member of the group', + eventStart: null, }, { id: 'post-without-group', title: 'A post without a group', content: 'I am a user who does not belong to a group yet.', + eventStart: null, }, ]), }, @@ -1489,21 +1513,25 @@ describe('Posts in Groups', () => { id: 'post-to-public-group', title: 'A post to a public group', content: 'I am posting into a public group as a member of the group', + eventStart: null, }, { id: 'post-without-group', title: 'A post without a group', content: 'I am a user who does not belong to a group yet.', + eventStart: null, }, { id: 'post-to-closed-group', title: 'A post to a closed group', content: 'I am posting into a closed group as a member of the group', + eventStart: null, }, { id: 'post-to-hidden-group', title: 'A post to a hidden group', content: 'I am posting into a hidden group as a member of the group', + eventStart: null, }, ]), }, @@ -1534,21 +1562,25 @@ describe('Posts in Groups', () => { id: 'post-to-public-group', title: 'A post to a public group', content: 'I am posting into a public group as a member of the group', + eventStart: null, }, { id: 'post-without-group', title: 'A post without a group', content: 'I am a user who does not belong to a group yet.', + eventStart: null, }, { id: 'post-to-closed-group', title: 'A post to a closed group', content: 'I am posting into a closed group as a member of the group', + eventStart: null, }, { id: 'post-to-hidden-group', title: 'A post to a hidden group', content: 'I am posting into a hidden group as a member of the group', + eventStart: null, }, ]), }, @@ -1579,21 +1611,25 @@ describe('Posts in Groups', () => { id: 'post-to-public-group', title: 'A post to a public group', content: 'I am posting into a public group as a member of the group', + eventStart: null, }, { id: 'post-without-group', title: 'A post without a group', content: 'I am a user who does not belong to a group yet.', + eventStart: null, }, { id: 'post-to-closed-group', title: 'A post to a closed group', content: 'I am posting into a closed group as a member of the group', + eventStart: null, }, { id: 'post-to-hidden-group', title: 'A post to a hidden group', content: 'I am posting into a hidden group as a member of the group', + eventStart: null, }, ]), }, @@ -1628,21 +1664,25 @@ describe('Posts in Groups', () => { id: 'post-to-public-group', title: 'A post to a public group', content: 'I am posting into a public group as a member of the group', + eventStart: null, }, { id: 'post-without-group', title: 'A post without a group', content: 'I am a user who does not belong to a group yet.', + eventStart: null, }, { id: 'post-to-closed-group', title: 'A post to a closed group', content: 'I am posting into a closed group as a member of the group', + eventStart: null, }, { id: 'post-to-hidden-group', title: 'A post to a hidden group', content: 'I am posting into a hidden group as a member of the group', + eventStart: null, }, ]), }, @@ -1675,21 +1715,25 @@ describe('Posts in Groups', () => { id: 'post-to-public-group', title: 'A post to a public group', content: 'I am posting into a public group as a member of the group', + eventStart: null, }, { id: 'post-without-group', title: 'A post without a group', content: 'I am a user who does not belong to a group yet.', + eventStart: null, }, { id: 'post-to-closed-group', title: 'A post to a closed group', content: 'I am posting into a closed group as a member of the group', + eventStart: null, }, { id: 'post-to-hidden-group', title: 'A post to a hidden group', content: 'I am posting into a hidden group as a member of the group', + eventStart: null, }, ]), }, @@ -1739,11 +1783,13 @@ describe('Posts in Groups', () => { id: 'post-to-closed-group', title: 'A post to a closed group', content: 'I am posting into a closed group as a member of the group', + eventStart: null, }, { id: 'post-to-hidden-group', title: 'A post to a hidden group', content: 'I am posting into a hidden group as a member of the group', + eventStart: null, }, ]), },