Skip to content

Commit

Permalink
fix: overwrite existing query if conflict in pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
SebRollen committed Nov 9, 2021
1 parent 88e0f50 commit 4010fbe
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 3 deletions.
18 changes: 15 additions & 3 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,14 +154,26 @@ impl Client {
if let Some(page) = page.as_ref() {
match page {
PaginationType::Query(queries) => {
let mut existing = base_request.url_mut().query_pairs_mut();
// There's no easy way to just overwrite specific queries, so we need
// to do some extra manipulating.
let keys: Vec<_> = queries.iter().map(|(k, _)| k).collect();
let unchanged_queries: Vec<(_, _)> = base_request
.url()
.query_pairs()
.filter(|(k, _)| !keys.contains(&&k.to_string()))
.collect();
let mut temp_url = base_request.url().clone();
temp_url.set_query(None);
for (key, val) in unchanged_queries {
temp_url.query_pairs_mut().append_pair(&key, &val);
}
for (key, val) in queries.iter() {
existing.append_pair(key, val);
temp_url.query_pairs_mut().append_pair(key, val);
}
base_request.url_mut().set_query(temp_url.query());
}
};
}

let response = self.send_raw(base_request).await?;
let state = paginator.next(&state, &response);
Ok(Some((response, (paginator, state))))
Expand Down
43 changes: 43 additions & 0 deletions tests/integration/pagination.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,46 @@ async fn query() {
);
assert!(response.next().await.is_none());
}

#[tokio::test]
async fn can_overwrite_existing_query() {
let server = MockServer::start().await;
let uri = server.uri();
let client = Client::new(&uri);

Mock::given(method("GET"))
.and(path("/page"))
.and(query_param("page", "0"))
.respond_with(|_: &MockRequest| {
let body = PaginationResponse {
next_page: Some(1),
data: "First!".into(),
};
ResponseTemplate::new(200).set_body_json(body)
})
.mount(&server)
.await;

Mock::given(method("GET"))
.and(path("/page"))
.and(query_param("page", "1"))
.respond_with(|_: &MockRequest| {
let body = PaginationResponse {
next_page: Some(2),
data: "Second!".into(),
};
ResponseTemplate::new(200).set_body_json(body)
})
.mount(&server)
.await;

let mut response = client.send_paginated(&PaginationRequest { page: Some(0) });
assert_eq!(
response.next().await.unwrap().unwrap().data,
"First!".to_string()
);
assert_eq!(
response.next().await.unwrap().unwrap().data,
"Second!".to_string()
);
}

0 comments on commit 4010fbe

Please sign in to comment.