share_test.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import { assertEquals } from "@std/assert";
  2. import { find, insert } from "utils/db.ts";
  3. import { getCryptoString } from "utils/server.ts";
  4. let testCounter = 0;
  5. function getTestDbPath() {
  6. testCounter++;
  7. return `data/test_api_share_${testCounter}_${Date.now()}.db`;
  8. }
  9. function cleanup(dbPath: string) {
  10. try {
  11. Deno.removeSync(dbPath);
  12. } catch {
  13. // File may not exist
  14. }
  15. }
  16. function makeCtx(method: string, body?: object, cookie?: string) {
  17. const headers: Record<string, string> = { "Content-Type": "application/json" };
  18. if (cookie) headers["Cookie"] = cookie;
  19. const req = new Request("http://localhost", {
  20. method,
  21. headers,
  22. body: method === "GET" ? undefined : JSON.stringify(body || {}),
  23. });
  24. return { req };
  25. }
  26. async function seedUserAndToken(email: string, password: string) {
  27. const hashedPw = await getCryptoString(password, "MD5");
  28. const user = insert("User", {
  29. name: email.split("@")[0],
  30. email,
  31. password: hashedPw,
  32. });
  33. const userId = user[0]["id"] as string | number;
  34. const token = await getCryptoString("share-token-" + userId + Date.now(), "MD5");
  35. insert("Token", { token, user_id: userId });
  36. return { userId, token };
  37. }
  38. Deno.test("API share - share a post", async () => {
  39. const dbPath = getTestDbPath();
  40. Deno.env.set("POSTDOWN_DB_PATH", dbPath);
  41. try {
  42. const { userId, token } = await seedUserAndToken("shareshare@example.com", "password");
  43. insert("Post", {
  44. id: "share-post-1",
  45. title: "Share Me",
  46. content: "Content",
  47. user_id: userId,
  48. shared: 0,
  49. });
  50. const { handler } = await import("../../routes/api/share.tsx");
  51. const ctx = makeCtx("POST", {
  52. id: "share-post-1",
  53. shared: true,
  54. }, `pd-user-token=${token}`);
  55. const res = await handler.POST!(ctx as any);
  56. const body = await res.json();
  57. assertEquals(body.success, true);
  58. const post = find("Post", { id: "share-post-1" }, ["shared"]);
  59. assertEquals(post[0]["shared"], 1);
  60. } finally {
  61. Deno.env.delete("POSTDOWN_DB_PATH");
  62. cleanup(dbPath);
  63. }
  64. });
  65. Deno.test("API share - unshare a post", async () => {
  66. const dbPath = getTestDbPath();
  67. Deno.env.set("POSTDOWN_DB_PATH", dbPath);
  68. try {
  69. const { userId, token } = await seedUserAndToken("shareunshare@example.com", "password");
  70. insert("Post", {
  71. id: "unshare-post-1",
  72. title: "Unshare Me",
  73. content: "Content",
  74. user_id: userId,
  75. shared: 1,
  76. });
  77. const { handler } = await import("../../routes/api/share.tsx");
  78. const ctx = makeCtx("POST", {
  79. id: "unshare-post-1",
  80. shared: false,
  81. }, `pd-user-token=${token}`);
  82. const res = await handler.POST!(ctx as any);
  83. const body = await res.json();
  84. assertEquals(body.success, true);
  85. const post = find("Post", { id: "unshare-post-1" }, ["shared"]);
  86. assertEquals(post[0]["shared"], 0);
  87. } finally {
  88. Deno.env.delete("POSTDOWN_DB_PATH");
  89. cleanup(dbPath);
  90. }
  91. });
  92. Deno.test("API share - without token returns error", async () => {
  93. const dbPath = getTestDbPath();
  94. Deno.env.set("POSTDOWN_DB_PATH", dbPath);
  95. try {
  96. const { handler } = await import("../../routes/api/share.tsx");
  97. const ctx = makeCtx("POST", {
  98. id: "some-post",
  99. shared: true,
  100. });
  101. const res = await handler.POST!(ctx as any);
  102. const body = await res.json();
  103. assertEquals(body.success, false);
  104. } finally {
  105. Deno.env.delete("POSTDOWN_DB_PATH");
  106. cleanup(dbPath);
  107. }
  108. });
  109. Deno.test("API share - share another user's post returns error", async () => {
  110. const dbPath = getTestDbPath();
  111. Deno.env.set("POSTDOWN_DB_PATH", dbPath);
  112. try {
  113. const { userId: otherUserId } = await seedUserAndToken("shareother@example.com", "password");
  114. insert("Post", {
  115. id: "other-post-1",
  116. title: "Other's Post",
  117. content: "Content",
  118. user_id: otherUserId,
  119. shared: 0,
  120. });
  121. const { token: myToken } = await seedUserAndToken("shareme@example.com", "password2");
  122. const { handler } = await import("../../routes/api/share.tsx");
  123. const ctx = makeCtx("POST", {
  124. id: "other-post-1",
  125. shared: true,
  126. }, `pd-user-token=${myToken}`);
  127. const res = await handler.POST!(ctx as any);
  128. const body = await res.json();
  129. assertEquals(body.success, false);
  130. } finally {
  131. Deno.env.delete("POSTDOWN_DB_PATH");
  132. cleanup(dbPath);
  133. }
  134. });