From 75d984073d44101998d329d758bc7ada0646b566 Mon Sep 17 00:00:00 2001 From: Matt Rider Date: Mon, 26 Aug 2019 16:19:42 +0200 Subject: [PATCH 1/6] Check there are ids in the badIds array - if there are no ids, we shouldn't add an empty array since it adds unneccessarily to our auto-generated post query and affects greatly performance. see issue #1390 --- backend/src/schema/resolvers/posts.js | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/backend/src/schema/resolvers/posts.js b/backend/src/schema/resolvers/posts.js index 46d7c414f..ea715f676 100644 --- a/backend/src/schema/resolvers/posts.js +++ b/backend/src/schema/resolvers/posts.js @@ -11,17 +11,19 @@ const filterForBlockedUsers = async (params, context) => { getBlockedByUsers(context), ]) const badIds = [...blockedByUsers.map(b => b.id), ...blockedUsers.map(b => b.id)] - params.filter = mergeWith( - params.filter, - { - author_not: { id_in: badIds }, - }, - (objValue, srcValue) => { - if (isArray(objValue)) { - return objValue.concat(srcValue) - } - }, - ) + if (badIds.length) { + params.filter = mergeWith( + params.filter, + { + author_not: { id_in: badIds }, + }, + (objValue, srcValue) => { + if (isArray(objValue)) { + return objValue.concat(srcValue) + } + }, + ) + } return params } From 9f6757f409642046866fd45bdb36995dc21da4df Mon Sep 17 00:00:00 2001 From: roschaefer Date: Mon, 26 Aug 2019 16:53:22 +0200 Subject: [PATCH 2/6] Use guard clauses if possible --- backend/src/schema/resolvers/posts.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/backend/src/schema/resolvers/posts.js b/backend/src/schema/resolvers/posts.js index ea715f676..a265c28f0 100644 --- a/backend/src/schema/resolvers/posts.js +++ b/backend/src/schema/resolvers/posts.js @@ -11,19 +11,19 @@ const filterForBlockedUsers = async (params, context) => { getBlockedByUsers(context), ]) const badIds = [...blockedByUsers.map(b => b.id), ...blockedUsers.map(b => b.id)] - if (badIds.length) { - params.filter = mergeWith( - params.filter, - { - author_not: { id_in: badIds }, - }, - (objValue, srcValue) => { - if (isArray(objValue)) { - return objValue.concat(srcValue) - } - }, - ) - } + if (!badIds.length) return params + + params.filter = mergeWith( + params.filter, + { + author_not: { id_in: badIds }, + }, + (objValue, srcValue) => { + if (isArray(objValue)) { + return objValue.concat(srcValue) + } + }, + ) return params } From b990a1055b48515866c31c131c9aa0553577fa34 Mon Sep 17 00:00:00 2001 From: Matt Rider Date: Mon, 26 Aug 2019 17:51:44 +0200 Subject: [PATCH 3/6] Fix search functionality - remove unused line that allows for an empty array of author_not.id_in --- backend/src/schema/resolvers/posts.js | 2 +- backend/src/schema/types/schema.gql | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/backend/src/schema/resolvers/posts.js b/backend/src/schema/resolvers/posts.js index a265c28f0..17107c241 100644 --- a/backend/src/schema/resolvers/posts.js +++ b/backend/src/schema/resolvers/posts.js @@ -35,7 +35,7 @@ export default { }, findPosts: async (object, params, context, resolveInfo) => { params = await filterForBlockedUsers(params, context) - return neo4jgraphql(object, params, context, resolveInfo, false) + return neo4jgraphql(object, params, context, resolveInfo, true) }, PostsEmotionsCountByEmotion: async (object, params, context, resolveInfo) => { const session = context.driver.session() diff --git a/backend/src/schema/types/schema.gql b/backend/src/schema/types/schema.gql index e0a2c328b..d4959889f 100644 --- a/backend/src/schema/types/schema.gql +++ b/backend/src/schema/types/schema.gql @@ -13,7 +13,6 @@ type Query { WHERE score >= 0.2 AND NOT user.deleted = true AND NOT user.disabled = true AND NOT post.deleted = true AND NOT post.disabled = true - AND NOT user.id in COALESCE($filter.author_not.id_in, []) RETURN post LIMIT $limit """ From 6de602fd5885b0c39fb7ee06ffc0f7f40b8c9218 Mon Sep 17 00:00:00 2001 From: Matt Rider Date: Mon, 26 Aug 2019 21:37:36 +0200 Subject: [PATCH 4/6] Revert @roschaefer's hacky fix to Search.feature - now that we are checking to see if there are any badIds, it was breaking the search functionality --- backend/src/schema/resolvers/posts.js | 2 +- backend/src/schema/types/schema.gql | 4 ++-- webapp/store/search.js | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/backend/src/schema/resolvers/posts.js b/backend/src/schema/resolvers/posts.js index 17107c241..a265c28f0 100644 --- a/backend/src/schema/resolvers/posts.js +++ b/backend/src/schema/resolvers/posts.js @@ -35,7 +35,7 @@ export default { }, findPosts: async (object, params, context, resolveInfo) => { params = await filterForBlockedUsers(params, context) - return neo4jgraphql(object, params, context, resolveInfo, true) + return neo4jgraphql(object, params, context, resolveInfo, false) }, PostsEmotionsCountByEmotion: async (object, params, context, resolveInfo) => { const session = context.driver.session() diff --git a/backend/src/schema/types/schema.gql b/backend/src/schema/types/schema.gql index d4959889f..6d9ec99db 100644 --- a/backend/src/schema/types/schema.gql +++ b/backend/src/schema/types/schema.gql @@ -4,10 +4,10 @@ type Query { currentUser: User # Get the latest Network Statistics statistics: Statistics! - findPosts(query: String!, limit: Int = 10): [Post]! + findPosts(filter: String!, limit: Int = 10): [Post]! @cypher( statement: """ - CALL db.index.fulltext.queryNodes('full_text_search', $query) + CALL db.index.fulltext.queryNodes('full_text_search', $filter) YIELD node as post, score MATCH (post)<-[:WROTE]-(user:User) WHERE score >= 0.2 diff --git a/webapp/store/search.js b/webapp/store/search.js index 0d0172a98..103cb2493 100644 --- a/webapp/store/search.js +++ b/webapp/store/search.js @@ -46,8 +46,8 @@ export const actions = { await this.app.apolloProvider.defaultClient .query({ query: gql` - query findPosts($query: String!) { - findPosts(query: $query, limit: 10) { + query findPosts($filter: String!) { + findPosts(filter: $filter, limit: 10) { id slug label: title @@ -63,7 +63,7 @@ export const actions = { } `, variables: { - query: value.replace(/\s/g, '~ ') + '~', + filter: value.replace(/\s/g, '~ ') + '~', }, }) .then(res => { From cf60397477545c6a742dd41717dfdb8313dd0cb9 Mon Sep 17 00:00:00 2001 From: Matt Rider Date: Fri, 30 Aug 2019 07:47:57 +0200 Subject: [PATCH 5/6] Fix failing cypress test, add steps - Added step to expose the search feature was completely broken after my latest commit. - when a user blocks another user, the search functionality just stopped working. - reverted changes to @roschaefer hacky fix of the search functionality --- backend/src/schema/types/schema.gql | 5 +-- cypress/integration/common/steps.js | 4 +-- .../blocked-users/Blocking.feature | 35 +++++++++++-------- webapp/store/search.js | 7 ++-- 4 files changed, 30 insertions(+), 21 deletions(-) diff --git a/backend/src/schema/types/schema.gql b/backend/src/schema/types/schema.gql index 6d9ec99db..62f84d677 100644 --- a/backend/src/schema/types/schema.gql +++ b/backend/src/schema/types/schema.gql @@ -4,15 +4,16 @@ type Query { currentUser: User # Get the latest Network Statistics statistics: Statistics! - findPosts(filter: String!, limit: Int = 10): [Post]! + findPosts(query: String!, limit: Int = 10, filter: _PostFilter): [Post]! @cypher( statement: """ - CALL db.index.fulltext.queryNodes('full_text_search', $filter) + CALL db.index.fulltext.queryNodes('full_text_search', $query) YIELD node as post, score MATCH (post)<-[:WROTE]-(user:User) WHERE score >= 0.2 AND NOT user.deleted = true AND NOT user.disabled = true AND NOT post.deleted = true AND NOT post.disabled = true + AND NOT user.id in COALESCE($filter.author_not.id_in, []) RETURN post LIMIT $limit """ diff --git a/cypress/integration/common/steps.js b/cypress/integration/common/steps.js index 4387feeaf..e3db43e14 100644 --- a/cypress/integration/common/steps.js +++ b/cypress/integration/common/steps.js @@ -168,13 +168,13 @@ Given("we have the following posts in our database:", table => { }; postAttributes.deleted = Boolean(postAttributes.deleted); const disabled = Boolean(postAttributes.disabled); - postAttributes.categoryIds = [`cat${i}`]; + postAttributes.categoryIds = [`cat${i}${new Date()}`]; postAttributes; cy.factory() .create("User", userAttributes) .authenticateAs(userAttributes) .create("Category", { - id: `cat${i}`, + id: `cat${i}${new Date()}`, name: "Just For Fun", slug: `just-for-fun-${i}`, icon: "smile" diff --git a/cypress/integration/user_profile/blocked-users/Blocking.feature b/cypress/integration/user_profile/blocked-users/Blocking.feature index 3ce4fd6c4..64e05dbbf 100644 --- a/cypress/integration/user_profile/blocked-users/Blocking.feature +++ b/cypress/integration/user_profile/blocked-users/Blocking.feature @@ -9,23 +9,26 @@ Feature: Block a User And I am logged in And we have a selection of categories - Scenario: Block a user - Given I am on the profile page of the annoying user - When I click on "Block user" from the content menu in the user info box - And I navigate to my "Blocked users" settings page - Then I can see the following table: - | Avatar | Name | - | | Spammy Spammer | + # Scenario: Block a user + # Given I am on the profile page of the annoying user + # When I click on "Block user" from the content menu in the user info box + # And I navigate to my "Blocked users" settings page + # Then I can see the following table: + # | Avatar | Name | + # | | Spammy Spammer | - Scenario: Block a previously followed user - Given I follow the user "Spammy Spammer" - And "Spammy Spammer" wrote a post "Spam Spam Spam" - When I visit the profile page of the annoying user - And I click on "Block user" from the content menu in the user info box - Then the list of posts of this user is empty - And nobody is following the user profile anymore + # Scenario: Block a previously followed user + # Given I follow the user "Spammy Spammer" + # And "Spammy Spammer" wrote a post "Spam Spam Spam" + # When I visit the profile page of the annoying user + # And I click on "Block user" from the content menu in the user info box + # Then the list of posts of this user is empty + # And nobody is following the user profile anymore Scenario: Posts of blocked users are filtered from search results + Given we have the following posts in our database: + | Author | id | title | content | + | Some unblocked user | im-not-blocked | Post that should be seen | cause I'm not blocked | Given "Spammy Spammer" wrote a post "Spam Spam Spam" When I search for "Spam" Then I should see the following posts in the select dropdown: @@ -35,3 +38,7 @@ Feature: Block a User And I refresh the page And I search for "Spam" Then the search has no results + But I search for "not blocked" + Then I should see the following posts in the select dropdown: + | title | + | Post that should be seen | diff --git a/webapp/store/search.js b/webapp/store/search.js index 103cb2493..a65e020cb 100644 --- a/webapp/store/search.js +++ b/webapp/store/search.js @@ -46,8 +46,8 @@ export const actions = { await this.app.apolloProvider.defaultClient .query({ query: gql` - query findPosts($filter: String!) { - findPosts(filter: $filter, limit: 10) { + query findPosts($query: String!, $filter: _PostFilter) { + findPosts(query: $query, limit: 10, filter: $filter) { id slug label: title @@ -63,7 +63,8 @@ export const actions = { } `, variables: { - filter: value.replace(/\s/g, '~ ') + '~', + query: value.replace(/\s/g, '~ ') + '~', + filter: {}, }, }) .then(res => { From f6ba3cf5816c11a010d6ae9f530f59db744d5653 Mon Sep 17 00:00:00 2001 From: Matt Rider Date: Fri, 30 Aug 2019 08:00:07 +0200 Subject: [PATCH 6/6] Uncomment out feature steps --- .../blocked-users/Blocking.feature | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/cypress/integration/user_profile/blocked-users/Blocking.feature b/cypress/integration/user_profile/blocked-users/Blocking.feature index 64e05dbbf..ed784b803 100644 --- a/cypress/integration/user_profile/blocked-users/Blocking.feature +++ b/cypress/integration/user_profile/blocked-users/Blocking.feature @@ -9,21 +9,21 @@ Feature: Block a User And I am logged in And we have a selection of categories - # Scenario: Block a user - # Given I am on the profile page of the annoying user - # When I click on "Block user" from the content menu in the user info box - # And I navigate to my "Blocked users" settings page - # Then I can see the following table: - # | Avatar | Name | - # | | Spammy Spammer | + Scenario: Block a user + Given I am on the profile page of the annoying user + When I click on "Block user" from the content menu in the user info box + And I navigate to my "Blocked users" settings page + Then I can see the following table: + | Avatar | Name | + | | Spammy Spammer | - # Scenario: Block a previously followed user - # Given I follow the user "Spammy Spammer" - # And "Spammy Spammer" wrote a post "Spam Spam Spam" - # When I visit the profile page of the annoying user - # And I click on "Block user" from the content menu in the user info box - # Then the list of posts of this user is empty - # And nobody is following the user profile anymore + Scenario: Block a previously followed user + Given I follow the user "Spammy Spammer" + And "Spammy Spammer" wrote a post "Spam Spam Spam" + When I visit the profile page of the annoying user + And I click on "Block user" from the content menu in the user info box + Then the list of posts of this user is empty + And nobody is following the user profile anymore Scenario: Posts of blocked users are filtered from search results Given we have the following posts in our database: