Skip to content
This repository was archived by the owner on Mar 12, 2025. It is now read-only.

Commit df27f82

Browse files
Sembaukesidemt
andauthored
fix: show drafts for contributors (#337)
Co-authored-by: yoko <[email protected]>
1 parent 6ba330d commit df27f82

File tree

6 files changed

+156
-5
lines changed

6 files changed

+156
-5
lines changed

Diff for: apps/backend/src/seed/index.js

+20-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,26 @@ async function createSeedPosts(strapi) {
155155
title: "Internal post",
156156
author: { connect: [userIds[1]] },
157157
tags: { connect: [internalTagId] },
158-
body: "I'm an internal post and meant to be hidden",
158+
body: "A post with internal tag.",
159+
publishedAt: new Date(),
160+
},
161+
});
162+
163+
// Posts by contributors
164+
await strapi.entityService.create("api::post.post", {
165+
data: {
166+
title: "Contributor's draft post",
167+
author: { connect: [userIds[0]] }, // Contributor
168+
tags: { connect: tagIds.slice(1, 3) },
169+
body: "A post by contributor in draft state.",
170+
},
171+
});
172+
await strapi.entityService.create("api::post.post", {
173+
data: {
174+
title: "Contributor's published post",
175+
author: { connect: [userIds[0]] }, // Contributor
176+
tags: { connect: tagIds.slice(1, 3) },
177+
body: "A post by contributor in published state.",
159178
publishedAt: new Date(),
160179
},
161180
});

Diff for: apps/backend/tests/post/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ describe("post", () => {
5757
).toBe(true);
5858
});
5959
});
60+
6061
describe("GET /posts/:id", () => {
6162
it("should prevent contributors viewing other user's post", async () => {
6263
const post = await getPost("editors-draft-post");

Diff for: apps/frontend/src/pages/posts/index.js

+12-3
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,14 @@ export async function getServerSideProps(context) {
129129
},
130130
})
131131
: getUserPosts(session.user.jwt, {
132+
publicationState: "preview",
132133
fields: ["id", "title", "slug", "publishedAt", "updatedAt"],
133134
populate: ["author", "tags"],
134135
filters: {
135136
author: session.user.id,
137+
publishedAt: {
138+
$notNull: false,
139+
},
136140
...queryHandler(context.query),
137141
},
138142
sort: sortHandler(context.query.sortBy),
@@ -524,9 +528,11 @@ export default function IndexPage({
524528
new Date(),
525529
);
526530
const status = post.attributes.publishedAt ? (
527-
<Badge>Published</Badge>
531+
<Badge data-testid="published-badge">Published</Badge>
528532
) : (
529-
<Badge colorScheme="pink">Draft</Badge>
533+
<Badge data-testid="draft-badge" colorScheme="pink">
534+
Draft
535+
</Badge>
530536
);
531537
return (
532538
<Tr
@@ -601,7 +607,10 @@ export default function IndexPage({
601607
/>
602608
</Box>
603609
<Menu ml="auto">
604-
<FilterButton text={resultsPerPage} />
610+
<FilterButton
611+
text={resultsPerPage}
612+
data-testid="results-per-page"
613+
/>
605614
<MenuList>
606615
<MenuOptionGroup
607616
value={resultsPerPage}

Diff for: e2e/contributor/posts.spec.ts

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { test, expect } from "@playwright/test";
2+
3+
test.describe("contributor", () => {
4+
test("can only view draft posts", async ({ page }) => {
5+
await page.goto("/posts");
6+
7+
// the filter "All posts" should be hidden
8+
await expect(page.getByRole("button", { name: "All posts" })).toBeHidden();
9+
10+
// check that only draft posts are in the list
11+
const publishedCount = await page
12+
.locator("data-testid=published-badge")
13+
.count();
14+
expect(publishedCount).toBe(0);
15+
const draftCount = await page.locator("data-testid=draft-badge").count();
16+
expect(draftCount).toBeGreaterThanOrEqual(1);
17+
});
18+
19+
test("can only view their own posts", async ({ page }) => {
20+
await page.goto("/posts");
21+
22+
// check that other user's posts are not in the list
23+
const ownPostsCount = await page.getByText("By contributor-user").count();
24+
const otherPostsCouint = await page.getByText("By editor-user").count();
25+
expect(ownPostsCount).toBeGreaterThanOrEqual(1);
26+
expect(otherPostsCouint).toBe(0);
27+
});
28+
});

Diff for: e2e/posts.spec.ts

+62-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,68 @@ test("has a button to create a new post", async ({ page }) => {
44
await page.goto("/posts");
55

66
await page.getByRole("button", { name: "New post" }).click();
7-
7+
88
await expect(page).toHaveURL(/.*\/posts\/\d+/);
99
await expect(page.getByRole("link", { name: "Posts" })).toBeVisible();
1010
});
11+
12+
test("an editor can view published and drafted posts in the list of posts", async ({
13+
page,
14+
}) => {
15+
await page.goto("/posts");
16+
17+
// The filter on posts page should be "All posts" by default
18+
await expect(page.getByRole("button", { name: "All posts" })).toBeVisible();
19+
20+
// Show 50 posts to see both draft and published posts
21+
await page.getByTestId("results-per-page").dispatchEvent("click");
22+
await page.click("text=50");
23+
// Wait for the table to load
24+
await page.waitForSelector("table tbody tr:nth-child(6)");
25+
26+
// Check that both draft and published posts are in the list
27+
const publishedCount = await page
28+
.locator("data-testid=published-badge")
29+
.count();
30+
expect(publishedCount).toBeGreaterThanOrEqual(1);
31+
const draftCount = await page.locator("data-testid=draft-badge").count();
32+
expect(draftCount).toBeGreaterThanOrEqual(1);
33+
});
34+
35+
test("an editor can filter by draft posts", async ({ page }) => {
36+
await page.goto("/posts");
37+
38+
// Show 50 posts to see both draft and published posts
39+
await page.getByTestId("results-per-page").dispatchEvent("click");
40+
await page.click("text=50");
41+
42+
// Select the "Drafts posts" filter
43+
await page.getByRole("button", { name: "All posts" }).dispatchEvent("click");
44+
await page.click("text=Drafts posts");
45+
46+
// Wait for published posts to disappear
47+
await expect(page.locator("data-testid=published-badge")).toHaveCount(0);
48+
// Check that draft posts are in the list
49+
const draftCount = await page.locator("data-testid=draft-badge").count();
50+
expect(draftCount).toBeGreaterThanOrEqual(1);
51+
});
52+
53+
test("an editor can filter by published posts", async ({ page }) => {
54+
await page.goto("/posts");
55+
56+
// Show 50 posts to see both draft and published posts
57+
await page.getByTestId("results-per-page").dispatchEvent("click");
58+
await page.click("text=50");
59+
60+
// Select the "Published posts" filter
61+
await page.getByRole("button", { name: "All posts" }).dispatchEvent("click");
62+
await page.click("text=Published posts");
63+
64+
// Wait for draft posts to disappear
65+
await expect(page.locator("data-testid=draft-badge")).toHaveCount(0);
66+
// Check that published posts are in the list
67+
const publishedCount = await page
68+
.locator("data-testid=published-badge")
69+
.count();
70+
expect(publishedCount).toBeGreaterThanOrEqual(1);
71+
});

Diff for: playwright.config.ts

+33
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export default defineConfig({
3535
{ name: "setup", testMatch: /.*\.setup\.ts/ },
3636
{
3737
name: "chromium",
38+
testIgnore: "e2e/contributor/**",
3839
use: {
3940
...devices["Desktop Chrome"],
4041
storageState: "playwright/.auth/editor.json",
@@ -44,6 +45,7 @@ export default defineConfig({
4445

4546
{
4647
name: "firefox",
48+
testIgnore: "e2e/contributor/**",
4749
use: {
4850
...devices["Desktop Firefox"],
4951
storageState: "playwright/.auth/editor.json",
@@ -53,13 +55,44 @@ export default defineConfig({
5355

5456
{
5557
name: "webkit",
58+
testIgnore: "e2e/contributor/**",
5659
use: {
5760
...devices["Desktop Safari"],
5861
storageState: "playwright/.auth/editor.json",
5962
},
6063
dependencies: ["setup"],
6164
},
6265

66+
{
67+
name: "chromium-contributor",
68+
testDir: "e2e/contributor",
69+
use: {
70+
...devices["Desktop Chrome"],
71+
storageState: "playwright/.auth/contributor.json",
72+
},
73+
dependencies: ["setup"],
74+
},
75+
76+
{
77+
name: "firefox-contributor",
78+
testDir: "e2e/contributor",
79+
use: {
80+
...devices["Desktop Firefox"],
81+
storageState: "playwright/.auth/contributor.json",
82+
},
83+
dependencies: ["setup"],
84+
},
85+
86+
{
87+
name: "webkit-contributor",
88+
testDir: "e2e/contributor",
89+
use: {
90+
...devices["Desktop Safari"],
91+
storageState: "playwright/.auth/contributor.json",
92+
},
93+
dependencies: ["setup"],
94+
},
95+
6396
/* Test against mobile viewports. */
6497
// {
6598
// name: 'Mobile Chrome',

0 commit comments

Comments
 (0)