diff --git a/frontend/blog_portal/cypress/e2e/post_page.cy.ts b/frontend/blog_portal/cypress/e2e/post_page.cy.ts new file mode 100644 index 0000000..4bf4a8c --- /dev/null +++ b/frontend/blog_portal/cypress/e2e/post_page.cy.ts @@ -0,0 +1,136 @@ +describe("post page", function () { + beforeEach(function () { + cy.resetDb(); + cy.clearMail(); + cy.seedConfirmedUser({ + email: "alice@example.com", + displayName: "alice", + password: "longenoughpassword", + }); + cy.seedConfirmedUser({ + email: "bob@example.com", + displayName: "bob", + password: "longenoughpassword", + }); + cy.seedPostAs({ + email: "alice@example.com", + password: "longenoughpassword", + title: "Alice post", + body: "Body of alice's post.", + }).as("alicePost"); + }); + + it("renders the post for anonymous visitors with a login CTA", function () { + cy.get<{ id: number }>("@alicePost").then(function (post) { + cy.visit(`/posts/${post.id}`); + cy.contains("h1", "Alice post").should("be.visible"); + cy.contains("a", "alice").should("be.visible"); + cy.contains("Comments (0)").should("be.visible"); + cy.contains("Log in").should("be.visible"); + cy.get(".comment-form").should("not.exist"); + }); + }); + + it("lets a signed-in user add a comment", function () { + cy.loginViaApi({ + email: "bob@example.com", + password: "longenoughpassword", + }); + + cy.get<{ id: number }>("@alicePost").then(function (post) { + cy.visit(`/posts/${post.id}`); + cy.get(".comment-form textarea").type("nice post"); + cy.contains(".comment-form button", "Comment").click(); + + cy.contains(".comment-list li", "nice post").should("be.visible"); + cy.contains(".comment-list li", "bob").should("be.visible"); + cy.contains("Comments (1)").should("be.visible"); + }); + }); + + it("only shows the Delete control on comments you can delete", function () { + cy.loginViaApi({ + email: "bob@example.com", + password: "longenoughpassword", + }); + + cy.get<{ id: number }>("@alicePost").then(function (post) { + cy.request("POST", `/api/posts/${post.id}/comments`, { + body: "bob's comment", + }); + cy.logoutViaApi(); + cy.loginViaApi({ + email: "alice@example.com", + password: "longenoughpassword", + }); + cy.request("POST", `/api/posts/${post.id}/comments`, { + body: "alice's comment", + }); + + cy.visit(`/posts/${post.id}`); + cy.contains(".comment-list li", "alice's comment") + .find("button.delete") + .should("exist"); + cy.contains(".comment-list li", "bob's comment") + .find("button.delete") + .should("not.exist"); + }); + }); + + it("hides the Delete post control for non-author non-admin users", function () { + cy.loginViaApi({ + email: "bob@example.com", + password: "longenoughpassword", + }); + + cy.get<{ id: number }>("@alicePost").then(function (post) { + cy.visit(`/posts/${post.id}`); + cy.contains("button", "Delete post").should("not.exist"); + cy.contains("button", "Feature in slot 1").should("not.exist"); + }); + }); + + it("lets the author delete their post", function () { + cy.loginViaApi({ + email: "alice@example.com", + password: "longenoughpassword", + }); + + cy.get<{ id: number }>("@alicePost").then(function (post) { + cy.visit(`/posts/${post.id}`); + cy.contains("button", "Delete post").click(); + cy.location("pathname").should("eq", "/"); + }); + }); + + it("shows admin controls (delete, feature, unfeature) to admins", function () { + cy.seedAdmin({ + email: "admin@example.com", + displayName: "rootadmin", + password: "longenoughpassword", + }); + cy.loginViaApi({ + email: "admin@example.com", + password: "longenoughpassword", + }); + + cy.get<{ id: number }>("@alicePost").then(function (post) { + cy.visit(`/posts/${post.id}`); + cy.contains("button", "Delete post").should("be.visible"); + cy.contains("button", "Feature in slot 1").should("be.visible"); + cy.contains("button", "Feature in slot 2").should("be.visible"); + + cy.contains("button", "Feature in slot 1").click(); + cy.contains(".badge", "Featured (slot 1)").should("be.visible"); + cy.contains("button", "Unfeature").should("be.visible"); + + cy.contains("button", "Unfeature").click(); + cy.contains(".badge", "Featured").should("not.exist"); + }); + }); + + it("shows a not-found panel for unknown post ids", function () { + cy.visit("/posts/9999"); + cy.contains("h1", "Post not found").should("be.visible"); + }); +});