share_test.ts 4.4 KB

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