Skip to content

Commit 949c958

Browse files
committed
refactor: contract fixtures and simplification
1 parent febcc1d commit 949c958

9 files changed

Lines changed: 358 additions & 389 deletions

File tree

tests/common.rs

Lines changed: 226 additions & 237 deletions
Large diffs are not rendered by default.

tests/tools/build/contract.rs

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,48 @@
1-
use crate::common::{is_error, is_success, text, Contract, TestContext};
1+
use crate::common::{is_error, is_success, text, TestEnv};
22
use anyhow::Result;
33
use pop_mcp_server::tools::build::contract::{build_contract, BuildContractParams};
4+
use pop_mcp_server::tools::new::contract::{create_contract, CreateContractParams};
45

56
#[test]
67
fn build_contract_nonexistent_path_fails() -> Result<()> {
7-
let ctx = TestContext::new()?;
8-
let executor = ctx.executor()?;
8+
let env = TestEnv::new()?;
99
let params = BuildContractParams {
1010
path: "/nonexistent/path/to/contract".to_string(),
1111
release: None,
1212
};
1313

14-
let result = build_contract(&executor, params)?;
14+
let result = build_contract(env.executor(), params)?;
1515
assert!(is_error(&result));
1616
assert!(text(&result)?.contains("Build failed"));
1717
Ok(())
1818
}
1919

2020
#[test]
2121
fn build_contract_creates_ink_artifacts() -> Result<()> {
22-
let ctx = TestContext::new()?;
23-
let executor = ctx.executor()?;
24-
let contract = Contract::with_context(ctx, &executor, "build_test")?;
22+
let env = TestEnv::new()?;
2523

26-
let build_params = BuildContractParams {
27-
path: contract.path.to_string_lossy().to_string(),
28-
release: None,
29-
};
24+
// Create a fresh contract
25+
create_contract(
26+
env.executor(),
27+
CreateContractParams {
28+
name: "build_test".to_string(),
29+
template: "standard".to_string(),
30+
},
31+
)?;
3032

31-
let result = build_contract(&executor, build_params)?;
32-
assert!(is_success(&result));
33+
let contract_path = env.workdir().join("build_test");
3334

34-
let output = text(&result)?;
35-
assert!(output.contains("Build successful"));
35+
// Build it
36+
let result = build_contract(
37+
env.executor(),
38+
BuildContractParams {
39+
path: contract_path.display().to_string(),
40+
release: None,
41+
},
42+
)?;
3643

37-
// Verify build artifacts exist
38-
assert!(contract.path.join("target/ink").exists());
44+
assert!(is_success(&result));
45+
assert!(text(&result)?.contains("Build successful"));
46+
assert!(contract_path.join("target/ink").exists());
3947
Ok(())
4048
}

tests/tools/call/contract.rs

Lines changed: 52 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
use crate::common::{is_error, is_success, text, Contract, TestContext, DEFAULT_SURI};
2-
use anyhow::{anyhow, Result};
1+
use crate::common::{is_error, is_success, text, Contract, InkNode, TestEnv, DEFAULT_SURI};
2+
use anyhow::Result;
33
use pop_mcp_server::tools::call::contract::{call_contract, CallContractParams};
44

55
#[test]
66
fn call_contract_nonexistent_path_fails() -> Result<()> {
7-
let ctx = TestContext::new()?;
8-
let executor = ctx.executor()?;
9-
10-
// Call with a non-existent contract path - this will definitely fail
7+
let env = TestEnv::new()?;
118
let params = CallContractParams {
129
path: "/nonexistent/path/to/contract".to_string(),
1310
contract: "0x0000000000000000000000000000000000000000".to_string(),
@@ -19,73 +16,69 @@ fn call_contract_nonexistent_path_fails() -> Result<()> {
1916
url: None,
2017
};
2118

22-
let result = call_contract(&executor, params)?;
19+
let result = call_contract(env.executor(), params)?;
2320
assert!(is_error(&result));
2421
assert!(text(&result)?.contains("Contract call failed"));
2522
Ok(())
2623
}
2724

2825
#[test]
2926
fn call_contract_get_and_flip_mutates_state() -> Result<()> {
30-
let ctx = TestContext::new()?;
31-
let executor = ctx.executor()?;
32-
33-
let mut contract = Contract::with_context(ctx, &executor, "call_test")?;
34-
contract.build(&executor)?;
35-
contract.deploy(&executor, Some("new"), Some("false"))?;
36-
let addr = contract
37-
.address
38-
.as_ref()
39-
.ok_or_else(|| anyhow!("Missing contract address after deploy"))?
40-
.to_string();
41-
let node_url = contract
42-
.node_url()
43-
.ok_or_else(|| anyhow!("Missing node URL after deploy"))?
44-
.to_string();
27+
let env = TestEnv::new()?;
28+
let mut contract = Contract::new()?;
29+
contract.deploy("new", "false")?;
4530

46-
// Initial get - should return false (initial state)
47-
let params = CallContractParams {
48-
path: contract.path.to_string_lossy().to_string(),
49-
contract: addr.clone(),
50-
message: "get".to_string(),
51-
args: None,
52-
value: None,
53-
execute: None,
54-
suri: Some(DEFAULT_SURI.to_string()),
55-
url: Some(node_url.clone()),
56-
};
31+
let url = InkNode::url()?.to_string();
32+
let addr = contract.address().to_string();
33+
let path = contract.path.display().to_string();
5734

58-
let result = call_contract(&executor, params)?;
35+
// Initial get - should return false
36+
let result = call_contract(
37+
env.executor(),
38+
CallContractParams {
39+
path: path.clone(),
40+
contract: addr.clone(),
41+
message: "get".to_string(),
42+
args: None,
43+
value: None,
44+
execute: None,
45+
suri: Some(DEFAULT_SURI.to_string()),
46+
url: Some(url.clone()),
47+
},
48+
)?;
5949
assert!(is_success(&result));
6050
assert!(text(&result)?.contains("false"));
6151

62-
// Call flip to mutate state
63-
let flip_params = CallContractParams {
64-
path: contract.path.to_string_lossy().to_string(),
65-
contract: addr.clone(),
66-
message: "flip".to_string(),
67-
args: None,
68-
value: None,
69-
execute: Some(true),
70-
suri: Some(DEFAULT_SURI.to_string()),
71-
url: Some(node_url.clone()),
72-
};
73-
let flip_result = call_contract(&executor, flip_params)?;
52+
// Flip to mutate state
53+
let flip_result = call_contract(
54+
env.executor(),
55+
CallContractParams {
56+
path: path.clone(),
57+
contract: addr.clone(),
58+
message: "flip".to_string(),
59+
args: None,
60+
value: None,
61+
execute: Some(true),
62+
suri: Some(DEFAULT_SURI.to_string()),
63+
url: Some(url.clone()),
64+
},
65+
)?;
7466
assert!(is_success(&flip_result));
75-
assert!(!text(&flip_result)?.is_empty());
7667

77-
// Call get again - should now return true
78-
let get_params = CallContractParams {
79-
path: contract.path.to_string_lossy().to_string(),
80-
contract: addr,
81-
message: "get".to_string(),
82-
args: None,
83-
value: None,
84-
execute: None,
85-
suri: Some(DEFAULT_SURI.to_string()),
86-
url: Some(node_url),
87-
};
88-
let get_result = call_contract(&executor, get_params)?;
68+
// Get again - should return true
69+
let get_result = call_contract(
70+
env.executor(),
71+
CallContractParams {
72+
path,
73+
contract: addr,
74+
message: "get".to_string(),
75+
args: None,
76+
value: None,
77+
execute: None,
78+
suri: Some(DEFAULT_SURI.to_string()),
79+
url: Some(url),
80+
},
81+
)?;
8982
assert!(is_success(&get_result));
9083
assert!(text(&get_result)?.contains("true"));
9184
Ok(())

tests/tools/clean.rs

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,46 @@
11
use crate::common::{
22
is_port_in_use, is_success, parse_pids, text, texts, wait_for_port_closed, ws_port_from_url,
3-
TestContext,
3+
TestEnv,
44
};
55
use anyhow::Result;
66
use pop_mcp_server::tools::clean::{clean_nodes, CleanNodesParams};
77
use pop_mcp_server::tools::up::chain::{up_ink_node, UpInkNodeParams};
88
use serial_test::serial;
99

10-
/// Ports used by this test (different from shared node on 9945/8546 and defaults 9944/8545).
10+
/// Ports for lifecycle test (different from shared node on 9945/8546).
1111
const TEST_INK_PORT: u16 = 9946;
1212
const TEST_ETH_PORT: u16 = 8547;
1313

14-
/// Test node lifecycle: launch ink-node, verify it's running, then clean it up.
15-
///
16-
/// This test covers both `up_ink_node` and `clean_nodes` functionality:
17-
/// - Verifies `up_ink_node` launches successfully and returns URL + PIDs
18-
/// - Verifies the node is actually listening on the expected port
19-
/// - Verifies `clean_nodes` terminates the node processes
20-
/// - Verifies the port is released after cleanup
21-
///
22-
/// Uses explicit ports (9944/8545) which don't conflict with the shared test node
23-
/// that runs on different ports (9945/8546).
2414
#[test]
2515
#[serial]
2616
fn up_ink_node_and_clean_nodes_lifecycle() -> Result<()> {
27-
let ctx = TestContext::new()?;
28-
let executor = ctx.executor()?;
17+
let env = TestEnv::new()?;
2918

30-
// Launch ink-node with explicit ports
19+
// Launch ink-node
3120
let result = up_ink_node(
32-
&executor,
21+
env.executor(),
3322
UpInkNodeParams {
3423
ink_node_port: Some(TEST_INK_PORT),
3524
eth_rpc_port: Some(TEST_ETH_PORT),
3625
},
3726
)?;
3827
if !is_success(&result) {
39-
let err = text(&result).unwrap_or_else(|_| "unknown error".to_string());
40-
panic!("up_ink_node failed: {}", err);
28+
panic!("up_ink_node failed: {}", text(&result)?);
4129
}
4230

43-
// Verify URL is returned and node is listening
31+
// Verify URL and node is listening
4432
let url = text(&result)?;
4533
assert!(url.starts_with("ws://"));
4634
let port = ws_port_from_url(&url)?;
4735
assert!(is_port_in_use(port));
4836

49-
// Parse PIDs from output
37+
// Parse PIDs
5038
let pid_output = texts(&result).join("\n");
5139
let pids = parse_pids(&pid_output)?;
5240
assert!(!pids.is_empty());
5341

54-
// Clean up the node
55-
let result = clean_nodes(&executor, CleanNodesParams { pids })?;
42+
// Clean up
43+
let result = clean_nodes(env.executor(), CleanNodesParams { pids })?;
5644
assert!(is_success(&result));
5745

5846
// Verify port is released

tests/tools/convert.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,28 @@
1-
use crate::common::{is_error, is_success, text, TestContext};
1+
use crate::common::{is_error, is_success, text, TestEnv};
22
use anyhow::Result;
33
use pop_mcp_server::tools::convert::{convert_address, ConvertAddressParams};
44

55
#[test]
66
fn convert_ethereum_to_substrate() -> Result<()> {
7-
let ctx = TestContext::new()?;
8-
let executor = ctx.executor()?;
7+
let env = TestEnv::new()?;
98
let params = ConvertAddressParams {
109
address: "0x742d35Cc6634C0532925a3b844Bc454e4438f44e".to_string(),
1110
};
1211

13-
let result = convert_address(&executor, params)?;
12+
let result = convert_address(env.executor(), params)?;
1413
assert!(is_success(&result));
1514
assert!(!text(&result)?.is_empty());
1615
Ok(())
1716
}
1817

1918
#[test]
2019
fn convert_substrate_to_ethereum() -> Result<()> {
21-
let ctx = TestContext::new()?;
22-
let executor = ctx.executor()?;
20+
let env = TestEnv::new()?;
2321
let params = ConvertAddressParams {
2422
address: "13dKz82CEiU7fKfhfQ5aLpdbXHApLfJH5Z6y2RTZpRwKiNhX".to_string(),
2523
};
2624

27-
let result = convert_address(&executor, params)?;
25+
let result = convert_address(env.executor(), params)?;
2826
assert!(is_success(&result));
2927
assert!(text(&result)?
3028
.to_lowercase()
@@ -34,13 +32,12 @@ fn convert_substrate_to_ethereum() -> Result<()> {
3432

3533
#[test]
3634
fn convert_invalid_address_fails() -> Result<()> {
37-
let ctx = TestContext::new()?;
38-
let executor = ctx.executor()?;
35+
let env = TestEnv::new()?;
3936
let params = ConvertAddressParams {
4037
address: "not_a_valid_address".to_string(),
4138
};
4239

43-
let result = convert_address(&executor, params)?;
40+
let result = convert_address(env.executor(), params)?;
4441
assert!(is_error(&result));
4542
assert!(text(&result)?.contains("Address conversion failed"));
4643
Ok(())

tests/tools/install.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
use crate::common::{is_success, TestContext};
1+
use crate::common::{is_success, TestEnv};
22
use anyhow::Result;
33
use pop_mcp_server::tools::install::{check_pop_installation, CheckPopInstallationParams};
44

55
#[test]
66
fn check_pop_installation_succeeds() -> Result<()> {
7-
let ctx = TestContext::new()?;
8-
let executor = ctx.executor()?;
9-
let result = check_pop_installation(&executor, CheckPopInstallationParams {})?;
7+
let env = TestEnv::new()?;
8+
let result = check_pop_installation(env.executor(), CheckPopInstallationParams {})?;
109
assert!(is_success(&result));
1110
Ok(())
1211
}

tests/tools/new/contract.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
1-
use crate::common::{is_error, is_success, text, TestContext};
1+
use crate::common::{is_error, is_success, text, TestEnv};
22
use anyhow::Result;
33
use pop_mcp_server::tools::new::contract::{create_contract, CreateContractParams};
44

55
#[test]
66
fn create_contract_standard_template_creates_files() -> Result<()> {
7-
let ctx = TestContext::new()?;
8-
let executor = ctx.executor()?;
7+
let env = TestEnv::new()?;
98

109
let contract_name = "test_contract";
11-
let contract_path = ctx.workdir.join(contract_name);
10+
let contract_path = env.workdir().join(contract_name);
1211

1312
let params = CreateContractParams {
1413
name: contract_name.to_string(),
1514
template: "standard".to_string(),
1615
};
1716

18-
let result = create_contract(&executor, params)?;
17+
let result = create_contract(env.executor(), params)?;
1918
assert!(is_success(&result));
2019

2120
let output = text(&result)?;
@@ -28,26 +27,24 @@ fn create_contract_standard_template_creates_files() -> Result<()> {
2827

2928
#[test]
3029
fn create_contract_invalid_name_with_hyphen_fails_validation() -> Result<()> {
31-
let ctx = TestContext::new()?;
32-
let executor = ctx.executor()?;
30+
let env = TestEnv::new()?;
3331
let params = CreateContractParams {
3432
name: "invalid-name".to_string(),
3533
template: "standard".to_string(),
3634
};
37-
let result = create_contract(&executor, params);
35+
let result = create_contract(env.executor(), params);
3836
assert!(result.is_err());
3937
Ok(())
4038
}
4139

4240
#[test]
4341
fn create_contract_nonexistent_template_fails() -> Result<()> {
44-
let ctx = TestContext::new()?;
45-
let executor = ctx.executor()?;
42+
let env = TestEnv::new()?;
4643
let params = CreateContractParams {
4744
name: "test_contract".to_string(),
4845
template: "non_existing".to_string(),
4946
};
50-
let result = create_contract(&executor, params)?;
47+
let result = create_contract(env.executor(), params)?;
5148
assert!(is_error(&result));
5249
assert!(text(&result)?.starts_with("Failed to create contract:"));
5350
Ok(())

0 commit comments

Comments
 (0)