mirror of
https://github.com/HeyPuter/puter.git
synced 2026-05-04 00:20:45 +00:00
fs: adapt to different mkdir api, block write to root dir, add tests
This commit is contained in:
@@ -271,8 +271,32 @@ class HLMkdir extends HLFilesystemOperation {
|
||||
});
|
||||
}
|
||||
|
||||
// Unify the following formats:
|
||||
// - full path: {"path":"/foo/bar", args...}, used by apitest (./tools/api-tester/apitest.js)
|
||||
// - parent + path: {"parent": "/foo", "path":"bar", args...}, used by puter-js (puter.fs.mkdir("/foo/bar"))
|
||||
if ( !values.parent && values.path ) {
|
||||
values.parent = await fs.node(new NodePathSelector(_path.dirname(values.path)));
|
||||
values.path = _path.basename(values.path);
|
||||
}
|
||||
|
||||
let parent_node = values.parent || await fs.node(new RootNodeSelector());
|
||||
if ( parent_node.isRoot ) {
|
||||
// root directory is read-only
|
||||
throw APIError.create('forbidden', null, {
|
||||
message: 'Cannot create directories in the root directory.'
|
||||
});
|
||||
}
|
||||
console.log('USING PARENT', parent_node.selector.describe());
|
||||
|
||||
// TODO: this can be removed upon completion of: https://github.com/HeyPuter/puter/issues/1352
|
||||
if ( parent_node.isRoot ) {
|
||||
// root directory is read-only
|
||||
throw APIError.create('forbidden', null, {
|
||||
message: 'Cannot create directories in the root directory.'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
let target_basename = _path.basename(values.path);
|
||||
|
||||
// "top_parent" is the immediate parent of the target directory
|
||||
@@ -282,14 +306,6 @@ class HLMkdir extends HLFilesystemOperation {
|
||||
: await this._get_existing_top_parent({ top_parent: parent_node })
|
||||
;
|
||||
|
||||
// TODO: this can be removed upon completion of: https://github.com/HeyPuter/puter/issues/1352
|
||||
if ( top_parent.isRoot ) {
|
||||
// root directory is read-only
|
||||
throw APIError.create('forbidden', null, {
|
||||
message: 'Cannot create directories in the root directory.'
|
||||
});
|
||||
}
|
||||
|
||||
// `parent_node` becomes the parent of the last directory name
|
||||
// specified under `path`.
|
||||
parent_node = await this._create_parents({
|
||||
|
||||
@@ -188,6 +188,16 @@ module.exports = class TestSDK {
|
||||
});
|
||||
return res.data;
|
||||
};
|
||||
// parent + path format: {"parent": "/foo", "path":"bar", args...}
|
||||
// this is used by puter-js (puter.fs.mkdir("/foo/bar"))
|
||||
this.mkdir_v2 = async (parent, path, opts) => {
|
||||
const res = await this.post('mkdir', {
|
||||
parent: p(parent),
|
||||
path: p(path),
|
||||
...(opts ?? {})
|
||||
});
|
||||
return res.data;
|
||||
}
|
||||
this.write = async (path, bin, params) => {
|
||||
path = p(path);
|
||||
params = params ?? {};
|
||||
|
||||
@@ -65,5 +65,107 @@ module.exports = {
|
||||
expect(stat.name).equal(`a (${i})`);
|
||||
}
|
||||
});
|
||||
|
||||
await t.case('mkdir in root directory is prohibited', async () => {
|
||||
const path = '/a';
|
||||
await t.case('throws 403', async () => {
|
||||
try {
|
||||
// full path format: {"path":"/foo/bar", args...}
|
||||
await t.mkdir(path);
|
||||
} catch (e) {
|
||||
expect(e.response.status).equal(403);
|
||||
}
|
||||
|
||||
try {
|
||||
// parent + path format: {"parent": "/foo", "path":"bar", args...}
|
||||
const parent = '/';
|
||||
await t.mkdir(path, {
|
||||
parent: parent,
|
||||
});
|
||||
} catch (e) {
|
||||
expect(e.response.status).equal(403);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
await t.case('create_missing_parents works (full path api)', async () => {
|
||||
const path = 'a/b/c';
|
||||
|
||||
await t.case('parent directory does not exist', async () => {
|
||||
try {
|
||||
await t.stat('a');
|
||||
} catch (e) {
|
||||
expect(e.response.status).equal(404);
|
||||
}
|
||||
});
|
||||
|
||||
await t.case('mkdir failed without create_missing_parents', async () => {
|
||||
try {
|
||||
await t.mkdir('a/b/c');
|
||||
} catch (e) {
|
||||
expect(e.response.status).equal(409);
|
||||
}
|
||||
});
|
||||
|
||||
await t.case('mkdir succeeds with create_missing_parents', async () => {
|
||||
const result = await t.mkdir('a/b/c', {
|
||||
create_missing_parents: true,
|
||||
});
|
||||
expect(result.name).equal('c');
|
||||
});
|
||||
|
||||
await t.case('can stat the directory', async () => {
|
||||
const stat = await t.stat(path);
|
||||
expect(stat.name).equal('c');
|
||||
});
|
||||
|
||||
await t.case('can stat the parent directory', async () => {
|
||||
let stat = await t.stat('a');
|
||||
expect(stat.name).equal('a');
|
||||
|
||||
stat = await t.stat('a/b');
|
||||
expect(stat.name).equal('b');
|
||||
});
|
||||
});
|
||||
|
||||
await t.case('create_missing_parents works (parent + path api)', async () => {
|
||||
const path = 'a/b/c';
|
||||
|
||||
await t.case('parent directory does not exist', async () => {
|
||||
try {
|
||||
await t.stat('a');
|
||||
} catch (e) {
|
||||
expect(e.response.status).equal(404);
|
||||
}
|
||||
});
|
||||
|
||||
await t.case('mkdir failed without create_missing_parents', async () => {
|
||||
try {
|
||||
await t.mkdir_v2('a/b', 'c');
|
||||
} catch (e) {
|
||||
expect(e.response.status).equal(409);
|
||||
}
|
||||
});
|
||||
|
||||
await t.case('mkdir succeeds with create_missing_parents', async () => {
|
||||
const result = await t.mkdir_v2('a/b', 'c', {
|
||||
create_missing_parents: true,
|
||||
});
|
||||
expect(result.name).equal('c');
|
||||
});
|
||||
|
||||
await t.case('can stat the directory', async () => {
|
||||
const stat = await t.stat(path);
|
||||
expect(stat.name).equal('c');
|
||||
});
|
||||
|
||||
await t.case('can stat the parent directory', async () => {
|
||||
let stat = await t.stat('a');
|
||||
expect(stat.name).equal('a');
|
||||
|
||||
stat = await t.stat('a/b');
|
||||
expect(stat.name).equal('b');
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user