Skip to content

Commit 691a029

Browse files
committed
fix: ensure root path is passed when posting to broker
1 parent df4e7fb commit 691a029

1 file changed

Lines changed: 81 additions & 5 deletions

File tree

rust/pact_verifier/src/pact_broker.rs

Lines changed: 81 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -528,14 +528,30 @@ impl HALClient {
528528
async fn send_document(&self, url: &str, body: &str, method: Method) -> Result<Value, PactBrokerError> {
529529
debug!("Sending JSON to {} using {}: {}", url, method, body);
530530

531-
let base_url = &self.url.parse::<Url>()?;
532-
let url = if url.starts_with("/") {
533-
base_url.join(url)?
531+
// Extract path from URL if it's absolute (like fetch_url does), then resolve with context path
532+
let mut path = if let Ok(link_as_url) = url.parse::<Url>() {
533+
// URL is absolute, extract path to use broker's original host and context path
534+
link_as_url.path().to_string()
534535
} else {
535-
let url = url.parse::<Url>()?;
536-
base_url.join(&url.path())?
536+
// URL is already a path (relative)
537+
url.to_string()
537538
};
538539

540+
// If we have a context path and the path doesn't already include it, prepend it
541+
let broker_url = self.url.parse::<Url>()?;
542+
let context_path = broker_url.path();
543+
if !context_path.is_empty() && context_path != "/" && path.starts_with("/") {
544+
let context_with_slash = format!("{}/", context_path);
545+
let path_matches_context = path == context_path || path.starts_with(&context_with_slash);
546+
if !path_matches_context {
547+
// Path doesn't include context path, prepend it
548+
let full_path = format!("{}{}", context_path, path);
549+
path = full_path;
550+
}
551+
}
552+
553+
let url = self.resolve_path(path.as_str())?;
554+
539555
let request_builder = match self.auth {
540556
Some(ref auth) => match auth {
541557
HttpAuth::User(username, password) => self.client
@@ -2677,6 +2693,66 @@ mod tests {
26772693
expect!(result.path_info).to(be_some().value(serde_json::Value::String("Yay! You found your way here".to_string())));
26782694
}
26792695

2696+
2697+
#[test]
2698+
fn resolve_path_handles_absolute_links_correctly() {
2699+
let client = HALClientBuilder::builder()
2700+
.with_url("http://127.0.0.1:8080/pact", None)
2701+
.build();
2702+
2703+
let path = "/pact/pacts/provider/Example%20API/for-verification";
2704+
let resolved = client.resolve_path(path).expect("Should resolve path");
2705+
2706+
expect!(resolved.path()).to(be_equal_to("/pact/pacts/provider/Example%20API/for-verification"));
2707+
}
2708+
2709+
#[test_log::test(tokio::test)]
2710+
async fn subpath_broker_templates_are_substituted() {
2711+
let pact_broker = PactBuilderAsync::new("RustPactVerifier", "TemplateTest")
2712+
.interaction("fetch root", "", |mut i| async move {
2713+
i.request.path("/pact");
2714+
i.response
2715+
.header("Content-Type", "application/hal+json")
2716+
.json_body(json_pattern!({
2717+
"_links": {
2718+
"pb:test": {
2719+
"href": "http://localhost/pact/test/{id}",
2720+
"templated": true
2721+
}
2722+
}
2723+
}));
2724+
i
2725+
})
2726+
.await
2727+
.interaction("fetch templated", "", |mut i| async move {
2728+
i.request.path("/pact/test/123");
2729+
i.response
2730+
.header("Content-Type", "application/json")
2731+
.json_body(json_pattern!("success"));
2732+
i
2733+
})
2734+
.await
2735+
.start_mock_server(None, None);
2736+
2737+
let base_url = pact_broker.url().to_string();
2738+
let broker_url = if base_url.ends_with('/') {
2739+
format!("{}pact", base_url)
2740+
} else {
2741+
format!("{}/pact", base_url)
2742+
};
2743+
2744+
let client = HALClientBuilder::builder()
2745+
.with_url(broker_url, None)
2746+
.build();
2747+
2748+
// Navigate to templated link
2749+
let mut template_vals = HashMap::new();
2750+
template_vals.insert("id".to_string(), "123".to_string());
2751+
2752+
let client_after = client.navigate("pb:test", &template_vals).await.unwrap();
2753+
expect!(client_after.path_info).to(be_some());
2754+
}
2755+
26802756
#[test_log::test(tokio::test)]
26812757
async fn navigate_takes_context_paths_into_account() {
26822758
let pact_broker = PactBuilderAsync::new("RustPactVerifier", "PactBrokerStub")

0 commit comments

Comments
 (0)