///|
/// 写入自测:只在 `<测试目录>/open-list-self-test` 里创建、改名和删除文件。
///|
/// 顺序跑一遍写接口,每步失败只记录并继续。只有只读端点会额外打原始数据,
/// 写端点只调一次类型化方法,避免重复产生副作用。
pub async fn check_write(
client : @lib.OpenListClient,
test_dir : String,
is_admin : Bool,
) -> Unit {
section("写入自测(只动 open-list-self-test 子目录)")
let work = "\{test_dir}/open-list-self-test"
say("工作目录:\{work}")
let _ = check(
"POST /api/fs/mkdir",
"fs().mkdir(work)",
Ok(client.fs().mkdir(work)) catch {
error => Err(error)
},
fn(_) { "已创建目录" },
)
let text = "hello from open-list MoonBit client\n中文也要能传\n"
let _ = check(
"PUT /api/fs/put",
"fs().put_bytes(work + \"/hello.txt\")",
Ok(
client
.fs()
.put_bytes(
"\{work}/hello.txt",
@utf8.encode(text),
content_type="text/plain",
),
) catch {
error => Err(error)
},
task_result,
)
let _ = check(
"PUT /api/fs/put (As-Task)",
"fs().put_bytes(work + \"/task.txt\", as_task=true)",
Ok(
client
.fs()
.put_bytes(
"\{work}/task.txt",
@utf8.encode(text),
as_task=true,
content_type="text/plain",
),
) catch {
error => Err(error)
},
task_result,
)
let _ = check(
"PUT /api/fs/form",
"fs().put_form(work + \"/form.txt\", \"form.txt\")",
Ok(
client
.fs()
.put_form(
"\{work}/form.txt",
"form.txt",
@utf8.encode(text),
content_type="text/plain",
),
) catch {
error => Err(error)
},
task_result,
)
let _ = check(
"POST /api/fs/multipart/init → chunk → complete",
"fs().multipart_upload(work + \"/big.bin\", 3MB)",
Ok(
client
.fs()
.multipart_upload(
"\{work}/big.bin",
@utf8.encode("0123456789".repeat(300_000)),
chunk_size=1_048_576,
),
) catch {
error => Err(error)
},
fn(snapshot) {
"state=\{snapshot.state},已收 \{snapshot.received_bytes}/\{snapshot.size} 字节,分片 \{snapshot.received.length()}/\{snapshot.total_chunks}"
},
)
let listing = check(
"POST /api/fs/list",
"fs().list(work, refresh=true)",
Ok(client.fs().list(work, refresh=true, page=1, per_page=50)) catch {
error => Err(error)
},
fn(page) {
"total=\{page.total},写入后 \{page.content.length()} 个文件"
},
)
dump_raw(
client,
@lib.Method::Post,
"/api/fs/list",
body=Json::object({
"path": Json::string(work),
"page": Json::number(1),
"per_page": Json::number(50),
"refresh": Json::boolean(true),
}),
)
match listing {
Some(page) => {
say(" 写入后的条目:")
say(entry_lines(page.content))
}
None => ()
}
let _ = check(
"POST /api/fs/get",
"fs().get(work + \"/hello.txt\")",
Ok(client.fs().get("\{work}/hello.txt")) catch {
error => Err(error)
},
fn(response) { obj_summary(response.obj) },
)
let _ = check(
"POST /api/fs/rename",
"fs().rename(hello.txt → renamed.txt)",
Ok(client.fs().rename("\{work}/hello.txt", "renamed.txt")) catch {
error => Err(error)
},
fn(_) { "已改名" },
)
if is_admin {
let _ = check(
"POST /api/fs/link",
"fs().create_link(work + \"/task.txt\")",
Ok(client.fs().create_link("\{work}/task.txt")) catch {
error => Err(error)
},
fn(link) {
"url=\{brief(link.url, 60)} 并发=\{link.concurrency} 分片大小=\{link.part_size}"
},
)
} else {
skip(
"POST /api/fs/link", "fs().create_link(path)", "只有管理员能调用",
)
}
check_share_write(client, work)
let _ = check(
"POST /api/fs/remove",
"fs().remove(work, [...])",
Ok(
client
.fs()
.remove(work, ["renamed.txt", "task.txt", "form.txt", "big.bin"]),
) catch {
error => Err(error)
},
fn(_) { "已删除 4 个文件" },
)
let _ = check(
"POST /api/fs/remove_empty_directory",
"fs().remove_empty_directory(work)",
Ok(client.fs().remove_empty_directory(work)) catch {
error => Err(error)
},
fn(_) { "已删除自测目录" },
)
}
///|
/// 分享的写入自测:创建 → 查询 → 禁用 → 删除。
async fn check_share_write(client : @lib.OpenListClient, work : String) -> Unit {
let request = @lib.SharingUpdateRequest::new(
["\{work}/task.txt"],
pwd="1234",
remark="open-list 联调自测",
)
let created = check(
"POST /api/share/create",
"share().create(files → task.txt)",
Ok(client.share().create(request)) catch {
error => Err(error)
},
sharing_summary,
)
match created {
Some(sharing) => {
let _ = check(
"GET /api/share/get",
"share().get(id)",
Ok(client.share().get(sharing.id)) catch {
error => Err(error)
},
sharing_summary,
)
dump_raw(
client,
@lib.Method::Get,
"/api/share/get",
query=Json::object({ "id": Json::string(sharing.id) }),
)
let _ = check(
"POST /api/share/disable",
"share().disable(id)",
Ok(client.share().disable(sharing.id)) catch {
error => Err(error)
},
fn(_) { "已禁用分享 \{sharing.id}" },
)
let _ = check(
"POST /api/share/delete",
"share().delete(id)",
Ok(client.share().delete(sharing.id)) catch {
error => Err(error)
},
fn(_) { "已删除分享 \{sharing.id}" },
)
}
None => ()
}
}