uv/crates/uv-client/tests/user_agent_version.rs
samypr100 93f5609476
feat: add uv version to user agent (#2136)
## Summary

Closes #1977

This allows us to send uv's version in the `uv-client` User Agent
header.

Here's how request headers look like to a server now:
```
...
Accept: application/vnd.pypi.simple.v1+json, application/vnd.pypi.simple.v1+html;q=0.2, text/html;q=0.01
User-Agent: uv/0.1.13
...
```

~~I went for a mix of Option 1 and 2 from #1977.~~ Open to alternative
naming as well, not tied too strongly here to the names picked.

~~Another possibility for this new crate is that we can use it to
consolidate metadata that exists across crates to ultimately be able to
create linehaul information described in #1958, but I haven't looked
into what those changes might look like.~~

<!-- What's the purpose of the change? What does it do, and why? -->

## Test Plan

<!-- How was it tested? -->
Added initial tests in the new crate to exercise its public API and
added a new test to uv-client to validate the headers using a 1-time
disposable server.
2024-03-04 19:48:41 +00:00

63 lines
1.8 KiB
Rust

use anyhow::Result;
use futures::future;
use hyper::header::USER_AGENT;
use hyper::server::conn::Http;
use hyper::service::service_fn;
use hyper::{Body, Request, Response};
use tokio::net::TcpListener;
use uv_cache::Cache;
use uv_client::RegistryClientBuilder;
use uv_version::version;
#[tokio::test]
async fn test_user_agent_has_version() -> Result<()> {
// Set up the TCP listener on a random available port
let listener = TcpListener::bind("127.0.0.1:0").await?;
let addr = listener.local_addr()?;
// Spawn the server loop in a background task
tokio::spawn(async move {
let svc = service_fn(move |req: Request<Body>| {
// Get User Agent Header and send it back in the response
let user_agent = req
.headers()
.get(USER_AGENT)
.and_then(|v| v.to_str().ok())
.map(|s| s.to_string())
.unwrap_or_default(); // Empty Default
future::ok::<_, hyper::Error>(Response::new(Body::from(user_agent)))
});
// Start Hyper Server
let (socket, _) = listener.accept().await.unwrap();
Http::new()
.http1_keep_alive(false)
.serve_connection(socket, svc)
.with_upgrades()
.await
.expect("Server Started");
});
// Initialize uv-client
let cache = Cache::temp()?;
let client = RegistryClientBuilder::new(cache).build();
// Send request to our dummy server
let res = client
.cached_client()
.uncached()
.get(format!("http://{addr}"))
.send()
.await?;
// Check the HTTP status
assert!(res.status().is_success());
// Check User Agent
let body = res.text().await?;
// Verify body matches regex
assert_eq!(body, format!("uv/{}", version()));
Ok(())
}