From ed4a63eee760dad57b7c9937712dbc469e05f117 Mon Sep 17 00:00:00 2001 From: thiloho <123883702+thiloho@users.noreply.github.com> Date: Tue, 3 Sep 2024 16:06:07 +0200 Subject: [PATCH] Show message for image pasting and intialize permission test --- web-app/src/lib/utils.ts | 25 +- .../website/[websiteId]/+page.server.ts | 2 +- .../articles/[articleId]/+page.server.ts | 2 +- web-app/tests/collaborator.spec.ts | 291 ++++++++++++++++++ web-app/tests/website.spec.ts | 23 ++ 5 files changed, 333 insertions(+), 10 deletions(-) create mode 100644 web-app/tests/collaborator.spec.ts diff --git a/web-app/src/lib/utils.ts b/web-app/src/lib/utils.ts index cf7873c..09b7668 100644 --- a/web-app/src/lib/utils.ts +++ b/web-app/src/lib/utils.ts @@ -4,6 +4,7 @@ import { markedHighlight } from "marked-highlight"; import hljs from "highlight.js"; import GithubSlugger from "github-slugger"; import DOMPurify from "isomorphic-dompurify"; +import { applyAction, deserialize } from "$app/forms"; export const sortOptions = [ { value: "creation-time", text: "Creation time" }, @@ -175,15 +176,23 @@ export const handleImagePaste = async (event: ClipboardEvent, API_BASE_PREFIX: s body: formData }); + const result = deserialize(await request.clone().text()); + applyAction(result); + const response = await request.json(); - const fileId = JSON.parse(response.data)[1]; - const fileUrl = `${API_BASE_PREFIX}/rpc/retrieve_file?id=${fileId}`; - const target = event.target as HTMLTextAreaElement; - const newContent = - target.value.slice(0, target.selectionStart) + - `![](${fileUrl})` + - target.value.slice(target.selectionStart); + if (JSON.parse(response.data)[1]) { + const fileId = JSON.parse(response.data)[3]; + const fileUrl = `${API_BASE_PREFIX}/rpc/retrieve_file?id=${fileId}`; - return newContent; + const target = event.target as HTMLTextAreaElement; + const newContent = + target.value.slice(0, target.selectionStart) + + `![](${fileUrl})` + + target.value.slice(target.selectionStart); + + return newContent; + } else { + return ""; + } }; diff --git a/web-app/src/routes/(authenticated)/website/[websiteId]/+page.server.ts b/web-app/src/routes/(authenticated)/website/[websiteId]/+page.server.ts index d0f4cf9..e7c5038 100644 --- a/web-app/src/routes/(authenticated)/website/[websiteId]/+page.server.ts +++ b/web-app/src/routes/(authenticated)/website/[websiteId]/+page.server.ts @@ -215,6 +215,6 @@ export const actions: Actions = { return { success: false, message: fileJSON.message }; } - return { fileId: fileJSON.file_id }; + return { success: true, message: "Successfully uploaded image", fileId: fileJSON.file_id }; } }; diff --git a/web-app/src/routes/(authenticated)/website/[websiteId]/articles/[articleId]/+page.server.ts b/web-app/src/routes/(authenticated)/website/[websiteId]/articles/[articleId]/+page.server.ts index 023ad18..662121a 100644 --- a/web-app/src/routes/(authenticated)/website/[websiteId]/articles/[articleId]/+page.server.ts +++ b/web-app/src/routes/(authenticated)/website/[websiteId]/articles/[articleId]/+page.server.ts @@ -106,6 +106,6 @@ export const actions: Actions = { return { success: false, message: fileJSON.message }; } - return { fileId: fileJSON.file_id }; + return { success: true, message: "Successfully uploaded image", fileId: fileJSON.file_id }; } }; diff --git a/web-app/tests/collaborator.spec.ts b/web-app/tests/collaborator.spec.ts new file mode 100644 index 0000000..4eaf1cd --- /dev/null +++ b/web-app/tests/collaborator.spec.ts @@ -0,0 +1,291 @@ +import { test, expect, type Page } from "@playwright/test"; +import { randomBytes } from "node:crypto"; + +const username = randomBytes(8).toString("hex"); +const collabUsername = randomBytes(8).toString("hex"); +const collabUsername2 = randomBytes(8).toString("hex"); +const collabUsername3 = randomBytes(8).toString("hex"); +const password = "T3stuser??!!"; + +const permissionLevels = [10, 20, 30]; + +test("Setup", async ({ page }) => { + await page.goto("/register"); + + await page.getByLabel("Username:").click(); + await page.getByLabel("Username:").fill(username); + await page.getByLabel("Password:").click(); + await page.getByLabel("Password:").fill(password); + await page.getByRole("button", { name: "Submit" }).click(); + + await page.getByLabel("Username:").click(); + await page.getByLabel("Username:").fill(collabUsername); + await page.getByLabel("Password:").click(); + await page.getByLabel("Password:").fill(password); + await page.getByRole("button", { name: "Submit" }).click(); + + await page.getByLabel("Username:").click(); + await page.getByLabel("Username:").fill(collabUsername2); + await page.getByLabel("Password:").click(); + await page.getByLabel("Password:").fill(password); + await page.getByRole("button", { name: "Submit" }).click(); + + await page.getByLabel("Username:").click(); + await page.getByLabel("Username:").fill(collabUsername3); + await page.getByLabel("Password:").click(); + await page.getByLabel("Password:").fill(password); + await page.getByRole("button", { name: "Submit" }).click(); + + await page.goto("/login"); + await page.getByLabel("Username:").fill(username); + await page.getByLabel("Password:").fill(password); + await page.getByRole("button", { name: "Submit" }).click(); + + await page.getByRole("button", { name: "Create website" }).click(); + await page.getByLabel("Title:").click(); + await page.getByLabel("Title:").fill("Blog"); + await page.getByRole("button", { name: "Submit" }).click(); + + await page.getByRole("button", { name: "Create website" }).click(); + await page.getByLabel("Type: BlogDocs").selectOption("Docs"); + await page.getByLabel("Title:").click(); + await page.getByLabel("Title:").fill("Documentation"); + await page.getByRole("button", { name: "Submit" }).click(); + + await page.getByRole("link", { name: "Blog" }).click(); + await page.getByRole("link", { name: "Articles" }).click(); + await page.getByRole("button", { name: "Create article" }).click(); + await page.getByLabel("Title:").click(); + await page.getByLabel("Title:").fill("Article"); + await page.getByRole("button", { name: "Submit" }).click(); + + await page.getByRole("link", { name: "Collaborators" }).click(); + await page.getByRole("button", { name: "Add collaborator" }).click(); + await page.getByLabel("Username:").click(); + await page.getByLabel("Username:").fill(collabUsername); + await page.getByRole("button", { name: "Submit" }).click(); + + await page.goto("/"); + await page.getByRole("link", { name: "Documentation" }).click(); + await page.getByRole("link", { name: "Categories" }).click(); + await page.getByRole("button", { name: "Create category" }).click(); + await page.getByLabel("Name:").click(); + await page.getByLabel("Name:").fill("Category"); + await page.getByLabel("Weight:").click(); + await page.getByLabel("Weight:").fill("1000"); + await page.getByRole("button", { name: "Submit" }).click(); + + await page.getByRole("link", { name: "Collaborators" }).click(); + await page.getByRole("button", { name: "Add collaborator" }).click(); + await page.getByLabel("Username:").click(); + await page.getByLabel("Username:").fill(collabUsername); + await page.getByRole("button", { name: "Submit" }).click(); +}); + +for (const permissionLevel of permissionLevels) { + test(`Set collaborator permission level to ${permissionLevel}`, async ({ page }) => { + await page.goto("/login"); + await page.getByLabel("Username:").fill(username); + await page.getByLabel("Password:").fill(password); + await page.getByRole("button", { name: "Submit" }).click(); + await page.getByRole("link", { name: "Blog" }).click(); + await page.getByRole("link", { name: "Collaborators" }).click(); + await page.getByRole("button", { name: "Update" }).click(); + await page.getByRole("combobox").selectOption(permissionLevel.toString()); + await page.getByRole("button", { name: "Update collaborator" }).click(); + }); + + test.describe.serial(`Permission level: ${permissionLevel}`, () => { + test.beforeEach(async ({ page }) => { + await page.goto("/login"); + await page.getByLabel("Username:").fill(collabUsername); + await page.getByLabel("Password:").fill(password); + await page.getByRole("button", { name: "Submit" }).click(); + }); + + test("Update website", async ({ page }) => { + await page.getByRole("button", { name: "Update" }).nth(1).click(); + await page.getByRole("button", { name: "Submit" }).click(); + + if (permissionLevel === 10) { + await expect(page.getByText("You do not have the required")).toBeVisible(); + } + }); + /* test("Delete website", async ({ page }) => { + await page.getByRole("button", { name: "Delete" }).click(); + await page.getByRole("button", { name: "Delete website" }).click(); + + if (permissionLevel === 10) { + await expect(page.getByText("You do not have the required")).toBeVisible(); + } + }); */ + test("Update Global", async ({ page }) => { + await page.getByRole("link", { name: "Blog" }).click(); + await page.locator("#global").getByRole("button", { name: "Submit" }).click(); + + if (permissionLevel === 10) { + await expect(page.getByText("You do not have the required")).toBeVisible(); + } + }); + test("Update Header", async ({ page }) => { + await page.getByRole("link", { name: "Blog" }).click(); + await page.locator("#header").getByRole("button", { name: "Submit" }).click(); + + if (permissionLevel === 10) { + await expect(page.getByText("You do not have the required")).toBeVisible(); + } + }); + test("Update Home", async ({ page }) => { + await page.getByRole("link", { name: "Blog" }).click(); + await page.locator("#home").getByRole("button", { name: "Submit" }).click(); + + if (permissionLevel === 10) { + await expect(page.getByText("You do not have the required")).toBeVisible(); + } + }); + test("Update Footer", async ({ page }) => { + await page.getByRole("link", { name: "Blog" }).click(); + await page.locator("#footer").getByRole("button", { name: "Submit" }).click(); + + if (permissionLevel === 10) { + await expect(page.getByText("You do not have the required")).toBeVisible(); + } + }); + test("Create article", async ({ page }) => { + await page.getByRole("link", { name: "Blog" }).click(); + await page.getByRole("link", { name: "Articles" }).click(); + await page.getByRole("button", { name: "Create article" }).click(); + await page.getByLabel("Title:").click(); + await page.getByLabel("Title:").fill("Article"); + await page.getByRole("button", { name: "Submit" }).click(); + + if (permissionLevel === 10) { + await expect(page.getByText("You do not have the required")).toBeVisible(); + } + }); + test("Update article", async ({ page }) => { + await page.getByRole("link", { name: "Blog" }).click(); + await page.getByRole("link", { name: "Articles" }).click(); + await page + .getByRole("link", { name: "Edit" }) + .nth(permissionLevels.indexOf(permissionLevel)) + .click(); + await page.getByLabel("Description:").click(); + await page.getByLabel("Description:").fill("Description"); + await page.getByLabel("Author:").click(); + await page.getByLabel("Author:").fill("Author"); + await page.getByLabel("Main content:").click(); + await page.getByLabel("Main content:").fill("## Main content"); + await page.getByRole("button", { name: "Submit" }).click(); + + if (permissionLevel === 10) { + await expect(page.getByText("You do not have the required")).toBeVisible(); + } + }); + test("Delete article", async ({ page }) => { + await page.getByRole("link", { name: "Blog" }).click(); + await page.getByRole("link", { name: "Articles" }).click(); + await page + .getByRole("button", { name: "Delete" }) + .nth(permissionLevels.indexOf(permissionLevel)) + .click(); + await page.getByRole("button", { name: "Delete article" }).click(); + + if (permissionLevel === 10) { + await expect(page.getByText("You do not have the required")).toBeVisible(); + } + }); + test("Add collaborator", async ({ page }) => { + await page.getByRole("link", { name: "Blog" }).click(); + await page.getByRole("link", { name: "Collaborators" }).click(); + await page.getByRole("button", { name: "Add collaborator" }).click(); + await page.getByLabel("Username:").click(); + await page + .getByLabel("Username:") + .fill(permissionLevel === 10 || permissionLevel === 20 ? collabUsername2 : collabUsername3); + await page.getByRole("button", { name: "Submit" }).click(); + + if (permissionLevel === 10) { + await expect(page.getByText("You do not have the required")).toBeVisible(); + } + }); + test("Update collaborator", async ({ page }) => { + await page.getByRole("link", { name: "Blog" }).click(); + await page.getByRole("link", { name: "Collaborators" }).click(); + await page + .getByRole("button", { name: "Update" }) + .nth(permissionLevels.indexOf(permissionLevel)) + .click(); + await page.getByRole("combobox").selectOption("20"); + await page.getByRole("button", { name: "Update collaborator" }).click(); + + if (permissionLevel === 10) { + await expect(page.getByText("You do not have the required")).toBeVisible(); + } + }); + test("Remove collaborator", async ({ page }) => { + await page.getByRole("link", { name: "Blog" }).click(); + await page.getByRole("link", { name: "Collaborators" }).click(); + await page + .getByRole("button", { name: "Remove" }) + .nth(permissionLevels.indexOf(permissionLevel)) + .click(); + await page.getByRole("button", { name: "Remove collaborator" }).click(); + + if (permissionLevel === 10) { + await expect(page.getByText("You do not have the required")).toBeVisible(); + } + }); + test("Create category", async ({ page }) => { + await page.getByRole("link", { name: "Documentation" }).click(); + await page.getByRole("link", { name: "Categories" }).click(); + await page.getByRole("button", { name: "Create category" }).click(); + await page.getByLabel("Name:").click(); + await page.getByLabel("Name:").fill("Test"); + await page.getByRole("spinbutton", { name: "Weight:" }).click(); + await page.getByRole("spinbutton", { name: "Weight:" }).fill("900"); + await page.getByRole("button", { name: "Submit" }).click(); + + if (permissionLevel === 10) { + await expect(page.getByText("You do not have the required")).toBeVisible(); + } + }); + test("Update category", async ({ page }) => { + await page.getByRole("link", { name: "Documentation" }).click(); + await page.getByRole("link", { name: "Categories" }).click(); + await page + .getByRole("button", { name: "Update" }) + .nth(permissionLevels.indexOf(permissionLevel)) + .click(); + await page.getByRole("spinbutton", { name: "Weight:" }).click(); + await page.getByRole("spinbutton", { name: "Weight:" }).fill("500"); + await page.getByRole("button", { name: "Update category" }).click(); + + if (permissionLevel === 10) { + await expect(page.getByText("You do not have the required")).toBeVisible(); + } + }); + test("Delete category", async ({ page }) => { + await page.getByRole("link", { name: "Documentation" }).click(); + await page.getByRole("link", { name: "Categories" }).click(); + await page + .getByRole("button", { name: "Delete" }) + .nth(permissionLevels.indexOf(permissionLevel)) + .click(); + await page.getByRole("button", { name: "Delete category" }).click(); + + if (permissionLevel === 10) { + await expect(page.getByText("You do not have the required")).toBeVisible(); + } + }); + test("Publish website", async ({ page }) => { + await page.getByRole("link", { name: "Blog" }).click(); + await page.getByRole("link", { name: "Publish" }).click(); + await page.getByRole("button", { name: "Publish" }).click(); + + if (permissionLevel === 10) { + await expect(page.getByText("You do not have the required")).toBeVisible(); + } + }); + }); +} diff --git a/web-app/tests/website.spec.ts b/web-app/tests/website.spec.ts index 2c3916a..cee7c28 100644 --- a/web-app/tests/website.spec.ts +++ b/web-app/tests/website.spec.ts @@ -2,6 +2,7 @@ import { test as base, expect, type Page } from "@playwright/test"; import { fileURLToPath } from "node:url"; import { dirname, join } from "node:path"; import { randomBytes } from "node:crypto"; +import { platform } from "node:os"; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); @@ -162,6 +163,28 @@ test.describe("Blog", () => { await expect(page.getByText("Successfully updated article")).toBeVisible(); }); + test("Paste image", async ({ authenticatedPage: page, context }) => { + await page.getByRole("link", { name: "Blog" }).click(); + await page.getByRole("link", { name: "Articles" }).click(); + await page.getByRole("link", { name: "Edit" }).click(); + await page.getByLabel("Main content:").click(); + + await context.grantPermissions(["clipboard-read", "clipboard-write"]); + const isMac = platform() === "darwin"; + const modifier = isMac ? "Meta" : "Control"; + + const clipPage = await context.newPage(); + await clipPage.goto("https://picsum.photos/400/400.jpg"); + await clipPage.keyboard.press(`${modifier}+KeyC`); + + await page.bringToFront(); + await page.keyboard.press("Enter"); + await page.keyboard.press("Enter"); + await page.keyboard.press(`${modifier}+KeyV`); + + await expect(page.getByText("Successfully uploaded image")).toBeVisible(); + }); + test("Delete article", async ({ authenticatedPage: page }) => { await page.getByRole("link", { name: "Blog" }).click(); await page.getByRole("link", { name: "Articles" }).click();