From cafeb14f1ccfc6b3c2accfe71a0ec5ed51ccc5fc Mon Sep 17 00:00:00 2001
From: Nutomic <me@nutomic.com>
Date: Wed, 22 Nov 2023 16:15:06 +0100
Subject: [PATCH] Add API tests for purge user and purge post (#4183)

* Add API tests for purge user and purge post

* prettier

* fix test

* ci

---------

Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
---
 api_tests/prepare-drone-federation-test.sh |  1 +
 api_tests/src/comment.spec.ts              |  5 +-
 api_tests/src/community.spec.ts            |  5 +-
 api_tests/src/follow.spec.ts               |  9 +--
 api_tests/src/image.spec.ts                | 90 +++++++++++++++++++++-
 api_tests/src/post.spec.ts                 |  6 +-
 api_tests/src/shared.ts                    | 16 ++--
 api_tests/src/user.spec.ts                 | 18 +----
 docker/federation/lemmy_alpha.hjson        |  3 +
 docker/federation/lemmy_beta.hjson         |  3 +
 10 files changed, 112 insertions(+), 44 deletions(-)

diff --git a/api_tests/prepare-drone-federation-test.sh b/api_tests/prepare-drone-federation-test.sh
index 0b623f6d2..0f7591b31 100755
--- a/api_tests/prepare-drone-federation-test.sh
+++ b/api_tests/prepare-drone-federation-test.sh
@@ -16,6 +16,7 @@ fi
 ./api_tests/pict-rs \
   run -a 0.0.0.0:8080 \
   --danger-dummy-mode \
+  --api-key "my-pictrs-key" \
   filesystem -p /tmp/pictrs/files \
   sled -p /tmp/pictrs/sled-repo 2>&1 &
 
diff --git a/api_tests/src/comment.spec.ts b/api_tests/src/comment.spec.ts
index 7ab8db335..915c87a57 100644
--- a/api_tests/src/comment.spec.ts
+++ b/api_tests/src/comment.spec.ts
@@ -230,10 +230,7 @@ test.skip("Remove a comment from admin and community on the same instance", asyn
 });
 
 test("Remove a comment from admin and community on different instance", async () => {
-  let alpha_user = await registerUser(alpha);
-  let newAlphaApi = new LemmyHttp(alphaUrl, {
-    headers: { Authorization: `Bearer ${alpha_user.jwt ?? ""}` },
-  });
+  let newAlphaApi = await registerUser(alpha, alphaUrl);
 
   // New alpha user creates a community, post, and comment.
   let newCommunity = await createCommunity(newAlphaApi);
diff --git a/api_tests/src/community.spec.ts b/api_tests/src/community.spec.ts
index a16802e08..3b6697a68 100644
--- a/api_tests/src/community.spec.ts
+++ b/api_tests/src/community.spec.ts
@@ -251,10 +251,7 @@ test("Admin actions in remote community are not federated to origin", async () =
 
 test("moderator view", async () => {
   // register a new user with their own community on alpha and post to it
-  let registerUserRes = await registerUser(alpha);
-  let otherUser = new LemmyHttp(alphaUrl, {
-    headers: { Authorization: `Bearer ${registerUserRes.jwt ?? ""}` },
-  });
+  let otherUser = await registerUser(alpha, alphaUrl);
 
   let otherCommunity = (await createCommunity(otherUser)).community_view;
   expect(otherCommunity.community.name).toBeDefined();
diff --git a/api_tests/src/follow.spec.ts b/api_tests/src/follow.spec.ts
index 60ec98991..314b45eaf 100644
--- a/api_tests/src/follow.spec.ts
+++ b/api_tests/src/follow.spec.ts
@@ -1,6 +1,5 @@
 jest.setTimeout(120000);
 
-import { LemmyHttp } from "lemmy-js-client";
 import {
   alpha,
   setupLogins,
@@ -10,8 +9,8 @@ import {
   getSite,
   waitUntil,
   beta,
-  registerUser,
   betaUrl,
+  registerUser,
 } from "./shared";
 
 beforeAll(setupLogins);
@@ -21,11 +20,7 @@ afterAll(() => {
 });
 
 test("Follow local community", async () => {
-  let userRes = await registerUser(beta);
-  expect(userRes.jwt).toBeDefined();
-  let user = new LemmyHttp(betaUrl, {
-    headers: { Authorization: `Bearer ${userRes.jwt ?? ""}` },
-  });
+  let user = await registerUser(beta, betaUrl);
 
   let community = (await resolveBetaCommunity(user)).community!;
   expect(community.counts.subscribers).toBe(1);
diff --git a/api_tests/src/image.spec.ts b/api_tests/src/image.spec.ts
index 73d020872..e6407ec1a 100644
--- a/api_tests/src/image.spec.ts
+++ b/api_tests/src/image.spec.ts
@@ -1,7 +1,23 @@
 jest.setTimeout(120000);
 
-import { UploadImage, DeleteImage } from "lemmy-js-client";
-import { alpha, setupLogins, unfollowRemotes } from "./shared";
+import {
+  UploadImage,
+  DeleteImage,
+  PurgePerson,
+  PurgePost,
+} from "lemmy-js-client";
+import {
+  alpha,
+  alphaUrl,
+  beta,
+  betaUrl,
+  createPost,
+  getSite,
+  registerUser,
+  resolveBetaCommunity,
+  setupLogins,
+  unfollowRemotes,
+} from "./shared";
 import fs = require("fs");
 const downloadFileSync = require("download-file-sync");
 
@@ -18,7 +34,6 @@ test("Upload image and delete it", async () => {
     image: upload_image,
   };
   const upload = await alpha.uploadImage(upload_form);
-  console.log(upload);
   expect(upload.files![0].file).toBeDefined();
   expect(upload.files![0].delete_token).toBeDefined();
   expect(upload.url).toBeDefined();
@@ -41,4 +56,71 @@ test("Upload image and delete it", async () => {
   expect(content2).toBe("");
 });
 
-// TODO: add tests for image purging
+test("Purge user, uploaded image removed", async () => {
+  let user = await registerUser(alpha, alphaUrl);
+
+  // upload test image
+  const upload_image = fs.readFileSync("test.png");
+  const upload_form: UploadImage = {
+    image: upload_image,
+  };
+  const upload = await user.uploadImage(upload_form);
+  expect(upload.files![0].file).toBeDefined();
+  expect(upload.files![0].delete_token).toBeDefined();
+  expect(upload.url).toBeDefined();
+  expect(upload.delete_url).toBeDefined();
+
+  // ensure that image download is working. theres probably a better way to do this
+  const content = downloadFileSync(upload.url);
+  expect(content.length).toBeGreaterThan(0);
+
+  // purge user
+  let site = await getSite(user);
+  const purge_form: PurgePerson = {
+    person_id: site.my_user!.local_user_view.person.id,
+  };
+  const delete_ = await alpha.purgePerson(purge_form);
+  expect(delete_.success).toBe(true);
+
+  // ensure that image is deleted
+  const content2 = downloadFileSync(upload.url);
+  expect(content2).toBe("");
+});
+
+test("Purge post, linked image removed", async () => {
+  let user = await registerUser(beta, betaUrl);
+
+  // upload test image
+  const upload_image = fs.readFileSync("test.png");
+  const upload_form: UploadImage = {
+    image: upload_image,
+  };
+  const upload = await user.uploadImage(upload_form);
+  expect(upload.files![0].file).toBeDefined();
+  expect(upload.files![0].delete_token).toBeDefined();
+  expect(upload.url).toBeDefined();
+  expect(upload.delete_url).toBeDefined();
+
+  // ensure that image download is working. theres probably a better way to do this
+  const content = downloadFileSync(upload.url);
+  expect(content.length).toBeGreaterThan(0);
+
+  let community = await resolveBetaCommunity(user);
+  let post = await createPost(
+    user,
+    community.community!.community.id,
+    upload.url,
+  );
+  expect(post.post_view.post.url).toBe(upload.url);
+
+  // purge post
+  const purge_form: PurgePost = {
+    post_id: post.post_view.post.id,
+  };
+  const delete_ = await beta.purgePost(purge_form);
+  expect(delete_.success).toBe(true);
+
+  // ensure that image is deleted
+  const content2 = downloadFileSync(upload.url);
+  expect(content2).toBe("");
+});
diff --git a/api_tests/src/post.spec.ts b/api_tests/src/post.spec.ts
index d79a536cb..f92fedf6c 100644
--- a/api_tests/src/post.spec.ts
+++ b/api_tests/src/post.spec.ts
@@ -390,11 +390,7 @@ test("Enforce site ban for federated user", async () => {
     throw "Missing beta community";
   }
   // create a test user
-  let alphaUserJwt = await registerUser(alpha);
-  expect(alphaUserJwt).toBeDefined();
-  let alpha_user = new LemmyHttp(alphaUrl, {
-    headers: { Authorization: `Bearer ${alphaUserJwt.jwt ?? ""}` },
-  });
+  let alpha_user = await registerUser(alpha, alphaUrl);
   let alphaUserPerson = (await getSite(alpha_user)).my_user?.local_user_view
     .person;
   let alphaUserActorId = alphaUserPerson?.actor_id;
diff --git a/api_tests/src/shared.ts b/api_tests/src/shared.ts
index abd3093e3..ace3a6fac 100644
--- a/api_tests/src/shared.ts
+++ b/api_tests/src/shared.ts
@@ -196,12 +196,11 @@ export async function setupLogins() {
 export async function createPost(
   api: LemmyHttp,
   community_id: number,
+  // use example.com for consistent title and embed description
+  url: string = "https://example.com/",
 ): Promise<PostResponse> {
   let name = randomString(5);
   let body = randomString(10);
-  // switch from google.com to example.com for consistent title (embed_title and embed_description)
-  // google switches description when a google doodle appears
-  let url = "https://example.com/";
   let form: CreatePost = {
     name,
     url,
@@ -615,15 +614,22 @@ export async function deletePrivateMessage(
 
 export async function registerUser(
   api: LemmyHttp,
+  url: string,
   username: string = randomString(5),
-): Promise<LoginResponse> {
+): Promise<LemmyHttp> {
   let form: Register = {
     username,
     password,
     password_verify: password,
     show_nsfw: true,
   };
-  return api.register(form);
+  let login_response = await api.register(form);
+
+  expect(login_response.jwt).toBeDefined();
+  let lemmy_http = new LemmyHttp(url, {
+    headers: { Authorization: `Bearer ${login_response.jwt ?? ""}` },
+  });
+  return lemmy_http;
 }
 
 export async function loginUser(
diff --git a/api_tests/src/user.spec.ts b/api_tests/src/user.spec.ts
index d71827f89..c3c7d0bec 100644
--- a/api_tests/src/user.spec.ts
+++ b/api_tests/src/user.spec.ts
@@ -37,11 +37,7 @@ function assertUserFederation(userOne?: PersonView, userTwo?: PersonView) {
 }
 
 test("Create user", async () => {
-  let userRes = await registerUser(alpha);
-  expect(userRes.jwt).toBeDefined();
-  let user = new LemmyHttp(alphaUrl, {
-    headers: { Authorization: `Bearer ${userRes.jwt ?? ""}` },
-  });
+  let user = await registerUser(alpha, alphaUrl);
 
   let site = await getSite(user);
   expect(site.my_user).toBeDefined();
@@ -68,11 +64,7 @@ test("Set some user settings, check that they are federated", async () => {
 });
 
 test("Delete user", async () => {
-  let userRes = await registerUser(alpha);
-  expect(userRes.jwt).toBeDefined();
-  let user = new LemmyHttp(alphaUrl, {
-    headers: { Authorization: `Bearer ${userRes.jwt ?? ""}` },
-  });
+  let user = await registerUser(alpha, alphaUrl);
 
   // make a local post and comment
   let alphaCommunity = (await resolveCommunity(user, "!main@lemmy-alpha:8541"))
@@ -133,11 +125,7 @@ test("Requests with invalid auth should be treated as unauthenticated", async ()
 });
 
 test("Create user with Arabic name", async () => {
-  let userRes = await registerUser(alpha, "تجريب");
-  expect(userRes.jwt).toBeDefined();
-  let user = new LemmyHttp(alphaUrl, {
-    headers: { Authorization: `Bearer ${userRes.jwt ?? ""}` },
-  });
+  let user = await registerUser(alpha, alphaUrl, "تجريب");
 
   let site = await getSite(user);
   expect(site.my_user).toBeDefined();
diff --git a/docker/federation/lemmy_alpha.hjson b/docker/federation/lemmy_alpha.hjson
index a0329b30f..84ef1a16e 100644
--- a/docker/federation/lemmy_alpha.hjson
+++ b/docker/federation/lemmy_alpha.hjson
@@ -10,4 +10,7 @@
   database: {
     host: postgres_alpha
   }
+  pictrs: {
+    api_key: "my-pictrs-key"
+  }
 }
diff --git a/docker/federation/lemmy_beta.hjson b/docker/federation/lemmy_beta.hjson
index 228fe502d..1b4508a43 100644
--- a/docker/federation/lemmy_beta.hjson
+++ b/docker/federation/lemmy_beta.hjson
@@ -10,4 +10,7 @@
   database: {
     host: postgres_beta
   }
+  pictrs: {
+    api_key: "my-pictrs-key"
+  }
 }
-- 
GitLab