Compare commits
No commits in common. "72cdd7dc4e3255d8c0359eb08c3017dcedbe776f" and "178193bfd83f2cafc78e636c2e3f8f29a621df31" have entirely different histories.
72cdd7dc4e
...
178193bfd8
9 changed files with 0 additions and 682 deletions
|
|
@ -1,99 +0,0 @@
|
||||||
describe("admin actions", function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
cy.resetDb();
|
|
||||||
cy.clearMail();
|
|
||||||
cy.seedAdmin({
|
|
||||||
email: "admin@example.com",
|
|
||||||
displayName: "rootadmin",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
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.",
|
|
||||||
}).as("alicePost");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("admin promotes another user via the profile page", function () {
|
|
||||||
cy.loginViaApi({
|
|
||||||
email: "admin@example.com",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit("/users/alice");
|
|
||||||
cy.contains("button", "Promote to admin").click();
|
|
||||||
|
|
||||||
cy.logoutViaApi();
|
|
||||||
cy.loginViaApi({
|
|
||||||
email: "alice@example.com",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
cy.get<{ id: number }>("@alicePost").then(function (post) {
|
|
||||||
cy.visit(`/posts/${post.id}`);
|
|
||||||
cy.contains("button", "Feature in slot 1").should("be.visible");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("admin features a post and it shows up on the home page", function () {
|
|
||||||
cy.loginViaApi({
|
|
||||||
email: "admin@example.com",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.get<{ id: number }>("@alicePost").then(function (post) {
|
|
||||||
cy.visit(`/posts/${post.id}`);
|
|
||||||
cy.contains("button", "Feature in slot 1").click();
|
|
||||||
cy.contains(".badge", "Featured (slot 1)").should("be.visible");
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.logoutViaApi();
|
|
||||||
cy.visit("/");
|
|
||||||
cy.contains("h2", "Featured").should("be.visible");
|
|
||||||
cy.get(".featured .post-card").should("have.length", 1);
|
|
||||||
cy.contains(".featured .post-card", "Alice post").should("be.visible");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("admin unfeaturing a post removes it from the home page", function () {
|
|
||||||
cy.loginViaApi({
|
|
||||||
email: "admin@example.com",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.get<{ id: number }>("@alicePost").then(function (post) {
|
|
||||||
cy.visit(`/posts/${post.id}`);
|
|
||||||
cy.contains("button", "Feature in slot 1").click();
|
|
||||||
cy.contains(".badge", "Featured (slot 1)").should("be.visible");
|
|
||||||
cy.contains("button", "Unfeature").click();
|
|
||||||
cy.contains(".badge", "Featured").should("not.exist");
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.logoutViaApi();
|
|
||||||
cy.visit("/");
|
|
||||||
cy.contains("h2", "Featured").should("not.exist");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("a newly promoted admin can also feature posts", function () {
|
|
||||||
cy.promoteAdmin("bob@example.com");
|
|
||||||
cy.loginViaApi({
|
|
||||||
email: "bob@example.com",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.get<{ id: number }>("@alicePost").then(function (post) {
|
|
||||||
cy.visit(`/posts/${post.id}`);
|
|
||||||
cy.contains("button", "Feature in slot 2").click();
|
|
||||||
cy.contains(".badge", "Featured (slot 2)").should("be.visible");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
describe("confirm email page", function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
cy.resetDb();
|
|
||||||
cy.clearMail();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("redirects to /login when no token is present", function () {
|
|
||||||
cy.visit("/confirm-email");
|
|
||||||
cy.location("pathname").should("eq", "/login");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("sets the password and redirects to /login on success", function () {
|
|
||||||
cy.signupViaApi({
|
|
||||||
email: "alice@example.com",
|
|
||||||
displayName: "alice",
|
|
||||||
});
|
|
||||||
cy.fetchLatestConfirmToken("alice@example.com").then(function (token) {
|
|
||||||
cy.visit(`/confirm-email?token=${token}`);
|
|
||||||
cy.get('input[type="password"]').type("longenoughpassword");
|
|
||||||
cy.contains("button", "Confirm").click();
|
|
||||||
|
|
||||||
cy.location("pathname").should("eq", "/login");
|
|
||||||
|
|
||||||
cy.loginViaApi({
|
|
||||||
email: "alice@example.com",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("shows the backend error when password is too short", function () {
|
|
||||||
cy.signupViaApi({
|
|
||||||
email: "alice@example.com",
|
|
||||||
displayName: "alice",
|
|
||||||
});
|
|
||||||
cy.fetchLatestConfirmToken("alice@example.com").then(function (token) {
|
|
||||||
cy.visit(`/confirm-email?token=${token}`);
|
|
||||||
cy.get('input[type="password"]')
|
|
||||||
.invoke("removeAttr", "minlength")
|
|
||||||
.type("short");
|
|
||||||
cy.contains("button", "Confirm").click();
|
|
||||||
|
|
||||||
cy.contains(".error", "password must be at least 8").should(
|
|
||||||
"be.visible",
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
describe("guest route guards", function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
cy.resetDb();
|
|
||||||
cy.clearMail();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("redirects anonymous visitors away from /users/:displayName/posts/new", function () {
|
|
||||||
cy.visit("/users/alice/posts/new");
|
|
||||||
cy.location("pathname").should("eq", "/login");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("redirects authenticated visitors away from /login", function () {
|
|
||||||
cy.seedConfirmedUser({
|
|
||||||
email: "alice@example.com",
|
|
||||||
displayName: "alice",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
cy.loginViaApi({
|
|
||||||
email: "alice@example.com",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit("/login");
|
|
||||||
cy.location("pathname").should("eq", "/");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("redirects authenticated visitors away from /signup", function () {
|
|
||||||
cy.seedConfirmedUser({
|
|
||||||
email: "alice@example.com",
|
|
||||||
displayName: "alice",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
cy.loginViaApi({
|
|
||||||
email: "alice@example.com",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit("/signup");
|
|
||||||
cy.location("pathname").should("eq", "/");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,101 +0,0 @@
|
||||||
describe("home 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 first",
|
|
||||||
body: "Alice's first post.",
|
|
||||||
});
|
|
||||||
cy.seedPostAs({
|
|
||||||
email: "bob@example.com",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
title: "Bob says hi",
|
|
||||||
body: "Bob's only post.",
|
|
||||||
});
|
|
||||||
cy.seedPostAs({
|
|
||||||
email: "alice@example.com",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
title: "Alice second",
|
|
||||||
body: "Alice's second post.",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("renders recent posts in newest-first order with author links", function () {
|
|
||||||
cy.visit("/");
|
|
||||||
cy.contains("h2", "Recent posts").should("be.visible");
|
|
||||||
cy.get(".recent .post-card").should("have.length", 3);
|
|
||||||
cy.get(".recent .post-card").first().within(function () {
|
|
||||||
cy.contains("Alice second");
|
|
||||||
cy.contains("a", "alice");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("hides the featured section when no posts are featured", function () {
|
|
||||||
cy.visit("/");
|
|
||||||
cy.contains("h2", "Featured").should("not.exist");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("shows featured posts in slot order once an admin features them", function () {
|
|
||||||
cy.seedAdmin({
|
|
||||||
email: "admin@example.com",
|
|
||||||
displayName: "rootadmin",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
cy.request("/api/posts").then(function (response) {
|
|
||||||
const posts = response.body.posts as Array<{
|
|
||||||
id: number;
|
|
||||||
title: string;
|
|
||||||
}>;
|
|
||||||
const aliceSecond = posts.find(function (entry) {
|
|
||||||
return entry.title === "Alice second";
|
|
||||||
})!;
|
|
||||||
const bobPost = posts.find(function (entry) {
|
|
||||||
return entry.title === "Bob says hi";
|
|
||||||
})!;
|
|
||||||
cy.seedFeaturedPost({
|
|
||||||
adminEmail: "admin@example.com",
|
|
||||||
adminPassword: "longenoughpassword",
|
|
||||||
postId: bobPost.id,
|
|
||||||
slot: 2,
|
|
||||||
});
|
|
||||||
cy.seedFeaturedPost({
|
|
||||||
adminEmail: "admin@example.com",
|
|
||||||
adminPassword: "longenoughpassword",
|
|
||||||
postId: aliceSecond.id,
|
|
||||||
slot: 1,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit("/");
|
|
||||||
cy.contains("h2", "Featured").should("be.visible");
|
|
||||||
cy.get(".featured .post-card").should("have.length", 2);
|
|
||||||
cy.get(".featured .post-card").eq(0).contains("Alice second");
|
|
||||||
cy.get(".featured .post-card").eq(1).contains("Bob says hi");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("searches users by display name and email prefix", function () {
|
|
||||||
cy.visit("/");
|
|
||||||
cy.get('input[type="search"]').type("al");
|
|
||||||
cy.get(".results li").should("have.length", 1);
|
|
||||||
cy.get(".results li").contains("alice");
|
|
||||||
|
|
||||||
cy.get('input[type="search"]').clear().type("b");
|
|
||||||
cy.get(".results li").should("have.length", 1);
|
|
||||||
cy.get(".results li").contains("bob");
|
|
||||||
|
|
||||||
cy.get('input[type="search"]').clear().type("zzz");
|
|
||||||
cy.get(".results li").should("have.length", 0);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
describe("login page", function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
cy.resetDb();
|
|
||||||
cy.clearMail();
|
|
||||||
cy.seedConfirmedUser({
|
|
||||||
email: "alice@example.com",
|
|
||||||
displayName: "alice",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("logs in with valid credentials and shows the user in the header", function () {
|
|
||||||
cy.visit("/login");
|
|
||||||
cy.get('input[type="email"]').type("alice@example.com");
|
|
||||||
cy.get('input[type="password"]').type("longenoughpassword");
|
|
||||||
cy.contains("button", "Log in").click();
|
|
||||||
|
|
||||||
cy.location("pathname").should("eq", "/");
|
|
||||||
cy.get(".app-header").contains("alice").should("be.visible");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("shows an error on wrong password", function () {
|
|
||||||
cy.visit("/login");
|
|
||||||
cy.get('input[type="email"]').type("alice@example.com");
|
|
||||||
cy.get('input[type="password"]').type("wrongpassword");
|
|
||||||
cy.contains("button", "Log in").click();
|
|
||||||
|
|
||||||
cy.location("pathname").should("eq", "/login");
|
|
||||||
cy.contains(".error", "invalid credentials").should("be.visible");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("redirects authenticated users away from /login", function () {
|
|
||||||
cy.loginViaApi({
|
|
||||||
email: "alice@example.com",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit("/login");
|
|
||||||
cy.location("pathname").should("eq", "/");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
describe("new 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",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("redirects anonymous visitors to /login", function () {
|
|
||||||
cy.visit("/users/alice/posts/new");
|
|
||||||
cy.location("pathname").should("eq", "/login");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("redirects users away from another user's new-post page", function () {
|
|
||||||
cy.loginViaApi({
|
|
||||||
email: "alice@example.com",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit("/users/bob/posts/new");
|
|
||||||
cy.location("pathname").should("eq", "/");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("publishes a post and redirects to the new post page", function () {
|
|
||||||
cy.loginViaApi({
|
|
||||||
email: "alice@example.com",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit("/users/alice/posts/new");
|
|
||||||
cy.get('input[type="text"]').type("Hello world");
|
|
||||||
cy.get("textarea").type("This is the body of my first post.");
|
|
||||||
cy.contains("button", "Publish").click();
|
|
||||||
|
|
||||||
cy.location("pathname").should("match", /^\/posts\/\d+$/);
|
|
||||||
cy.contains("h1", "Hello world").should("be.visible");
|
|
||||||
cy.contains(".body", "This is the body of my first post.").should(
|
|
||||||
"be.visible",
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("blocks submission when the title is empty (HTML5 validation)", function () {
|
|
||||||
cy.loginViaApi({
|
|
||||||
email: "alice@example.com",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit("/users/alice/posts/new");
|
|
||||||
cy.get("textarea").type("body only");
|
|
||||||
cy.contains("button", "Publish").click();
|
|
||||||
|
|
||||||
cy.location("pathname").should("eq", "/users/alice/posts/new");
|
|
||||||
cy.get('input[type="text"]:invalid').should("exist");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,136 +0,0 @@
|
||||||
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");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,86 +0,0 @@
|
||||||
describe("profile 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's only post",
|
|
||||||
body: "Hello.",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("shows posts to anonymous visitors without owner controls", function () {
|
|
||||||
cy.visit("/users/alice");
|
|
||||||
cy.contains("h1", "alice").should("be.visible");
|
|
||||||
cy.contains(".post-card", "Alice's only post").should("be.visible");
|
|
||||||
cy.contains("button", "New post").should("not.exist");
|
|
||||||
cy.contains("button", "Promote to admin").should("not.exist");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("shows the New post button when viewing your own profile", function () {
|
|
||||||
cy.loginViaApi({
|
|
||||||
email: "alice@example.com",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit("/users/alice");
|
|
||||||
cy.contains("button", "New post").should("be.visible");
|
|
||||||
cy.contains("button", "Promote to admin").should("not.exist");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("hides the Promote button from non-admin viewers", function () {
|
|
||||||
cy.loginViaApi({
|
|
||||||
email: "bob@example.com",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit("/users/alice");
|
|
||||||
cy.contains("button", "Promote to admin").should("not.exist");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("shows the Promote button to an admin viewing someone else", function () {
|
|
||||||
cy.seedAdmin({
|
|
||||||
email: "admin@example.com",
|
|
||||||
displayName: "rootadmin",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
cy.loginViaApi({
|
|
||||||
email: "admin@example.com",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit("/users/alice");
|
|
||||||
cy.contains("button", "Promote to admin").should("be.visible");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("hides the Promote button when an admin views their own profile", function () {
|
|
||||||
cy.seedAdmin({
|
|
||||||
email: "admin@example.com",
|
|
||||||
displayName: "rootadmin",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
cy.loginViaApi({
|
|
||||||
email: "admin@example.com",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit("/users/rootadmin");
|
|
||||||
cy.contains("button", "Promote to admin").should("not.exist");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("renders a not-found panel for unknown display names", function () {
|
|
||||||
cy.visit("/users/nobody");
|
|
||||||
cy.contains("h1", "User not found").should("be.visible");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
describe("signup page", function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
cy.resetDb();
|
|
||||||
cy.clearMail();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("creates an unconfirmed user and redirects to check-email", function () {
|
|
||||||
cy.visit("/signup");
|
|
||||||
cy.get('input[type="email"]').type("alice@example.com");
|
|
||||||
cy.get('input[autocomplete="username"]').type("alice");
|
|
||||||
cy.contains("button", "Continue").click();
|
|
||||||
|
|
||||||
cy.location("pathname").should("eq", "/check-email");
|
|
||||||
cy.contains("h1", "Check your email").should("be.visible");
|
|
||||||
|
|
||||||
cy.getMail().then(function (inbox) {
|
|
||||||
expect(inbox.messages).to.have.length(1);
|
|
||||||
expect(inbox.messages[0].To[0].Address).to.equal(
|
|
||||||
"alice@example.com",
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("surfaces a 409 when the email is already registered", function () {
|
|
||||||
cy.seedConfirmedUser({
|
|
||||||
email: "alice@example.com",
|
|
||||||
displayName: "alice",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
cy.clearMail();
|
|
||||||
|
|
||||||
cy.visit("/signup");
|
|
||||||
cy.get('input[type="email"]').type("alice@example.com");
|
|
||||||
cy.get('input[autocomplete="username"]').type("alice2");
|
|
||||||
cy.contains("button", "Continue").click();
|
|
||||||
|
|
||||||
cy.location("pathname").should("eq", "/signup");
|
|
||||||
cy.contains(".error", "email already registered").should("be.visible");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("surfaces a 409 when the display name is taken", function () {
|
|
||||||
cy.seedConfirmedUser({
|
|
||||||
email: "alice@example.com",
|
|
||||||
displayName: "alice",
|
|
||||||
password: "longenoughpassword",
|
|
||||||
});
|
|
||||||
cy.clearMail();
|
|
||||||
|
|
||||||
cy.visit("/signup");
|
|
||||||
cy.get('input[type="email"]').type("other@example.com");
|
|
||||||
cy.get('input[autocomplete="username"]').type("alice");
|
|
||||||
cy.contains("button", "Continue").click();
|
|
||||||
|
|
||||||
cy.location("pathname").should("eq", "/signup");
|
|
||||||
cy.contains(".error", "displayName already taken").should("be.visible");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("blocks invalid display name characters client-side", function () {
|
|
||||||
cy.visit("/signup");
|
|
||||||
cy.get('input[type="email"]').type("alice@example.com");
|
|
||||||
cy.get('input[autocomplete="username"]').type("Has Spaces");
|
|
||||||
cy.contains("button", "Continue").click();
|
|
||||||
|
|
||||||
cy.location("pathname").should("eq", "/signup");
|
|
||||||
cy.get('input[autocomplete="username"]:invalid').should("exist");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue