use anyhow::{Context, Result}; use assert_cmd::prelude::*; use futures::TryStreamExt; use predicates::str::contains; use toml_edit::{value, Array}; use wasm_metadata::LinkType; use wasm_pkg_client::{Client, Error}; use crate::support::*; mod support; #[test] fn help() { for arg in ["help publish", "publish -h", "publish --help"] { wit(arg.split_whitespace()) .assert() .stdout(contains("Publish a WIT package to a registry")) .success(); } } #[test] fn it_fails_with_missing_toml_file() -> Result<()> { wit(["publish"]) .assert() .stderr(contains( "error: failed to find configuration file `wit.toml`", )) .failure(); Ok(()) } #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn it_publishes_a_wit_package() -> Result<()> { let (server, _, _) = spawn_server(Vec::::new()).await?; let project = server.project("foo", Vec::::new())?; project.file("baz.wit", "package test:qux;\n")?; project .wit(["publish"]) .env("WIT_PUBLISH_KEY", test_signing_key()) .assert() .stderr(contains("Published package `test:qux` v0.1.0")) .success(); Ok(()) } #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn it_does_a_dry_run_publish() -> Result<()> { let (server, config, _) = spawn_server(Vec::::new()).await?; let project = server.project("foo", Vec::::new())?; project.file("baz.wit", "package test:qux;\n")?; project .wit(["publish", "--dry-run"]) .env("WIT_PUBLISH_KEY", test_signing_key()) .assert() .stderr(contains( "warning: not publishing package to the registry due to the --dry-run option", )) .success(); let client = Client::new(config); let err = client .get_release(&"test:qux".parse().unwrap(), &"0.1.0".parse().unwrap()) .await .expect_err("Should not be able to get release after dry run"); assert!( matches!(err, Error::PackageNotFound), "Expected PackageNotFound" ); Ok(()) } #[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn it_publishes_with_registry_metadata() -> Result<()> { let (server, config, _) = spawn_server(Vec::::new()).await?; let project = server.project("foo", Vec::::new())?; let authors = ["Jane Doe "]; let categories = ["wasm"]; let description = "A test package"; let license = "Apache-2.0"; let documentation = "https://example.com/docs"; let homepage = "https://example.com/home"; let repository = "https://example.com/repo"; project.file("baz.wit", "package test:qux;\n")?; project.update_manifest(|mut doc| { doc["authors"] = value(Array::from_iter(authors)); doc["categories"] = value(Array::from_iter(categories)); doc["description"] = value(description); doc["license"] = value(license); doc["documentation"] = value(documentation); doc["homepage"] = value(homepage); doc["repository"] = value(repository); Ok(doc) })?; project .wit(["publish"]) .env("WIT_PUBLISH_KEY", test_signing_key()) .assert() .stderr(contains("Published package `test:qux` v0.1.0")) .success(); let client = Client::new(config); let package_ref = "test:qux".parse().unwrap(); let release = client .get_release(&package_ref, &"0.1.0".parse().unwrap()) .await?; let stream = client.stream_content(&package_ref, &release).await?; let bytes = stream.map_ok(Vec::from).try_concat().await?; let metadata = wasm_metadata::RegistryMetadata::from_wasm(&bytes) .context("failed to parse registry metadata from bytes")? .expect("missing registry metadata"); assert_eq!( metadata.get_authors().expect("missing authors").as_slice(), authors ); assert_eq!( metadata .get_categories() .expect("missing categories") .as_slice(), categories ); assert_eq!( metadata.get_description().expect("missing description"), description ); assert_eq!(metadata.get_license().expect("missing license"), license); let links = metadata.get_links().expect("missing links"); assert_eq!(links.len(), 3); assert_eq!( links .iter() .find(|link| link.ty == LinkType::Documentation) .expect("missing documentation") .value, documentation ); assert_eq!( links .iter() .find(|link| link.ty == LinkType::Homepage) .expect("missing homepage") .value, homepage ); assert_eq!( links .iter() .find(|link| link.ty == LinkType::Repository) .expect("missing repository") .value, repository ); Ok(()) }