@verdaccio/e2e-cli 2.10.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +1591 -0
- package/Cargo.toml +19 -0
- package/bin/e2e-cli.js +26 -6
- package/build/bin/verdaccio-e2e +0 -0
- package/build/cjs/index.cjs +11 -166
- package/build/esm/index.js +10 -153
- package/build/index.d.ts +15 -6
- package/package.json +14 -16
- package/scripts/build-js-package.mjs +25 -0
- package/src/e2e_tests/audit.rs +51 -0
- package/src/e2e_tests/ci.rs +32 -0
- package/src/e2e_tests/deprecate.rs +64 -0
- package/src/e2e_tests/dist_tags.rs +56 -0
- package/src/e2e_tests/info.rs +43 -0
- package/src/e2e_tests/install.rs +27 -0
- package/src/e2e_tests/login.rs +64 -0
- package/src/e2e_tests/mod.rs +104 -0
- package/src/e2e_tests/ping.rs +33 -0
- package/src/e2e_tests/publish.rs +68 -0
- package/src/e2e_tests/search.rs +14 -0
- package/src/e2e_tests/unpublish.rs +37 -0
- package/src/main.rs +1411 -0
- package/src/scenarios/install_multiple_deps.rs +99 -0
- package/src/scenarios/minimum_release_age.rs +45 -0
- package/src/scenarios/mod.rs +11 -0
- package/build/adapters/adapter.d.ts +0 -1
- package/build/adapters/bun.d.ts +0 -2
- package/build/adapters/deno.d.ts +0 -2
- package/build/adapters/index.d.ts +0 -6
- package/build/adapters/npm.d.ts +0 -2
- package/build/adapters/pnpm.d.ts +0 -2
- package/build/adapters/yarn-classic.d.ts +0 -2
- package/build/adapters/yarn-modern.d.ts +0 -2
- package/build/cjs/_virtual/_rolldown/runtime.cjs +0 -23
- package/build/cjs/adapters/bun.cjs +0 -63
- package/build/cjs/adapters/bun.cjs.map +0 -1
- package/build/cjs/adapters/deno.cjs +0 -58
- package/build/cjs/adapters/deno.cjs.map +0 -1
- package/build/cjs/adapters/index.cjs +0 -6
- package/build/cjs/adapters/npm.cjs +0 -75
- package/build/cjs/adapters/npm.cjs.map +0 -1
- package/build/cjs/adapters/pnpm.cjs +0 -104
- package/build/cjs/adapters/pnpm.cjs.map +0 -1
- package/build/cjs/adapters/yarn-classic.cjs +0 -98
- package/build/cjs/adapters/yarn-classic.cjs.map +0 -1
- package/build/cjs/adapters/yarn-modern.cjs +0 -206
- package/build/cjs/adapters/yarn-modern.cjs.map +0 -1
- package/build/cjs/index.cjs.map +0 -1
- package/build/cjs/reporter.cjs +0 -113
- package/build/cjs/reporter.cjs.map +0 -1
- package/build/cjs/runner.cjs +0 -141
- package/build/cjs/runner.cjs.map +0 -1
- package/build/cjs/scenarios/index.cjs +0 -8
- package/build/cjs/scenarios/index.cjs.map +0 -1
- package/build/cjs/scenarios/install-multiple-deps.cjs +0 -116
- package/build/cjs/scenarios/install-multiple-deps.cjs.map +0 -1
- package/build/cjs/scenarios/minimum-release-age.cjs +0 -112
- package/build/cjs/scenarios/minimum-release-age.cjs.map +0 -1
- package/build/cjs/tests/audit.cjs +0 -47
- package/build/cjs/tests/audit.cjs.map +0 -1
- package/build/cjs/tests/ci.cjs +0 -83
- package/build/cjs/tests/ci.cjs.map +0 -1
- package/build/cjs/tests/deprecate.cjs +0 -107
- package/build/cjs/tests/deprecate.cjs.map +0 -1
- package/build/cjs/tests/dist-tags.cjs +0 -43
- package/build/cjs/tests/dist-tags.cjs.map +0 -1
- package/build/cjs/tests/index.cjs +0 -33
- package/build/cjs/tests/index.cjs.map +0 -1
- package/build/cjs/tests/info.cjs +0 -41
- package/build/cjs/tests/info.cjs.map +0 -1
- package/build/cjs/tests/install.cjs +0 -27
- package/build/cjs/tests/install.cjs.map +0 -1
- package/build/cjs/tests/login.cjs +0 -117
- package/build/cjs/tests/login.cjs.map +0 -1
- package/build/cjs/tests/ping.cjs +0 -30
- package/build/cjs/tests/ping.cjs.map +0 -1
- package/build/cjs/tests/publish.cjs +0 -37
- package/build/cjs/tests/publish.cjs.map +0 -1
- package/build/cjs/tests/search.cjs +0 -19
- package/build/cjs/tests/search.cjs.map +0 -1
- package/build/cjs/tests/unpublish.cjs +0 -40
- package/build/cjs/tests/unpublish.cjs.map +0 -1
- package/build/cjs/utils/process.cjs +0 -85
- package/build/cjs/utils/process.cjs.map +0 -1
- package/build/cjs/utils/project.cjs +0 -55
- package/build/cjs/utils/project.cjs.map +0 -1
- package/build/cjs/utils/registry-client.cjs +0 -56
- package/build/cjs/utils/registry-client.cjs.map +0 -1
- package/build/esm/adapters/bun.js +0 -61
- package/build/esm/adapters/bun.js.map +0 -1
- package/build/esm/adapters/deno.js +0 -56
- package/build/esm/adapters/deno.js.map +0 -1
- package/build/esm/adapters/index.js +0 -7
- package/build/esm/adapters/npm.js +0 -73
- package/build/esm/adapters/npm.js.map +0 -1
- package/build/esm/adapters/pnpm.js +0 -102
- package/build/esm/adapters/pnpm.js.map +0 -1
- package/build/esm/adapters/yarn-classic.js +0 -96
- package/build/esm/adapters/yarn-classic.js.map +0 -1
- package/build/esm/adapters/yarn-modern.js +0 -203
- package/build/esm/adapters/yarn-modern.js.map +0 -1
- package/build/esm/index.js.map +0 -1
- package/build/esm/reporter.js +0 -107
- package/build/esm/reporter.js.map +0 -1
- package/build/esm/runner.js +0 -138
- package/build/esm/runner.js.map +0 -1
- package/build/esm/scenarios/index.js +0 -8
- package/build/esm/scenarios/index.js.map +0 -1
- package/build/esm/scenarios/install-multiple-deps.js +0 -113
- package/build/esm/scenarios/install-multiple-deps.js.map +0 -1
- package/build/esm/scenarios/minimum-release-age.js +0 -109
- package/build/esm/scenarios/minimum-release-age.js.map +0 -1
- package/build/esm/tests/audit.js +0 -44
- package/build/esm/tests/audit.js.map +0 -1
- package/build/esm/tests/ci.js +0 -80
- package/build/esm/tests/ci.js.map +0 -1
- package/build/esm/tests/deprecate.js +0 -104
- package/build/esm/tests/deprecate.js.map +0 -1
- package/build/esm/tests/dist-tags.js +0 -41
- package/build/esm/tests/dist-tags.js.map +0 -1
- package/build/esm/tests/index.js +0 -33
- package/build/esm/tests/index.js.map +0 -1
- package/build/esm/tests/info.js +0 -39
- package/build/esm/tests/info.js.map +0 -1
- package/build/esm/tests/install.js +0 -25
- package/build/esm/tests/install.js.map +0 -1
- package/build/esm/tests/login.js +0 -113
- package/build/esm/tests/login.js.map +0 -1
- package/build/esm/tests/ping.js +0 -28
- package/build/esm/tests/ping.js.map +0 -1
- package/build/esm/tests/publish.js +0 -35
- package/build/esm/tests/publish.js.map +0 -1
- package/build/esm/tests/search.js +0 -17
- package/build/esm/tests/search.js.map +0 -1
- package/build/esm/tests/unpublish.js +0 -38
- package/build/esm/tests/unpublish.js.map +0 -1
- package/build/esm/utils/process.js +0 -82
- package/build/esm/utils/process.js.map +0 -1
- package/build/esm/utils/project.js +0 -50
- package/build/esm/utils/project.js.map +0 -1
- package/build/esm/utils/registry-client.js +0 -53
- package/build/esm/utils/registry-client.js.map +0 -1
- package/build/reporter.d.ts +0 -7
- package/build/runner.d.ts +0 -13
- package/build/scenarios/index.d.ts +0 -5
- package/build/scenarios/install-multiple-deps.d.ts +0 -2
- package/build/scenarios/minimum-release-age.d.ts +0 -11
- package/build/tests/audit.d.ts +0 -2
- package/build/tests/ci.d.ts +0 -2
- package/build/tests/deprecate.d.ts +0 -2
- package/build/tests/dist-tags.d.ts +0 -2
- package/build/tests/index.d.ts +0 -15
- package/build/tests/info.d.ts +0 -2
- package/build/tests/install.d.ts +0 -2
- package/build/tests/login.d.ts +0 -2
- package/build/tests/ping.d.ts +0 -2
- package/build/tests/publish.d.ts +0 -2
- package/build/tests/search.d.ts +0 -2
- package/build/tests/unpublish.d.ts +0 -2
- package/build/types.d.ts +0 -81
- package/build/utils/index.d.ts +0 -3
- package/build/utils/process.d.ts +0 -4
- package/build/utils/project.d.ts +0 -6
- package/build/utils/registry-client.d.ts +0 -15
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
use super::prelude::*;
|
|
2
|
+
|
|
3
|
+
pub(crate) fn test_dist_tags(ctx: &mut TestContext<'_>) -> Result<()> {
|
|
4
|
+
let pkg1 = format!("@foo/dt1-{}", ctx.run_id);
|
|
5
|
+
let tf1 = prepare_project(ctx, &pkg1, "1.0.0", BTreeMap::new(), BTreeMap::new())?;
|
|
6
|
+
publish_pkg(ctx, &tf1)?;
|
|
7
|
+
bump_version(ctx, &tf1, "minor")?;
|
|
8
|
+
publish_pkg_extra(ctx, &tf1, vec!["--tag".into(), "beta".into()])?;
|
|
9
|
+
let mut args = vec!["dist-tag".into(), "ls".into(), "--json".into()];
|
|
10
|
+
args.extend(registry_arg(&ctx.adapter, &ctx.registry_url));
|
|
11
|
+
let resp = exec_adapter(ctx, Some(&tf1), args)?;
|
|
12
|
+
assert_eq_str(
|
|
13
|
+
&normalize_dist_tag_list(&resp.stdout),
|
|
14
|
+
"beta: 1.1.0\nlatest: 1.0.0",
|
|
15
|
+
)?;
|
|
16
|
+
|
|
17
|
+
let pkg2 = format!("@verdaccio/dt2-{}", ctx.run_id);
|
|
18
|
+
let tf2 = prepare_project(ctx, &pkg2, "1.0.0", BTreeMap::new(), BTreeMap::new())?;
|
|
19
|
+
publish_pkg(ctx, &tf2)?;
|
|
20
|
+
bump_version(ctx, &tf2, "minor")?;
|
|
21
|
+
publish_pkg_extra(ctx, &tf2, vec!["--tag".into(), "beta".into()])?;
|
|
22
|
+
let mut args = vec![
|
|
23
|
+
"dist-tag".into(),
|
|
24
|
+
"rm".into(),
|
|
25
|
+
format!("{pkg2}@1.1.0"),
|
|
26
|
+
"beta".into(),
|
|
27
|
+
];
|
|
28
|
+
args.extend(registry_arg(&ctx.adapter, &ctx.registry_url));
|
|
29
|
+
let resp = exec_adapter(ctx, Some(&tf2), args)?;
|
|
30
|
+
assert_eq_str(resp.stdout.trim(), &format!("-beta: {pkg2}@1.1.0"))?;
|
|
31
|
+
|
|
32
|
+
let pkg3 = format!("@verdaccio/dt3-{}", ctx.run_id);
|
|
33
|
+
let tf3 = prepare_project(ctx, &pkg3, "1.0.0", BTreeMap::new(), BTreeMap::new())?;
|
|
34
|
+
publish_pkg(ctx, &tf3)?;
|
|
35
|
+
bump_version(ctx, &tf3, "minor")?;
|
|
36
|
+
publish_pkg(ctx, &tf3)?;
|
|
37
|
+
let mut args = vec![
|
|
38
|
+
"dist-tag".into(),
|
|
39
|
+
"add".into(),
|
|
40
|
+
format!("{pkg3}@1.1.0"),
|
|
41
|
+
"alfa".into(),
|
|
42
|
+
];
|
|
43
|
+
args.extend(registry_arg(&ctx.adapter, &ctx.registry_url));
|
|
44
|
+
let resp = exec_adapter(ctx, Some(&tf3), args)?;
|
|
45
|
+
assert_eq_str(resp.stdout.trim(), &format!("+alfa: {pkg3}@1.1.0"))?;
|
|
46
|
+
Ok(())
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
fn normalize_dist_tag_list(output: &str) -> String {
|
|
50
|
+
output
|
|
51
|
+
.lines()
|
|
52
|
+
.map(str::trim)
|
|
53
|
+
.filter(|line| !line.is_empty())
|
|
54
|
+
.collect::<Vec<_>>()
|
|
55
|
+
.join("\n")
|
|
56
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
use super::prelude::*;
|
|
2
|
+
|
|
3
|
+
pub(crate) fn test_info(ctx: &mut TestContext<'_>) -> Result<()> {
|
|
4
|
+
let dir = create_temp_dir(ctx.state, "info-test")?
|
|
5
|
+
.path()
|
|
6
|
+
.to_path_buf();
|
|
7
|
+
fs::write(
|
|
8
|
+
dir.join("package.json"),
|
|
9
|
+
r#"{"name":"info-test","version":"1.0.0"}"#,
|
|
10
|
+
)?;
|
|
11
|
+
let mut args = vec!["info".into(), "verdaccio".into(), "--json".into()];
|
|
12
|
+
args.extend(registry_arg(&ctx.adapter, &ctx.registry_url));
|
|
13
|
+
let resp = exec_adapter(ctx, Some(&dir), args)?;
|
|
14
|
+
match ctx.adapter.kind {
|
|
15
|
+
AdapterType::YarnClassic => {
|
|
16
|
+
let found = resp.stdout.lines().any(|line| {
|
|
17
|
+
serde_json::from_str::<Value>(line)
|
|
18
|
+
.ok()
|
|
19
|
+
.and_then(|v| v.get("type").cloned())
|
|
20
|
+
.and_then(|v| v.as_str().map(|s| s == "inspect"))
|
|
21
|
+
.unwrap_or(false)
|
|
22
|
+
});
|
|
23
|
+
assert_true(
|
|
24
|
+
found,
|
|
25
|
+
"Expected yarn info NDJSON to contain an inspect entry",
|
|
26
|
+
)?;
|
|
27
|
+
}
|
|
28
|
+
AdapterType::Deno => assert_contains(&(resp.stdout + &resp.stderr), "verdaccio")?,
|
|
29
|
+
_ => {
|
|
30
|
+
let parsed = parse_info_json(&resp.stdout)?;
|
|
31
|
+
assert_eq_json(
|
|
32
|
+
parsed.get("name"),
|
|
33
|
+
"verdaccio",
|
|
34
|
+
"Expected package name verdaccio",
|
|
35
|
+
)?;
|
|
36
|
+
assert_true(
|
|
37
|
+
parsed.get("dependencies").is_some(),
|
|
38
|
+
"Expected dependencies to be defined",
|
|
39
|
+
)?;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
Ok(())
|
|
43
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
use super::prelude::*;
|
|
2
|
+
|
|
3
|
+
pub(crate) fn test_install(ctx: &mut TestContext<'_>) -> Result<()> {
|
|
4
|
+
let mut deps = BTreeMap::new();
|
|
5
|
+
deps.insert("react".into(), "18.2.0".into());
|
|
6
|
+
let temp = prepare_project(
|
|
7
|
+
ctx,
|
|
8
|
+
&format!("install-test-{}", ctx.run_id),
|
|
9
|
+
"1.0.0",
|
|
10
|
+
deps,
|
|
11
|
+
BTreeMap::new(),
|
|
12
|
+
)?;
|
|
13
|
+
let mut args = vec!["install".into()];
|
|
14
|
+
if ctx.adapter.kind == AdapterType::Npm {
|
|
15
|
+
args.push("--json".into());
|
|
16
|
+
}
|
|
17
|
+
args.extend(registry_arg(&ctx.adapter, &ctx.registry_url));
|
|
18
|
+
let resp = exec_adapter(ctx, Some(&temp), args)?;
|
|
19
|
+
if ctx.adapter.kind == AdapterType::Npm {
|
|
20
|
+
let parsed: Value = serde_json::from_str(&resp.stdout)?;
|
|
21
|
+
assert_true(
|
|
22
|
+
parsed.get("added").is_some(),
|
|
23
|
+
"Expected \"added\" field in install response",
|
|
24
|
+
)?;
|
|
25
|
+
}
|
|
26
|
+
Ok(())
|
|
27
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
use super::prelude::*;
|
|
2
|
+
|
|
3
|
+
pub(crate) fn test_login(ctx: &mut TestContext<'_>) -> Result<()> {
|
|
4
|
+
if ctx.adapter.kind != AdapterType::YarnModern {
|
|
5
|
+
return Ok(());
|
|
6
|
+
}
|
|
7
|
+
let user1 = format!("login-a-{}", ctx.run_id);
|
|
8
|
+
let password1 = "test-password-123";
|
|
9
|
+
let email1 = format!("{user1}@test.example.com");
|
|
10
|
+
sub_test(ctx, "create new user + whoami", |ctx| {
|
|
11
|
+
let tf = prepare_login_project(ctx, &format!("verdaccio-login1-{}", ctx.run_id))?;
|
|
12
|
+
let login = yarn_login(ctx, &tf, &user1, password1, &email1)?;
|
|
13
|
+
assert_true(
|
|
14
|
+
login.stdout.contains("Logged in") || login.stdout.contains("token saved"),
|
|
15
|
+
"Expected login success message",
|
|
16
|
+
)?;
|
|
17
|
+
assert_contains(&yarn_whoami(ctx, &tf)?, &user1)
|
|
18
|
+
})?;
|
|
19
|
+
sub_test(ctx, "login existing user", |ctx| {
|
|
20
|
+
let tf = prepare_login_project(ctx, &format!("verdaccio-login2-{}", ctx.run_id))?;
|
|
21
|
+
let login = yarn_login(ctx, &tf, &user1, password1, &email1)?;
|
|
22
|
+
assert_true(
|
|
23
|
+
login.stdout.contains("Logged in") || login.stdout.contains("token saved"),
|
|
24
|
+
"Expected login success message",
|
|
25
|
+
)?;
|
|
26
|
+
assert_contains(&yarn_whoami(ctx, &tf)?, &user1)
|
|
27
|
+
})?;
|
|
28
|
+
sub_test(ctx, "wrong password fails", |ctx| {
|
|
29
|
+
let tf = prepare_login_project(ctx, &format!("verdaccio-login3-{}", ctx.run_id))?;
|
|
30
|
+
let failed = yarn_login(ctx, &tf, &user1, "wrong-password", &email1).is_err();
|
|
31
|
+
assert_true(failed, "Login with wrong password should have failed")
|
|
32
|
+
})?;
|
|
33
|
+
sub_test(ctx, "login then publish", |ctx| {
|
|
34
|
+
let pkg = format!("@verdaccio/login-pub-{}", ctx.run_id);
|
|
35
|
+
let tf = create_temp_dir(ctx.state, &format!("login-pub-{}", ctx.run_id))?
|
|
36
|
+
.path()
|
|
37
|
+
.to_path_buf();
|
|
38
|
+
fs::write(
|
|
39
|
+
tf.join(".yarnrc.yml"),
|
|
40
|
+
yarn_config(&ctx.registry_url, None, ctx.adapter.yarn_major)?,
|
|
41
|
+
)?;
|
|
42
|
+
fs::write(
|
|
43
|
+
tf.join("package.json"),
|
|
44
|
+
package_json(&pkg, "1.0.0", BTreeMap::new(), BTreeMap::new())?,
|
|
45
|
+
)?;
|
|
46
|
+
fs::write(tf.join("README.md"), readme(&pkg))?;
|
|
47
|
+
import_plugin(ctx, &tf, "npm-login")?;
|
|
48
|
+
yarn_login(ctx, &tf, &user1, password1, &email1)?;
|
|
49
|
+
exec_adapter(ctx, Some(&tf), vec!["install".into()])?;
|
|
50
|
+
let published = exec_adapter(ctx, Some(&tf), vec!["publish".into()])?;
|
|
51
|
+
assert_contains(&published.stdout, "Package archive published")
|
|
52
|
+
})?;
|
|
53
|
+
sub_test(ctx, "switch users", |ctx| {
|
|
54
|
+
let user2 = format!("login-b-{}", ctx.run_id);
|
|
55
|
+
let password2 = "other-password-456";
|
|
56
|
+
let email2 = format!("{user2}@test.example.com");
|
|
57
|
+
let tf = prepare_login_project(ctx, &format!("verdaccio-login5-{}", ctx.run_id))?;
|
|
58
|
+
yarn_login(ctx, &tf, &user1, password1, &email1)?;
|
|
59
|
+
assert_contains(&yarn_whoami(ctx, &tf)?, &user1)?;
|
|
60
|
+
yarn_login(ctx, &tf, &user2, password2, &email2)?;
|
|
61
|
+
assert_contains(&yarn_whoami(ctx, &tf)?, &user2)
|
|
62
|
+
})?;
|
|
63
|
+
Ok(())
|
|
64
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
pub(crate) mod audit;
|
|
2
|
+
pub(crate) mod ci;
|
|
3
|
+
pub(crate) mod deprecate;
|
|
4
|
+
pub(crate) mod dist_tags;
|
|
5
|
+
pub(crate) mod info;
|
|
6
|
+
pub(crate) mod install;
|
|
7
|
+
pub(crate) mod login;
|
|
8
|
+
pub(crate) mod ping;
|
|
9
|
+
pub(crate) mod publish;
|
|
10
|
+
pub(crate) mod search;
|
|
11
|
+
pub(crate) mod unpublish;
|
|
12
|
+
|
|
13
|
+
pub(crate) mod prelude {
|
|
14
|
+
pub(crate) use anyhow::{Context, Result};
|
|
15
|
+
pub(crate) use reqwest::blocking::Client;
|
|
16
|
+
pub(crate) use serde_json::Value;
|
|
17
|
+
pub(crate) use std::collections::BTreeMap;
|
|
18
|
+
pub(crate) use std::fs;
|
|
19
|
+
|
|
20
|
+
pub(crate) use crate::*;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
pub(crate) fn all_tests() -> Vec<crate::TestDefinition> {
|
|
24
|
+
vec![
|
|
25
|
+
crate::TestDefinition {
|
|
26
|
+
name: "publish",
|
|
27
|
+
requires: &["publish"],
|
|
28
|
+
applies_to: |_| true,
|
|
29
|
+
run: publish::test_publish,
|
|
30
|
+
},
|
|
31
|
+
crate::TestDefinition {
|
|
32
|
+
name: "install",
|
|
33
|
+
requires: &["install"],
|
|
34
|
+
applies_to: |_| true,
|
|
35
|
+
run: install::test_install,
|
|
36
|
+
},
|
|
37
|
+
crate::TestDefinition {
|
|
38
|
+
name: "ci",
|
|
39
|
+
requires: &["install"],
|
|
40
|
+
applies_to: |_| true,
|
|
41
|
+
run: ci::test_ci,
|
|
42
|
+
},
|
|
43
|
+
crate::TestDefinition {
|
|
44
|
+
name: "audit",
|
|
45
|
+
requires: &["audit"],
|
|
46
|
+
applies_to: |_| true,
|
|
47
|
+
run: audit::test_audit,
|
|
48
|
+
},
|
|
49
|
+
crate::TestDefinition {
|
|
50
|
+
name: "info",
|
|
51
|
+
requires: &["info"],
|
|
52
|
+
applies_to: |_| true,
|
|
53
|
+
run: info::test_info,
|
|
54
|
+
},
|
|
55
|
+
crate::TestDefinition {
|
|
56
|
+
name: "deprecate",
|
|
57
|
+
requires: &["deprecate"],
|
|
58
|
+
applies_to: |_| true,
|
|
59
|
+
run: deprecate::test_deprecate,
|
|
60
|
+
},
|
|
61
|
+
crate::TestDefinition {
|
|
62
|
+
name: "dist-tags",
|
|
63
|
+
requires: &["dist-tag"],
|
|
64
|
+
applies_to: |_| true,
|
|
65
|
+
run: dist_tags::test_dist_tags,
|
|
66
|
+
},
|
|
67
|
+
crate::TestDefinition {
|
|
68
|
+
name: "login",
|
|
69
|
+
requires: &["login"],
|
|
70
|
+
applies_to: |_| true,
|
|
71
|
+
run: login::test_login,
|
|
72
|
+
},
|
|
73
|
+
crate::TestDefinition {
|
|
74
|
+
name: "ping",
|
|
75
|
+
requires: &["ping"],
|
|
76
|
+
applies_to: |_| true,
|
|
77
|
+
run: ping::test_ping,
|
|
78
|
+
},
|
|
79
|
+
crate::TestDefinition {
|
|
80
|
+
name: "search",
|
|
81
|
+
requires: &["search"],
|
|
82
|
+
applies_to: |_| true,
|
|
83
|
+
run: search::test_search,
|
|
84
|
+
},
|
|
85
|
+
crate::TestDefinition {
|
|
86
|
+
name: "unpublish",
|
|
87
|
+
requires: &["unpublish"],
|
|
88
|
+
applies_to: |_| true,
|
|
89
|
+
run: unpublish::test_unpublish,
|
|
90
|
+
},
|
|
91
|
+
crate::TestDefinition {
|
|
92
|
+
name: "scenario:install-multiple-deps",
|
|
93
|
+
requires: &["publish", "install", "info"],
|
|
94
|
+
applies_to: |_| true,
|
|
95
|
+
run: crate::scenarios::install_multiple_deps::scenario_install_multiple_deps,
|
|
96
|
+
},
|
|
97
|
+
crate::TestDefinition {
|
|
98
|
+
name: "scenario:minimum-release-age",
|
|
99
|
+
requires: &["publish", "install"],
|
|
100
|
+
applies_to: crate::is_pnpm_minimum_release_age_capable,
|
|
101
|
+
run: crate::scenarios::minimum_release_age::scenario_minimum_release_age,
|
|
102
|
+
},
|
|
103
|
+
]
|
|
104
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
use super::prelude::*;
|
|
2
|
+
|
|
3
|
+
pub(crate) fn test_ping(ctx: &mut TestContext<'_>) -> Result<()> {
|
|
4
|
+
let cwd = if ctx.adapter.kind == AdapterType::YarnModern {
|
|
5
|
+
let temp = prepare_project(
|
|
6
|
+
ctx,
|
|
7
|
+
&format!("verdaccio-ping-{}", ctx.run_id),
|
|
8
|
+
"1.0.0",
|
|
9
|
+
BTreeMap::new(),
|
|
10
|
+
BTreeMap::new(),
|
|
11
|
+
)?;
|
|
12
|
+
import_plugin(ctx, &temp, "npm-ping")?;
|
|
13
|
+
Some(temp)
|
|
14
|
+
} else {
|
|
15
|
+
None
|
|
16
|
+
};
|
|
17
|
+
let mut args = vec!["ping".into()];
|
|
18
|
+
if ctx.adapter.kind != AdapterType::YarnModern {
|
|
19
|
+
args.push("--json".into());
|
|
20
|
+
}
|
|
21
|
+
args.extend(registry_arg(&ctx.adapter, &ctx.registry_url));
|
|
22
|
+
let resp = exec_adapter(ctx, cwd.as_deref(), args)?;
|
|
23
|
+
if ctx.adapter.kind != AdapterType::YarnModern {
|
|
24
|
+
let parsed: Value = serde_json::from_str(&resp.stdout)?;
|
|
25
|
+
let expected_registry = format!("{}/", ctx.registry_url);
|
|
26
|
+
assert_eq_json(
|
|
27
|
+
parsed.get("registry"),
|
|
28
|
+
expected_registry.as_str(),
|
|
29
|
+
"Registry mismatch",
|
|
30
|
+
)?;
|
|
31
|
+
}
|
|
32
|
+
Ok(())
|
|
33
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
use super::prelude::*;
|
|
2
|
+
|
|
3
|
+
pub(crate) fn test_publish(ctx: &mut TestContext<'_>) -> Result<()> {
|
|
4
|
+
let packages = vec![
|
|
5
|
+
format!("verdaccio-memory-{}", ctx.run_id),
|
|
6
|
+
format!("verdaccio-{}", ctx.run_id),
|
|
7
|
+
format!("@verdaccio/foo-{}", ctx.run_id),
|
|
8
|
+
format!("@verdaccio/some-foo-{}", ctx.run_id),
|
|
9
|
+
];
|
|
10
|
+
for pkg_name in packages {
|
|
11
|
+
let temp = prepare_project(ctx, &pkg_name, "1.0.0", BTreeMap::new(), BTreeMap::new())?;
|
|
12
|
+
if ctx.adapter.kind == AdapterType::YarnModern {
|
|
13
|
+
exec_adapter(ctx, Some(&temp), vec!["install".into()])?;
|
|
14
|
+
}
|
|
15
|
+
let mut args = vec!["publish".into(), "--json".into()];
|
|
16
|
+
args.extend(registry_arg(&ctx.adapter, &ctx.registry_url));
|
|
17
|
+
let resp = exec_adapter(ctx, Some(&temp), args)?;
|
|
18
|
+
match ctx.adapter.kind {
|
|
19
|
+
AdapterType::YarnModern => assert_contains(&resp.stdout, "Package archive published")?,
|
|
20
|
+
AdapterType::YarnClassic => {
|
|
21
|
+
assert_true(!resp.stdout.is_empty(), "Expected publish output")?
|
|
22
|
+
}
|
|
23
|
+
AdapterType::Bun => {}
|
|
24
|
+
_ => {
|
|
25
|
+
if let Ok(parsed) = serde_json::from_str::<Value>(&resp.stdout) {
|
|
26
|
+
let expected_id = format!("{pkg_name}@1.0.0");
|
|
27
|
+
let published_name = parsed.get("name").and_then(Value::as_str);
|
|
28
|
+
let published_id = parsed.get("id").and_then(Value::as_str);
|
|
29
|
+
if published_name.is_some() || published_id.is_some() {
|
|
30
|
+
assert_true(
|
|
31
|
+
published_name == Some(pkg_name.as_str())
|
|
32
|
+
|| published_id == Some(expected_id.as_str()),
|
|
33
|
+
&format!(
|
|
34
|
+
"Expected package name \"{pkg_name}\" or id \"{expected_id}\""
|
|
35
|
+
),
|
|
36
|
+
)?;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
assert_published(ctx, &pkg_name)?;
|
|
42
|
+
}
|
|
43
|
+
Ok(())
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
fn assert_published(ctx: &TestContext<'_>, pkg_name: &str) -> Result<()> {
|
|
47
|
+
let encoded = pkg_name.replace('/', "%2F");
|
|
48
|
+
let response = Client::new()
|
|
49
|
+
.get(format!(
|
|
50
|
+
"{}/{}",
|
|
51
|
+
ctx.registry_url.trim_end_matches('/'),
|
|
52
|
+
encoded
|
|
53
|
+
))
|
|
54
|
+
.bearer_auth(&ctx.token)
|
|
55
|
+
.send()
|
|
56
|
+
.with_context(|| format!("failed to fetch published package {pkg_name}"))?;
|
|
57
|
+
let status = response.status();
|
|
58
|
+
let body: Value = response.json().unwrap_or(Value::Null);
|
|
59
|
+
assert_true(
|
|
60
|
+
status.is_success(),
|
|
61
|
+
&format!("Expected published package {pkg_name}, got {status} {body}"),
|
|
62
|
+
)?;
|
|
63
|
+
assert_eq_json(
|
|
64
|
+
body.get("name"),
|
|
65
|
+
pkg_name,
|
|
66
|
+
"Expected published registry package name",
|
|
67
|
+
)
|
|
68
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
use super::prelude::*;
|
|
2
|
+
|
|
3
|
+
pub(crate) fn test_search(ctx: &mut TestContext<'_>) -> Result<()> {
|
|
4
|
+
let mut args = vec!["search".into(), "@verdaccio/cli".into(), "--json".into()];
|
|
5
|
+
args.extend(registry_arg(&ctx.adapter, &ctx.registry_url));
|
|
6
|
+
let resp = exec_adapter(ctx, None, args)?;
|
|
7
|
+
let parsed: Value = serde_json::from_str(&resp.stdout)?;
|
|
8
|
+
let found = parsed
|
|
9
|
+
.as_array()
|
|
10
|
+
.unwrap_or(&Vec::new())
|
|
11
|
+
.iter()
|
|
12
|
+
.any(|item| item.get("name").and_then(Value::as_str) == Some("@verdaccio/cli"));
|
|
13
|
+
assert_true(found, "Expected to find @verdaccio/cli in search results")
|
|
14
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
use super::prelude::*;
|
|
2
|
+
|
|
3
|
+
pub(crate) fn test_unpublish(ctx: &mut TestContext<'_>) -> Result<()> {
|
|
4
|
+
let pkg = format!("@verdaccio/unpub1-{}", ctx.run_id);
|
|
5
|
+
let temp = prepare_project(ctx, &pkg, "1.0.0", BTreeMap::new(), BTreeMap::new())?;
|
|
6
|
+
for bump in ["minor", "minor", "major"] {
|
|
7
|
+
publish_pkg(ctx, &temp)?;
|
|
8
|
+
bump_version(ctx, &temp, bump)?;
|
|
9
|
+
}
|
|
10
|
+
publish_pkg(ctx, &temp)?;
|
|
11
|
+
let mut args = vec![
|
|
12
|
+
"unpublish".into(),
|
|
13
|
+
pkg.clone(),
|
|
14
|
+
"--force".into(),
|
|
15
|
+
"--loglevel=info".into(),
|
|
16
|
+
"--json".into(),
|
|
17
|
+
];
|
|
18
|
+
args.extend(registry_arg(&ctx.adapter, &ctx.registry_url));
|
|
19
|
+
let resp = exec_adapter(ctx, Some(&temp), args)?;
|
|
20
|
+
assert_contains(&resp.stdout, &pkg)?;
|
|
21
|
+
|
|
22
|
+
let pkg2 = format!("@verdaccio/unpub2-{}", ctx.run_id);
|
|
23
|
+
let temp2 = prepare_project(ctx, &pkg2, "1.0.0", BTreeMap::new(), BTreeMap::new())?;
|
|
24
|
+
publish_pkg(ctx, &temp2)?;
|
|
25
|
+
bump_version(ctx, &temp2, "minor")?;
|
|
26
|
+
publish_pkg(ctx, &temp2)?;
|
|
27
|
+
let mut args = vec![
|
|
28
|
+
"unpublish".into(),
|
|
29
|
+
format!("{pkg2}@1.0.0"),
|
|
30
|
+
"--force".into(),
|
|
31
|
+
"--loglevel=info".into(),
|
|
32
|
+
"--json".into(),
|
|
33
|
+
];
|
|
34
|
+
args.extend(registry_arg(&ctx.adapter, &ctx.registry_url));
|
|
35
|
+
let resp = exec_adapter(ctx, Some(&temp2), args)?;
|
|
36
|
+
assert_contains(&resp.stdout, &pkg2)
|
|
37
|
+
}
|