117 lines
4.6 KiB
Rust
117 lines
4.6 KiB
Rust
use super::package::packages;
|
|
|
|
const STORAGE: &str = "public type PutResult { Stored(key: Uuid)\nerror Failed(message: Text) }\npublic put(upload: Upload) (key: Uuid) { key = stored(dever.system.uploadPut(upload)) }\nstored(result: PutResult.Stored(value)) (key: Uuid) { key = value }\nstored(result: PutResult.Failed(message)) (key: Uuid) { fail(PutResult.Failed(message)) }";
|
|
const APP: &str = "accept(file: Upload, caption: Text) (size: Int, name: Text) { size = dever.api.uploadSize(file)\nname = caption + dever.api.uploadFilename(file)\ndever.api.closeUpload(file) }";
|
|
|
|
#[test]
|
|
fn upload_metadata_then_close_preserves_a_single_owned_post_input() {
|
|
let program = packages(&[
|
|
("demo.media.app", APP),
|
|
("demo.media.api", "public post accept = app.accept"),
|
|
])
|
|
.unwrap();
|
|
assert!(
|
|
dever::compiler::build::runtime_features(&program, &program.entries().collect())
|
|
.contains(&"upload")
|
|
);
|
|
for api in ["public get accept = app.accept", "cmd accept = app.accept"] {
|
|
assert!(
|
|
packages(&[("demo.media.app", APP), ("demo.media.api", api)]).is_err(),
|
|
"{api}"
|
|
);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn upload_rejects_duplication_nesting_output_and_helpers() {
|
|
for app in [
|
|
"accept(file: Upload) () {}",
|
|
"accept(file: Upload) () { dever.api.closeUpload(file)\ndever.api.closeUpload(file) }",
|
|
"accept(file: Upload) (size: Int) { dever.api.closeUpload(file)\nsize = dever.api.uploadSize(file) }",
|
|
"accept(file: Upload) () { copy = file\ndever.api.closeUpload(copy) }",
|
|
"accept(file: Upload) (out: Upload) { out = file }",
|
|
"type Container { file: Upload }",
|
|
"type Container { Wrapped(file: Upload) }",
|
|
"accept(files: List<Upload>) () {}",
|
|
"accept(file: Upload?) () {}",
|
|
"accept(file: Upload, other: Upload) () { dever.api.closeUpload(file)\ndever.api.closeUpload(other) }",
|
|
"accept(file: Upload) () { helper(file) }\nhelper(file: Upload) () { dever.api.closeUpload(file) }",
|
|
] {
|
|
let error = packages(&[("demo.media.app", app)]).unwrap_err();
|
|
assert!(
|
|
!error.code.starts_with('P'),
|
|
"syntax did not reach ownership check: {error:?}"
|
|
);
|
|
}
|
|
assert!(packages(&[("demo.media.domain", "ignore(file: Upload) () {}")]).is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn upload_storage_requires_a_same_domain_port_and_never_escapes_to_tasks() {
|
|
let app = "accept(file: Upload) (key: Uuid) { key = port.store(file) }";
|
|
let port = "store(file: Upload) (key: Uuid) fails dever.storage.PutResult";
|
|
let adapter = "port.store(file: Upload) (key: Uuid) { key = dever.storage.put(file) }";
|
|
let checked = |app: &str| {
|
|
packages(&[
|
|
("dever.storage", STORAGE),
|
|
("demo.media.app", app),
|
|
("demo.media.port", port),
|
|
("demo.media.adapter.disk", adapter),
|
|
("demo.media.api", "public post accept = app.accept"),
|
|
])
|
|
};
|
|
checked(app).unwrap();
|
|
for app in [
|
|
"accept(file: Upload) (key: Uuid) { key = dever.storage.put(file) }",
|
|
"accept(file: Upload) (key: Uuid) { task = run(port.store(file))\nkey = wait(task) }",
|
|
"accept(file: Upload) (key: Uuid) { key = blocking(port.store(file)) }",
|
|
"accept(file: Upload) (key: Uuid) { key = parallel(port.store(file)) }",
|
|
] {
|
|
assert!(checked(app).is_err(), "{app}");
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn upload_storage_remains_an_external_effect_for_database_transactions() {
|
|
let check = |prefix: &str, api: &str| {
|
|
packages(&[
|
|
("dever.storage", STORAGE),
|
|
("dever.database", super::database::ERROR),
|
|
("demo.media.model", "type Entry { name: Text }"),
|
|
(
|
|
"demo.media.app",
|
|
&format!(
|
|
"{prefix}accept(file: Upload) (key: Uuid) {{ row = model.create({{ name = \"upload\" }})\nkey = port.store(file) }}"
|
|
),
|
|
),
|
|
(
|
|
"demo.media.port",
|
|
"store(file: Upload) (key: Uuid) fails dever.storage.PutResult",
|
|
),
|
|
(
|
|
"demo.media.adapter",
|
|
"port.store(file: Upload) (key: Uuid) { key = dever.storage.put(file) }",
|
|
),
|
|
("demo.media.api", api),
|
|
])
|
|
};
|
|
assert_eq!(
|
|
check("", "public post accept = app.accept")
|
|
.unwrap_err()
|
|
.code,
|
|
"C014"
|
|
);
|
|
assert_eq!(
|
|
check("transaction ", "public post accept = app.accept")
|
|
.unwrap_err()
|
|
.code,
|
|
"C014"
|
|
);
|
|
assert_eq!(
|
|
check("", "public long post accept = app.accept")
|
|
.unwrap_err()
|
|
.code,
|
|
"C014"
|
|
);
|
|
}
|