public.spec.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. ///<reference path="server/index.d.ts"/>
  2. import { expect, test } from "@playwright/test";
  3. import { CID } from "multiformats";
  4. import { sha256 } from "multiformats/hashes/sha2";
  5. const url = "http://localhost:8085";
  6. test.beforeEach(async ({ page }) => {
  7. await page.goto(url);
  8. await page.waitForFunction(() => window.setup != null);
  9. });
  10. test.describe("PublicDirectory", () => {
  11. test("lookupNode can fetch file added to directory", async ({ page }) => {
  12. const result = await page.evaluate(async () => {
  13. const {
  14. wnfs: { PublicDirectory },
  15. mock: { MemoryBlockStore, sampleCID },
  16. } = await window.setup();
  17. const time = new Date();
  18. const store = new MemoryBlockStore();
  19. const root = new PublicDirectory(time);
  20. var { rootDir } = await root.write(["text.txt"], sampleCID, time, store);
  21. return await rootDir.lookupNode("text.txt", store);
  22. });
  23. expect(result).toBeDefined();
  24. });
  25. test("lookupNode cannot fetch file not added to directory", async ({ page }) => {
  26. const result = await page.evaluate(async () => {
  27. const {
  28. wnfs: { PublicDirectory },
  29. mock: { MemoryBlockStore },
  30. } = await window.setup();
  31. const time = new Date();
  32. const store = new MemoryBlockStore();
  33. const root = new PublicDirectory(time);
  34. return await root.lookupNode("Unknown", store);
  35. });
  36. expect(result).toBe(undefined);
  37. });
  38. test("getNode can fetch node from root dir", async ({ page }) => {
  39. const [result0, result1] = await page.evaluate(async (): Promise<any[]> => {
  40. const {
  41. wnfs: { PublicDirectory },
  42. mock: { MemoryBlockStore, sampleCID },
  43. } = await window.setup();
  44. const time = new Date();
  45. const store = new MemoryBlockStore();
  46. const root = new PublicDirectory(time);
  47. var { rootDir } = await root.mkdir(["pictures", "dogs"], time, store);
  48. var { rootDir } = await rootDir.write(
  49. ["pictures", "cats", "tabby.png"],
  50. sampleCID,
  51. time,
  52. store,
  53. );
  54. let result0 = await rootDir.getNode(["pictures", "cats", "tabby.png"], store);
  55. let result1 = await rootDir.getNode(["pictures", "dogs", "bingo.png"], store);
  56. return [result0, result1];
  57. });
  58. expect(result0).toBeDefined();
  59. expect(result1).toBeUndefined();
  60. });
  61. test("mkdir can create new directory", async ({ page }) => {
  62. const result = await page.evaluate(async () => {
  63. const {
  64. wnfs: { PublicDirectory },
  65. mock: { MemoryBlockStore, sampleCID },
  66. } = await window.setup();
  67. const time = new Date();
  68. const store = new MemoryBlockStore();
  69. const root = new PublicDirectory(time);
  70. var { rootDir } = await root.mkdir(["pictures", "cats"], time, store);
  71. var { rootDir } = await rootDir.write(
  72. ["pictures", "cats", "tabby.png"],
  73. sampleCID,
  74. time,
  75. store,
  76. );
  77. await rootDir.getNode(["pictures", "cats", "tabby.png"], store);
  78. return rootDir;
  79. });
  80. expect(result).toBeDefined();
  81. });
  82. test("ls can list children under directory", async ({ page }) => {
  83. const result = await page.evaluate(async () => {
  84. const {
  85. wnfs: { PublicDirectory },
  86. mock: { MemoryBlockStore, sampleCID },
  87. } = await window.setup();
  88. const time = new Date();
  89. const store = new MemoryBlockStore();
  90. const root = new PublicDirectory(time);
  91. var { rootDir } = await root.mkdir(["pictures", "dogs"], time, store);
  92. var { rootDir } = await rootDir.write(
  93. ["pictures", "cats", "tabby.png"],
  94. sampleCID,
  95. time,
  96. store,
  97. );
  98. const result = await rootDir.ls(["pictures"], store);
  99. return result;
  100. });
  101. expect(result.length).toBe(2);
  102. expect(result[0].name).toBe("cats");
  103. expect(result[1].name).toBe("dogs");
  104. });
  105. test("rm can remove children from directory", async ({ page }) => {
  106. const result = await page.evaluate(async () => {
  107. const {
  108. wnfs: { PublicDirectory },
  109. mock: { MemoryBlockStore, sampleCID },
  110. } = await window.setup();
  111. const time = new Date();
  112. const store = new MemoryBlockStore();
  113. const root = new PublicDirectory(time);
  114. var { rootDir } = await root.write(
  115. ["pictures", "dogs", "billie.jpeg"],
  116. sampleCID,
  117. time,
  118. store,
  119. );
  120. var { rootDir } = await rootDir.write(
  121. ["pictures", "cats", "tabby.png"],
  122. sampleCID,
  123. time,
  124. store,
  125. );
  126. var { rootDir } = await rootDir.rm(["pictures", "cats"], store);
  127. const result = await rootDir.ls(["pictures"], store);
  128. return result;
  129. });
  130. expect(result.length).toEqual(1);
  131. expect(result[0].name).toEqual("dogs");
  132. });
  133. test("basicMv can move content between directories", async ({ page }) => {
  134. const [imagesContent, picturesContent] = await page.evaluate(async () => {
  135. const {
  136. wnfs: { PublicDirectory },
  137. mock: { MemoryBlockStore, sampleCID },
  138. } = await window.setup();
  139. const time = new Date();
  140. const store = new MemoryBlockStore();
  141. const root = new PublicDirectory(time);
  142. var { rootDir } = await root.write(["pictures", "cats", "luna.jpeg"], sampleCID, time, store);
  143. var { rootDir } = await rootDir.write(
  144. ["pictures", "cats", "tabby.png"],
  145. sampleCID,
  146. time,
  147. store,
  148. );
  149. var { rootDir } = await rootDir.mkdir(["images"], time, store);
  150. var { rootDir } = await rootDir.basicMv(
  151. ["pictures", "cats"],
  152. ["images", "cats"],
  153. time,
  154. store,
  155. );
  156. const imagesContent = await rootDir.ls(["images"], store);
  157. const picturesContent = await rootDir.ls(["pictures"], store);
  158. return [imagesContent, picturesContent];
  159. });
  160. expect(imagesContent.length).toEqual(1);
  161. expect(picturesContent.length).toEqual(0);
  162. expect(imagesContent[0].name).toEqual("cats");
  163. });
  164. test("cp can copy content between directories", async ({ page }) => {
  165. const [imagesContent, picturesContent] = await page.evaluate(async () => {
  166. const {
  167. wnfs: { PublicDirectory },
  168. mock: { MemoryBlockStore, sampleCID },
  169. } = await window.setup();
  170. const time = new Date();
  171. const store = new MemoryBlockStore();
  172. const root = new PublicDirectory(time);
  173. var { rootDir } = await root.write(["pictures", "cats", "luna.jpeg"], sampleCID, time, store);
  174. var { rootDir } = await rootDir.write(
  175. ["pictures", "cats", "tabby.png"],
  176. sampleCID,
  177. time,
  178. store,
  179. );
  180. var { rootDir } = await rootDir.mkdir(["images"], time, store);
  181. var { rootDir } = await rootDir.cp(["pictures", "cats"], ["images", "cats"], time, store);
  182. const imagesContent = await rootDir.ls(["images"], store);
  183. const picturesContent = await rootDir.ls(["pictures"], store);
  184. return [imagesContent, picturesContent];
  185. });
  186. expect(imagesContent.length).toEqual(1);
  187. expect(picturesContent.length).toEqual(1);
  188. expect(imagesContent[0].name).toEqual("cats");
  189. });
  190. test("A PublicDirectory has the correct metadata", async ({ page }) => {
  191. const result = await page.evaluate(async () => {
  192. const {
  193. wnfs: { PublicDirectory },
  194. } = await window.setup();
  195. const time = new Date();
  196. return new PublicDirectory(time).metadata();
  197. });
  198. expect(result.created).not.toBeUndefined();
  199. });
  200. test("A PublicFile has the correct metadata", async ({ page }) => {
  201. const result = await page.evaluate(async () => {
  202. const {
  203. wnfs: { PublicFile },
  204. } = await window.setup();
  205. const time = new Date();
  206. return new PublicFile(time).metadata();
  207. });
  208. expect(result.created).not.toBeUndefined();
  209. });
  210. test("A PublicFile can be written and read", async ({ page }) => {
  211. const result = await page.evaluate(async () => {
  212. const {
  213. wnfs: { PublicFile },
  214. mock: { MemoryBlockStore },
  215. } = await window.setup();
  216. const store = new MemoryBlockStore();
  217. const time = new Date();
  218. const file = new PublicFile(time);
  219. const content = new TextEncoder().encode("Hello, World!");
  220. const file2 = await file.setContent(time, content, store);
  221. const readBack = await file2.getContent(store);
  222. const partialRead = await file2.readAt(7, 5, store);
  223. return [new TextDecoder().decode(readBack), new TextDecoder().decode(partialRead)];
  224. });
  225. expect(result[0]).toEqual("Hello, World!");
  226. expect(result[1]).toEqual("World");
  227. });
  228. test("A PublicFile supports chunking files", async ({ page }) => {
  229. const longString = "x".repeat(5 * 1024 * 1024); // 5 MiB
  230. const result = await page.evaluate(async () => {
  231. const {
  232. wnfs: { PublicFile },
  233. mock: { MemoryBlockStore },
  234. } = await window.setup();
  235. const store = new MemoryBlockStore();
  236. const time = new Date();
  237. const file = new PublicFile(time);
  238. const longString = "x".repeat(5 * 1024 * 1024);
  239. const content = new TextEncoder().encode(longString);
  240. const file2 = await file.setContent(time, content, store);
  241. const readBack = await file2.readAt(0, undefined, store);
  242. return new TextDecoder().decode(readBack);
  243. });
  244. expect(result).toEqual(longString);
  245. });
  246. test("A PublicFile has a content CID", async ({ page }) => {
  247. const result = await page.evaluate(async () => {
  248. const {
  249. wnfs: { PublicFile },
  250. mock: { CID, MemoryBlockStore },
  251. } = await window.setup();
  252. const store = new MemoryBlockStore();
  253. const time = new Date();
  254. const file = new PublicFile(time);
  255. const content = new TextEncoder().encode("hello");
  256. const file2 = await file.setContent(time, content, store);
  257. const cid_bytes = await file2.getRawContentCid(store);
  258. return cid_bytes ? CID.decode(cid_bytes).toV1().toString() : undefined;
  259. });
  260. expect(result).not.toBeUndefined();
  261. expect(result).toEqual("bafkr4ihkr4ld3m4gqkjf4reryxsy2s5tkbxprqkow6fin2iiyvreuzzab4");
  262. });
  263. test("A PublicFile has a content size", async ({ page }) => {
  264. const result = await page.evaluate(async () => {
  265. const {
  266. wnfs: { PublicFile },
  267. mock: { MemoryBlockStore },
  268. } = await window.setup();
  269. const store = new MemoryBlockStore();
  270. const time = new Date();
  271. const file = new PublicFile(time);
  272. const longString = "x".repeat(5 * 1024 * 1024);
  273. const content = new TextEncoder().encode(longString);
  274. const file2 = await file.setContent(time, content, store);
  275. return await file2.getSize(store);
  276. });
  277. expect(result).toEqual(5 * 1024 * 1024);
  278. });
  279. });
  280. test.describe("BlockStore", () => {
  281. test("a BlockStore implementation can overwrite the putBlock method", async ({ page }) => {
  282. const result = await page.evaluate(async () => {
  283. const {
  284. wnfs: { PublicFile },
  285. mock: { CID, Sha256BlockStore },
  286. } = await window.setup();
  287. const store = new Sha256BlockStore();
  288. const time = new Date();
  289. const file = new PublicFile(time);
  290. const longString = "x".repeat(5 * 1024 * 1024);
  291. const content = new TextEncoder().encode(longString);
  292. const file2 = await file.setContent(time, content, store);
  293. const cid = await file2.store(store);
  294. return CID.decode(cid).toString();
  295. });
  296. const cid = CID.parse(result);
  297. expect(cid.multihash.code).toEqual(sha256.code);
  298. })
  299. })