diff --git a/backend/src/schema/resolvers/posts.js b/backend/src/schema/resolvers/posts.js index 37710dc38..b5ffc7755 100644 --- a/backend/src/schema/resolvers/posts.js +++ b/backend/src/schema/resolvers/posts.js @@ -83,17 +83,14 @@ export default { await session.run(cypherDeletePreviousRelations, { params }) - let updatePostCypher = `MATCH (post:Post {id: $params.id}) + const updatePostCypher = `MATCH (post:Post {id: $params.id}) SET post = $params - ` - if (categoryIds && categoryIds.length) { - updatePostCypher += `WITH post - UNWIND $categoryIds AS categoryId - MATCH (category:Category {id: categoryId}) - MERGE (post)-[:CATEGORIZED]->(category) - ` - } - updatePostCypher += `RETURN post` + WITH post + UNWIND $categoryIds AS categoryId + MATCH (category:Category {id: categoryId}) + MERGE (post)-[:CATEGORIZED]->(category) + RETURN post` + const updatePostVariables = { categoryIds, params } const transactionRes = await session.run(updatePostCypher, updatePostVariables) @@ -110,22 +107,18 @@ export default { const { categoryIds } = params delete params.categoryIds params = await fileUpload(params, { file: 'imageUpload', url: 'image' }) - params.id = params.id || uuid() - let createPostCypher = `CREATE (post:Post {params}) - WITH post - MATCH (author:User {id: $userId}) - MERGE (post)<-[:WROTE]-(author) - ` - if (categoryIds) { - createPostCypher += `WITH post + const createPostCypher = `CREATE (post:Post {params}) + WITH post + MATCH (author:User {id: $userId}) + MERGE (post)<-[:WROTE]-(author) + WITH post UNWIND $categoryIds AS categoryId MATCH (category:Category {id: categoryId}) MERGE (post)-[:CATEGORIZED]->(category) - ` - } - createPostCypher += `RETURN post` + RETURN post` + const createPostVariables = { userId: context.user.id, categoryIds, params } const session = context.driver.session() diff --git a/backend/src/schema/resolvers/posts.spec.js b/backend/src/schema/resolvers/posts.spec.js index f67b39da4..44618ecdc 100644 --- a/backend/src/schema/resolvers/posts.spec.js +++ b/backend/src/schema/resolvers/posts.spec.js @@ -74,22 +74,22 @@ beforeEach(async () => { } await factory.create('User', userParams) await Promise.all([ - factory.create('Category', { + instance.create('Category', { id: 'cat9', name: 'Democracy & Politics', icon: 'university', }), - factory.create('Category', { + instance.create('Category', { id: 'cat4', name: 'Environment & Nature', icon: 'tree', }), - factory.create('Category', { + instance.create('Category', { id: 'cat15', name: 'Consumption & Sustainability', icon: 'shopping-cart', }), - factory.create('Category', { + instance.create('Category', { id: 'cat27', name: 'Animal Protection', icon: 'paw', diff --git a/cypress/integration/administration/TagsAndCategories.feature b/cypress/integration/administration/TagsAndCategories.feature index e543b143b..7d0adb6a9 100644 --- a/cypress/integration/administration/TagsAndCategories.feature +++ b/cypress/integration/administration/TagsAndCategories.feature @@ -15,7 +15,9 @@ Feature: Tags and Categories Background: Given my user account has the role "admin" - And we have a selection of tags and categories as well as posts + And we have a selection of categories + And we have a selection of tags + And we have a selection of posts And I am logged in Scenario: See an overview of categories @@ -24,8 +26,8 @@ Feature: Tags and Categories Then I can see the following table: | | Name | Posts | | | Just For Fun | 2 | - | | Happyness & Values | 1 | - | | Health & Wellbeing | 0 | + | | Happiness & Values | 1 | + | | Health & Wellbeing | 1 | Scenario: See an overview of tags When I navigate to the administration dashboard diff --git a/cypress/integration/common/steps.js b/cypress/integration/common/steps.js index 7192b097b..61ae5d589 100644 --- a/cypress/integration/common/steps.js +++ b/cypress/integration/common/steps.js @@ -20,20 +20,19 @@ const narratorParams = { Given("I am logged in", () => { cy.login(loginCredentials); }); - -Given("we have a selection of tags and categories as well as posts", () => { +Given("we have a selection of categories", () => { cy.factory() .authenticateAs(loginCredentials) .create("Category", { id: "cat1", name: "Just For Fun", - slug: "justforfun", + slug: "just-for-fun", icon: "smile" }) .create("Category", { id: "cat2", - name: "Happyness & Values", - slug: "happyness-values", + name: "Happiness & Values", + slug: "happiness-values", icon: "heart-o" }) .create("Category", { @@ -41,11 +40,18 @@ Given("we have a selection of tags and categories as well as posts", () => { name: "Health & Wellbeing", slug: "health-wellbeing", icon: "medkit" - }) + }); +}); + +Given("we have a selection of tags", () => { + cy.factory() + .authenticateAs(loginCredentials) .create("Tag", { id: "Ecology" }) .create("Tag", { id: "Nature" }) .create("Tag", { id: "Democracy" }); +}); +Given("we have a selection of posts", () => { const someAuthor = { id: "authorId", email: "author@example.org", @@ -59,18 +65,15 @@ Given("we have a selection of tags and categories as well as posts", () => { cy.factory() .create("User", someAuthor) .authenticateAs(someAuthor) - .create("Post", { id: "p0" }) - .create("Post", { id: "p1" }); + .create("Post", { id: "p0", categoryIds: ["cat1"] }) + .create("Post", { id: "p1", categoryIds: ["cat2"] }); cy.factory() .create("User", yetAnotherAuthor) .authenticateAs(yetAnotherAuthor) - .create("Post", { id: "p2" }); + .create("Post", { id: "p2", categoryIds: ["cat1"] }); cy.factory() .authenticateAs(loginCredentials) - .create("Post", { id: "p3" }) - .relate("Post", "Categories", { from: "p0", to: "cat1" }) - .relate("Post", "Categories", { from: "p1", to: "cat2" }) - .relate("Post", "Categories", { from: "p2", to: "cat1" }) + .create("Post", { id: "p3", categoryIds: ["cat3"] }) .relate("Post", "Tags", { from: "p0", to: "Ecology" }) .relate("Post", "Tags", { from: "p0", to: "Nature" }) .relate("Post", "Tags", { from: "p0", to: "Democracy" }) @@ -182,9 +185,17 @@ 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; cy.factory() .create("User", userAttributes) .authenticateAs(userAttributes) + .create("Category", { + id: `cat${i}`, + name: "Just For Fun", + slug: `just-for-fun-${i}`, + icon: "smile" + }) .create("Post", postAttributes); if (disabled) { const moderatorParams = { @@ -218,6 +229,7 @@ When( Given("I previously created a post", () => { lastPost.title = "previously created post"; lastPost.content = "with some content"; + lastPost.categoryIds = "cat1"; cy.factory() .authenticateAs(loginCredentials) .create("Post", lastPost); @@ -233,6 +245,12 @@ When("I type in the following text:", text => { cy.get(".editor .ProseMirror").type(lastPost.content); }); +Then("I select a category", () => { + cy.get("span") + .contains("Just for Fun") + .click(); +}); + Then("the post shows up on the landing page at position {int}", index => { cy.openPage("landing"); const selector = `.post-card:nth-child(${index}) > .ds-card-content`; @@ -260,7 +278,9 @@ Then("the first post on the landing page has the title:", title => { Then( "the page {string} returns a 404 error with a message:", (route, message) => { - cy.request({ url: route, failOnStatusCode: false }).its('status').should('eq', 404) + cy.request({ url: route, failOnStatusCode: false }) + .its("status") + .should("eq", 404); cy.visit(route, { failOnStatusCode: false }); cy.get(".error").should("contain", message); } @@ -422,7 +442,7 @@ Given('"Spammy Spammer" wrote a post {string}', title => { email: "spammy-spammer@example.org", password: "1234" }) - .create("Post", { title }); + .create("Post", { title, categoryIds: ["cat2"] }); }); Then("the list of posts of this user is empty", () => { @@ -441,7 +461,7 @@ Then("nobody is following the user profile anymore", () => { Given("I wrote a post {string}", title => { cy.factory() .authenticateAs(loginCredentials) - .create("Post", { title }); + .create("Post", { title, categoryIds: ["cat2"] }); }); When("I block the user {string}", name => { @@ -466,3 +486,14 @@ Then("I see only one post with the title {string}", title => { .should("have.length", 1); cy.get(".main-container").contains(".post-link", title); }); + +And("some categories exist", () => { + cy.factory() + .authenticateAs(loginCredentials) + .create("Category", { + id: "cat1", + name: "Just For Fun", + slug: `just-for-fun`, + icon: "smile" + }); +}); diff --git a/cypress/integration/moderation/HidePosts.feature b/cypress/integration/moderation/HidePosts.feature index e886e5f95..bb82c7188 100644 --- a/cypress/integration/moderation/HidePosts.feature +++ b/cypress/integration/moderation/HidePosts.feature @@ -7,20 +7,20 @@ Feature: Hide Posts Given we have the following posts in our database: | id | title | deleted | disabled | | p1 | This post should be visible | | | - | p2 | This post is disabled | | x | - | p3 | This post is deleted | x | | + | p2 | This post is disabled | | x | + | p3 | This post is deleted | x | | Scenario: Disabled posts don't show up on the landing page Given I am logged in with a "user" role Then I should see only 1 post on the landing page And the first post on the landing page has the title: - """ - This post should be visible - """ + """ + This post should be visible + """ Scenario: Visiting a disabled post's page should return 404 Given I am logged in with a "user" role Then the page "/post/this-post-is-disabled" returns a 404 error with a message: - """ - This post could not be found - """ + """ + This post could not be found + """ diff --git a/cypress/integration/post/WritePost.feature b/cypress/integration/post/WritePost.feature index 06ac4a175..461766532 100644 --- a/cypress/integration/post/WritePost.feature +++ b/cypress/integration/post/WritePost.feature @@ -6,6 +6,7 @@ Feature: Create a post Background: Given I have a user account And I am logged in + And we have a selection of categories And I am on the "landing" page Scenario: Create a post @@ -16,6 +17,7 @@ Feature: Create a post Human Connection is a free and open-source social network for active citizenship. """ + Then I select a category And I click on "Save" Then I get redirected to ".../my-first-post" And the post was saved successfully diff --git a/cypress/integration/user_profile/blocked-users/Blocking.feature b/cypress/integration/user_profile/blocked-users/Blocking.feature index 9ab4fde6e..3ce4fd6c4 100644 --- a/cypress/integration/user_profile/blocked-users/Blocking.feature +++ b/cypress/integration/user_profile/blocked-users/Blocking.feature @@ -7,6 +7,7 @@ Feature: Block a User Given I have a user account And there is an annoying user called "Spammy Spammer" 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 diff --git a/webapp/components/CategoriesSelect/CategoriesSelect.vue b/webapp/components/CategoriesSelect/CategoriesSelect.vue index e1928b240..cbe46b890 100644 --- a/webapp/components/CategoriesSelect/CategoriesSelect.vue +++ b/webapp/components/CategoriesSelect/CategoriesSelect.vue @@ -27,7 +27,7 @@