diff --git a/wnfs-wasm/playwright.config.ts b/wnfs-wasm/playwright.config.ts index ce14e400..1fdab127 100644 --- a/wnfs-wasm/playwright.config.ts +++ b/wnfs-wasm/playwright.config.ts @@ -49,18 +49,18 @@ const config: PlaywrightTestConfig = { ...devices["Desktop Chrome"], }, }, - { - name: "firefox", - use: { - ...devices["Desktop Firefox"], - }, - }, - { - name: "safari", - use: { - ...devices["Desktop Safari"], - }, - }, + // { + // name: "firefox", + // use: { + // ...devices["Desktop Firefox"], + // }, + // }, + // { + // name: "safari", + // use: { + // ...devices["Desktop Safari"], + // }, + // }, ], /* Folder for test artifacts such as screenshots, videos, traces, etc. */ diff --git a/wnfs-wasm/src/fs/private/node.rs b/wnfs-wasm/src/fs/private/node.rs index 949bb2c5..bc161bc6 100644 --- a/wnfs-wasm/src/fs/private/node.rs +++ b/wnfs-wasm/src/fs/private/node.rs @@ -81,6 +81,22 @@ impl PrivateNode { })) } + #[wasm_bindgen(js_name = "searchLatest")] + pub fn search_latest(&self, forest: &PrivateForest, store: BlockStore) -> JsResult { + let node = self.0.clone(); // cheap clone + let store = ForeignBlockStore(store); + let forest = Rc::clone(&forest.0); + + Ok(future_to_promise(async move { + let latest_node = node + .search_latest(&forest, &store) + .await + .map_err(error("Cannot search latest"))?; + + Ok(value!(PrivateNode(latest_node))) + })) + } + #[wasm_bindgen(js_name = "asDir")] pub fn as_dir(&self) -> JsResult { let dir = self diff --git a/wnfs-wasm/tests/private.spec.ts b/wnfs-wasm/tests/private.spec.ts index a7bf7602..727b000e 100644 --- a/wnfs-wasm/tests/private.spec.ts +++ b/wnfs-wasm/tests/private.spec.ts @@ -500,6 +500,72 @@ test.describe("PrivateFile", () => { }); }); +test.describe("PrivateNode", () => { + test("load returns what was stored", async ({ page }) => { + const [metadataBefore, metadataAfter] = await page.evaluate(async () => { + const { + wnfs: { PrivateFile, PrivateNode, PrivateForest }, + mock: { MemoryBlockStore, Rng }, + } = await window.setup(); + + const rng = new Rng(); + const store = new MemoryBlockStore(); + const forest = new PrivateForest(rng); + const time = new Date(); + const file = new PrivateFile(forest.emptyName(), time, rng); + const node = file.asNode(); + const [privateRef, newForest] = await node.store(forest, store, rng); + const fetched = await PrivateNode.load(privateRef, newForest, store); + const metadataBefore = node.asFile().metadata(); + const metadataAfter = fetched.asFile().metadata(); + return [metadataBefore, metadataAfter]; + }); + + expect(metadataBefore).toBeDefined(); + expect(metadataAfter).toBeDefined(); + expect(metadataBefore.created).toEqual(metadataAfter.created); + expect(metadataBefore.modified).toEqual(metadataAfter.modified); + }); + + test("searchLatest finds latest", async ({ page }) => { + const [lsResultBefore, lsResultAfter] = await page.evaluate(async () => { + const { + wnfs: { PrivateDirectory, PrivateNode, PrivateForest }, + mock: { MemoryBlockStore, Rng }, + } = await window.setup(); + + const rng = new Rng(); + const store = new MemoryBlockStore(); + const forest0 = new PrivateForest(rng); + const time = new Date(); + + // Create a root directory and store + const rootDir0 = new PrivateDirectory(forest0.emptyName(), time, rng); + const [accessKey, forest1] = await rootDir0.store(forest0, store, rng); + + // Write something to the directory and store it + const { rootDir: rootDir1, forest: forest2 } = await rootDir0.write(["some", "file.txt"], true, new Uint8Array([0]), time, forest1, store, rng); + const [_, forest3] = await rootDir1.asNode().store(forest2, store, rng); + + // loading back the *old* directory using its access key should give an empty directory: + const oldNode = await PrivateNode.load(accessKey, forest3, store); + const { result: lsResultBefore } = await oldNode.asDir().ls([], false, forest3, store); + + // loading back the directory with search latest should work: + const latestNode = await oldNode.searchLatest(forest3, store); + const { result: lsResultAfter } = await latestNode.asDir().ls([], false, forest3, store); + + return [lsResultBefore, lsResultAfter]; + }); + + expect(lsResultBefore).toBeDefined(); + expect(lsResultAfter).toBeDefined(); + expect(lsResultBefore).toEqual([]); + expect(lsResultAfter.length).toEqual(1); + expect(lsResultAfter[0].name).toEqual("some"); + }) +}) + test.describe("PrivateForest", () => { test("store returns a PrivateRef", async ({ page }) => { const result = await page.evaluate(async () => { @@ -528,32 +594,6 @@ test.describe("PrivateForest", () => { expect(result.contentCid).toBeDefined(); }); - test("load returns what was stored", async ({ page }) => { - const [metadataBefore, metadataAfter] = await page.evaluate(async () => { - const { - wnfs: { PrivateFile, PrivateNode, PrivateForest }, - mock: { MemoryBlockStore, Rng }, - } = await window.setup(); - - const rng = new Rng(); - const store = new MemoryBlockStore(); - const forest = new PrivateForest(rng); - const time = new Date(); - const file = new PrivateFile(forest.emptyName(), time, rng); - const node = file.asNode(); - const [privateRef, newForest] = await node.store(forest, store, rng); - const fetched = await PrivateNode.load(privateRef, newForest, store); - const metadataBefore = node.asFile().metadata(); - const metadataAfter = fetched.asFile().metadata(); - return [metadataBefore, metadataAfter]; - }); - - expect(metadataBefore).toBeDefined(); - expect(metadataAfter).toBeDefined(); - expect(metadataBefore.created).toEqual(metadataAfter.created); - expect(metadataBefore.modified).toEqual(metadataAfter.modified); - }); - test("diff gets changes in forests", async ({ page }) => { const changes = await page.evaluate(async () => { const { @@ -626,7 +666,7 @@ test.describe("AccessKey", () => { mock: { MemoryBlockStore, Rng }, } = await window.setup(); - + const rng = new Rng(); const store = new MemoryBlockStore(); const forest = new PrivateForest(rng); @@ -634,16 +674,16 @@ test.describe("AccessKey", () => { const file = new PrivateFile(forest.emptyName(), time, rng); const node = file.asNode(); const [accessKey, newForest] = await node.store(forest, store, rng); - + const encodedAccessKey = accessKey.toBytes(); const decodedAccessKey = AccessKey.fromBytes(encodedAccessKey); - + const fetched = await PrivateNode.load(decodedAccessKey, newForest, store); const metadataBefore = node.asFile().metadata(); const metadataAfter = fetched.asFile().metadata(); return [metadataBefore, metadataAfter]; }); - + expect(metadataBefore).toBeDefined(); expect(metadataAfter).toBeDefined(); expect(metadataBefore.created).toEqual(metadataAfter.created);