Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: get_node should return null on missing path #253

Merged
merged 3 commits into from
May 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions wnfs-wasm/src/fs/private/directory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,7 @@ impl PrivateDirectory {
.await
.map_err(error("Cannot get node"))?;

Ok(utils::create_private_op_result(
directory,
forest,
result.map(PrivateNode),
)?)
appcypher marked this conversation as resolved.
Show resolved Hide resolved
Ok(value!(result.map(PrivateNode)))
}))
}

Expand Down
67 changes: 64 additions & 3 deletions wnfs-wasm/tests/private.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,61 @@ test.describe("PrivateDirectory", () => {
expect(result).toBeDefined();
});

test("getNode can fetch node from root dir", async ({ page }) => {
const [result0, result1] = await page.evaluate(async (): Promise<any[]> => {
const {
wnfs: { PrivateDirectory, PrivateForest, Namefilter },
mock: { MemoryBlockStore, Rng },
} = await window.setup();

const initialForest = new PrivateForest();
const rng = new Rng();
const store = new MemoryBlockStore();
const root = new PrivateDirectory(new Namefilter(), new Date(), rng);

var { rootDir, forest } = await root.mkdir(
["pictures", "dogs"],
true,
new Date(),
initialForest,
store,
rng
);

var { rootDir, forest } = await rootDir.write(
["pictures", "cats", "tabby.png"],
true,
new Uint8Array([1, 2, 3, 4, 5]),
new Date(),
forest,
store,
rng
);

var result0 = await rootDir.getNode(
["pictures", "cats", "tabby.png"],
true,
forest,
store
);

var result1 = await rootDir.getNode(
["pictures", "dogs", "bingo.png"],
true,
forest,
store
);

console.log(result0);
console.log(result1);

return [result0, result1];
});

expect(result0).toBeDefined();
expect(result1).toBeUndefined();
});

test("lookupNode cannot fetch file not added to directory", async ({
page,
}) => {
Expand Down Expand Up @@ -89,14 +144,14 @@ test.describe("PrivateDirectory", () => {
rng
);

var { rootDir } = await rootDir.getNode(
var result = await rootDir.getNode(
["pictures", "cats", "tabby.png"],
true,
forest,
store
);

return rootDir;
return result;
});

expect(result).toBeDefined();
Expand Down Expand Up @@ -527,7 +582,13 @@ test.describe("PrivateForest", () => {
test("merge combines changes in forests", async ({ page }) => {
const result = await page.evaluate(async () => {
const {
wnfs: { Namefilter, PrivateFile, PrivateDirectory, PrivateForest, PrivateNode },
wnfs: {
Namefilter,
PrivateFile,
PrivateDirectory,
PrivateForest,
PrivateNode,
},
mock: { MemoryBlockStore, Rng },
} = await window.setup();

Expand Down
44 changes: 39 additions & 5 deletions wnfs-wasm/tests/public.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ test.describe("PublicDirectory", () => {
expect(result).toBe(undefined);
});

test("mkdir can create new directory", async ({ page }) => {
const result = await page.evaluate(async () => {
test("getNode can fetch node from root dir", async ({ page }) => {
const [result0, result1] = await page.evaluate(async (): Promise<any[]> => {
const {
wnfs: { PublicDirectory },
mock: { MemoryBlockStore, sampleCID },
Expand All @@ -59,7 +59,7 @@ test.describe("PublicDirectory", () => {
const store = new MemoryBlockStore();
const root = new PublicDirectory(time);

var { rootDir } = await root.mkdir(["pictures", "cats"], time, store);
var { rootDir } = await root.mkdir(["pictures", "dogs"], time, store);

var { rootDir } = await rootDir.write(
["pictures", "cats", "tabby.png"],
Expand All @@ -68,11 +68,45 @@ test.describe("PublicDirectory", () => {
store
);

await rootDir.getNode(
let result0 = await rootDir.getNode(
["pictures", "cats", "tabby.png"],
store
);

let result1 = await rootDir.getNode(
["pictures", "dogs", "bingo.png"],
store
);

return [result0, result1];
});

expect(result0).toBeDefined();
expect(result1).toBeUndefined();
});

test("mkdir can create new directory", async ({ page }) => {
const result = await page.evaluate(async () => {
const {
wnfs: { PublicDirectory },
mock: { MemoryBlockStore, sampleCID },
} = await window.setup();

const time = new Date();
const store = new MemoryBlockStore();
const root = new PublicDirectory(time);

var { rootDir } = await root.mkdir(["pictures", "cats"], time, store);

var { rootDir } = await rootDir.write(
["pictures", "cats", "tabby.png"],
sampleCID,
time,
store
);

await rootDir.getNode(["pictures", "cats", "tabby.png"], store);

return rootDir;
});

Expand Down Expand Up @@ -208,7 +242,7 @@ test.describe("PublicDirectory", () => {
const result = await page.evaluate(async () => {
const {
wnfs: { PublicFile },
mock: { sampleCID }
mock: { sampleCID },
} = await window.setup();

const time = new Date();
Expand Down
87 changes: 84 additions & 3 deletions wnfs/src/private/directory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ impl PrivateDirectory {

let temporal_key = self.header.derive_temporal_key();
let previous_link = (1, Encrypted::from_value(previous_cid, &temporal_key)?);
let mut cloned = Rc::make_mut(self);
let cloned = Rc::make_mut(self);

// We make sure to clear any cached states.
cloned.content.persisted_as = OnceCell::new();
Expand Down Expand Up @@ -530,11 +530,11 @@ impl PrivateDirectory {
store: &impl BlockStore,
) -> Result<Option<PrivateNode>> {
let Some((tail, path)) = path_segments.split_last() else {
bail!(FsError::InvalidPath);
return Ok(None);
};

let SearchResult::Found(dir) = self.get_leaf_dir(path, search_latest, forest, store).await? else {
bail!(FsError::NotFound);
return Ok(None);
};

dir.lookup_node(tail, search_latest, forest, store).await
Expand Down Expand Up @@ -1605,6 +1605,87 @@ mod tests {
assert!(node.is_none());
}

#[test(async_std::test)]
async fn get_node_can_fetch_node_from_root_dir() {
let rng = &mut TestRng::deterministic_rng(RngAlgorithm::ChaCha);
let root_dir = &mut Rc::new(PrivateDirectory::new(
Namefilter::default(),
Utc::now(),
rng,
));
let store = &mut MemoryBlockStore::default();
let forest = &mut Rc::new(PrivateForest::new());

root_dir
.mkdir(
&["pictures".into(), "dogs".into()],
true,
Utc::now(),
forest,
store,
rng,
)
.await
.unwrap();

root_dir
.write(
&["pictures".into(), "cats".into(), "tabby.jpg".into()],
true,
Utc::now(),
b"file".to_vec(),
forest,
store,
rng,
)
.await
.unwrap();

assert!(root_dir
.get_node(
&["pictures".into(), "cats".into(), "tabby.jpg".into()],
true,
forest,
store,
)
.await
.unwrap()
.is_some());

assert!(root_dir
.get_node(
&["pictures".into(), "cats".into(), "tabby.jpeg".into()],
true,
forest,
store,
)
.await
.unwrap()
.is_none());

assert!(root_dir
.get_node(
&["images".into(), "parrots".into(), "coco.png".into()],
true,
forest,
store,
)
.await
.unwrap()
.is_none());

assert!(root_dir
.get_node(
&["pictures".into(), "dogs".into(), "bingo.jpg".into()],
true,
forest,
store,
)
.await
.unwrap()
.is_none());
}

#[test(async_std::test)]
async fn mkdir_can_create_new_directory() {
let rng = &mut TestRng::deterministic_rng(RngAlgorithm::ChaCha);
Expand Down
2 changes: 1 addition & 1 deletion wnfs/src/private/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ impl PrivateFile {

let temporal_key = self.header.derive_temporal_key();
let previous_link = (1, Encrypted::from_value(previous_cid, &temporal_key)?);
let mut cloned = Rc::make_mut(self);
let cloned = Rc::make_mut(self);

// We make sure to clear any cached states.
cloned.content.persisted_as = OnceCell::new();
Expand Down
62 changes: 60 additions & 2 deletions wnfs/src/public/directory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,11 +247,11 @@ impl PublicDirectory {
store: &impl BlockStore,
) -> Result<Option<&'a PublicNode>> {
let Some((tail, path)) = path_segments.split_last() else {
bail!(FsError::InvalidPath);
return Ok(None);
};

let SearchResult::Found(dir) = self.get_leaf_dir(path, store).await? else {
bail!(FsError::NotFound);
return Ok(None)
};

dir.lookup_node(tail, store).await
Expand Down Expand Up @@ -845,6 +845,64 @@ mod tests {
assert_eq!(node.unwrap(), None);
}

#[async_std::test]
async fn get_node_can_fetch_node_from_root_dir() {
let time = Utc::now();
let store = MemoryBlockStore::default();
let root_dir = &mut Rc::new(PublicDirectory::new(time));

root_dir
.mkdir(&["pictures".into(), "dogs".into()], time, &store)
.await
.unwrap();

root_dir
.write(
&["pictures".into(), "cats".into(), "tabby.jpg".into()],
Cid::default(),
time,
&store,
)
.await
.unwrap();

assert!(root_dir
.get_node(
&["pictures".into(), "cats".into(), "tabby.jpg".into()],
&store
)
.await
.unwrap()
.is_some());

assert!(root_dir
.get_node(
&["pictures".into(), "cats".into(), "tabby.jpeg".into()],
&store
)
.await
.unwrap()
.is_none());

assert!(root_dir
.get_node(
&["images".into(), "parrots".into(), "coco.png".into()],
&store
)
.await
.unwrap()
.is_none());

assert!(root_dir
.get_node(
&["pictures".into(), "dogs".into(), "bingo.jpg".into()],
&store
)
.await
.unwrap()
.is_none());
}

#[async_std::test]
async fn directory_added_to_store_can_be_retrieved() {
let root = PublicDirectory::new(Utc::now());
Expand Down
Loading