diff --git a/backend/src/schema/resolvers/searches.js b/backend/src/schema/resolvers/searches.js index 5316ccd9a..bfbdd21b1 100644 --- a/backend/src/schema/resolvers/searches.js +++ b/backend/src/schema/resolvers/searches.js @@ -20,7 +20,7 @@ export default { AND NOT ( author.deleted = true OR author.disabled = true OR resource.deleted = true OR resource.disabled = true - OR (:User { id: $thisUserId })-[:BLOCKED]-(author) + OR (:User { id: $thisUserId })-[:MUTED]-(author) ) WITH resource, author, [(resource)<-[:COMMENTS]-(comment:Comment) | comment] as comments, diff --git a/backend/src/schema/resolvers/users.js b/backend/src/schema/resolvers/users.js index dc962dc00..915d8b6f8 100644 --- a/backend/src/schema/resolvers/users.js +++ b/backend/src/schema/resolvers/users.js @@ -23,6 +23,21 @@ export const getMutedUsers = async context => { return mutedUsers } +export const getBlockedUsers = async context => { + const { neode } = context + const userModel = neode.model('User') + let blockedUsers = neode + .query() + .match('user', userModel) + .where('user.id', context.user.id) + .relationship(userModel.relationships().get('blocked')) + .to('blocked', userModel) + .return('blocked') + blockedUsers = await blockedUsers.execute() + blockedUsers = blockedUsers.records.map(r => r.get('blocked').properties) + return blockedUsers +} + export default { Query: { mutedUsers: async (object, args, context, resolveInfo) => { @@ -32,6 +47,13 @@ export default { throw new UserInputError(e.message) } }, + blockedUsers: async (object, args, context, resolveInfo) => { + try { + return getBlockedUsers(context) + } catch (e) { + throw new UserInputError(e.message) + } + }, User: async (object, args, context, resolveInfo) => { const { email } = args if (email) { diff --git a/cypress/integration/common/steps.js b/cypress/integration/common/steps.js index 53b5f7c3d..29f2fa85a 100644 --- a/cypress/integration/common/steps.js +++ b/cypress/integration/common/steps.js @@ -39,7 +39,7 @@ Given("I am logged in", () => { cy.login(loginCredentials); }); -Given("I am logged in as the muted user", () => { +Given("I am logged in as the {string} user", _ => { cy.login({ email: annoyingParams.email, password: '1234' }); }); @@ -123,6 +123,12 @@ When("I visit the {string} page", page => { cy.openPage(page); }); +When("the blocked user visits my post", () => { + cy.logout() + .login({ email: annoyingParams.email, password: annoyingParams.password }) + .openPage('/post/previously-created-post') +}) + Given("I am on the {string} page", page => { cy.openPage(page); }); @@ -485,7 +491,7 @@ Given("I follow the user {string}", name => { }); }); -Given('"Spammy Spammer" wrote a post {string}', title => { +Given('{string} wrote a post {string}', (_, title) => { cy.createCategories("cat21") .factory() .create("Post", { @@ -532,6 +538,20 @@ When("I mute the user {string}", name => { }); }); +When("I block the user {string}", name => { + cy.neode() + .first("User", { + name + }) + .then(blockedUser => { + cy.neode() + .first("User", { + name: narratorParams.name + }) + .relateTo(blockedUser, "blocked"); + }); +}); + When("I log in with:", table => { const [firstRow] = table.hashes(); const { @@ -550,3 +570,11 @@ Then("I see only one post with the title {string}", title => { .should("have.length", 1); cy.get(".main-container").contains(".post-link", title); }); + +Then("they should not see the comment from", () => { + cy.get(".ds-card-footer").children().should('not.have.class', 'comment-form') +}) + +Then("they should see a text explaining commenting is not possible", () => { + cy.get('.ds-placeholder').should('contain', "Commenting is not possible at this time on this post.") +}) \ No newline at end of file diff --git a/cypress/integration/user_profile/BlockUser.feature b/cypress/integration/user_profile/BlockUser.feature new file mode 100644 index 000000000..a04455b53 --- /dev/null +++ b/cypress/integration/user_profile/BlockUser.feature @@ -0,0 +1,48 @@ +Feature: Block a User + As a user + I'd like to have a button to block another user + To prevent him from seeing and interacting with my contributions + + Background: + Given I have a user account + And there is an annoying user called "Harassing User" + And I am logged in + + 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 | + | | Harassing User | + + Scenario: Blocked user cannot interact with my contributions + Given I block the user "Harassing User" + And I previously created a post + And the blocked user visits my post + Then they should not see the comment from + And they should see a text explaining commenting is not possible + + Scenario: Block a previously followed user + Given I follow the user "Harassing User" + 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 + And nobody is following the user profile anymore + + Scenario: Posts of blocked users are not filtered from search results + Given "Harassing User" wrote a post "You can still see my posts" + And I block the user "Harassing User" + When I search for "see" + Then I should see the following posts in the select dropdown: + | title | + | You can still see my posts | + + Scenario: Blocked users can still see my posts + Given I previously created a post + And I block the user "Harassing User" + Given I log out + And I am logged in as the "blocked" user + When I search for "previously created" + Then I should see the following posts in the select dropdown: + | title | + | previously created post | diff --git a/cypress/integration/user_profile/mute-users/Mute.feature b/cypress/integration/user_profile/mute-users/Mute.feature index b52faeeaa..cd7d1c827 100644 --- a/cypress/integration/user_profile/mute-users/Mute.feature +++ b/cypress/integration/user_profile/mute-users/Mute.feature @@ -1,8 +1,7 @@ Feature: Mute a User As a user I'd like to have a button to mute another user - To prevent him from seeing and interacting with my contributions and also to avoid seeing his/her posts - + To prevent him from seeing and interacting with my contributions Background: Given I have a user account And there is an annoying user called "Spammy Spammer" @@ -46,7 +45,7 @@ Feature: Mute a User Given I previously created a post And I mute the user "Spammy Spammer" Given I log out - And I am logged in as the muted user + And I am logged in as the "muted" user When I search for "previously created" Then I should see the following posts in the select dropdown: | title | diff --git a/webapp/components/ContentMenu/ContentMenu.vue b/webapp/components/ContentMenu/ContentMenu.vue index a22bc3267..31d90a614 100644 --- a/webapp/components/ContentMenu/ContentMenu.vue +++ b/webapp/components/ContentMenu/ContentMenu.vue @@ -172,6 +172,23 @@ export default { icon: 'user-times', }) } + if (this.resource.isBlocked) { + routes.push({ + label: this.$t(`settings.blocked-users.unblock`), + callback: () => { + this.$emit('unblock', this.resource) + }, + icon: 'user-plus', + }) + } else { + routes.push({ + label: this.$t(`settings.blocked-users.block`), + callback: () => { + this.$emit('block', this.resource) + }, + icon: 'user-times', + }) + } } } diff --git a/webapp/locales/en.json b/webapp/locales/en.json index 2191a91e7..e36214d8a 100644 --- a/webapp/locales/en.json +++ b/webapp/locales/en.json @@ -337,7 +337,9 @@ "your-perspective": "You will no longer be able to interact with their contributions.", "their-perspective": "Vice versa: The blocked person will also no longer be able to interact with your contributions.", "notifications": "Blocked users will no longer receive notifications if they mention each other.", - "closing": "This should be sufficient for now so that blocked users can no longer bother you." + "closing": "This should be sufficient for now so that blocked users can no longer bother you.", + "commenting-disabled": "Commenting is not possible at this time on this post.", + "commenting-explanation": "This can happen for several reasons, please see our " }, "columns": { "name": "Name", diff --git a/webapp/pages/profile/_id/_slug.vue b/webapp/pages/profile/_id/_slug.vue index ce220b66b..01190caa2 100644 --- a/webapp/pages/profile/_id/_slug.vue +++ b/webapp/pages/profile/_id/_slug.vue @@ -24,6 +24,8 @@ class="user-content-menu" @mute="muteUser" @unmute="unmuteUser" + @block="blockUser" + @unblock="unblockUser" /> @@ -67,7 +69,7 @@