Skip to content

Commit

Permalink
chore: more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kainlite committed Jan 24, 2025
1 parent 7fc53d4 commit f9eba9c
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 33 deletions.
42 changes: 21 additions & 21 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 11 additions & 11 deletions src/registry/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ struct TokenResponse {
}

#[derive(Debug)]
struct AuthChallenge {
realm: String,
service: String,
scope: String,
pub struct AuthChallenge {
pub realm: String,
pub service: String,
pub scope: String,
}

impl AuthChallenge {
fn from_header(header: &str) -> Option<Self> {
pub fn from_header(header: &str) -> Option<Self> {
let mut realm = None;
let mut service = None;
let mut scope = None;
Expand Down Expand Up @@ -57,11 +57,11 @@ impl AuthChallenge {

#[derive(Debug)]
pub struct RegistryChecker {
client: Client,
registry_url: String,
auth_token: Option<String>,
username: Option<String>,
password: Option<String>,
pub client: Client,
pub registry_url: String,
pub auth_token: Option<String>,
pub username: Option<String>,
pub password: Option<String>,
}

impl RegistryChecker {
Expand Down Expand Up @@ -107,7 +107,7 @@ impl RegistryChecker {
})
}

async fn get_bearer_token(&self, challenge: &AuthChallenge) -> Result<String> {
pub async fn get_bearer_token(&self, challenge: &AuthChallenge) -> Result<String> {
let mut request = self
.client
.get(&challenge.realm)
Expand Down
116 changes: 115 additions & 1 deletion tests/registry_tests.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#[cfg(test)]
mod tests {
use gitops_operator::registry::*;

use serde_json::json;
use tracing_subscriber::{fmt, EnvFilter};
use wiremock::{
matchers::{header, method, path},
matchers::{header, method, path, query_param},
Mock, MockServer, ResponseTemplate,
};

Expand Down Expand Up @@ -148,4 +149,117 @@ mod tests {

assert!(!result.unwrap());
}

#[test]
fn test_auth_challenge_from_header() {
// Test successful parsing
let header = r#"Bearer realm="https://auth.docker.io/token",service="registry.docker.io",scope="repository:test/image:pull""#;
let challenge = AuthChallenge::from_header(header);
assert!(challenge.is_some());

let challenge = challenge.unwrap();
assert_eq!(challenge.realm, "https://auth.docker.io/token");
assert_eq!(challenge.service, "registry.docker.io");
assert_eq!(challenge.scope, "repository:test/image:pull");

// Test missing Bearer prefix
let header = r#"realm="https://auth.docker.io/token",service="registry.docker.io",scope="repository:test/image:pull""#;
let challenge = AuthChallenge::from_header(header);
assert!(challenge.is_none());

// Test missing required field
let header =
r#"Bearer realm="https://auth.docker.io/token",scope="repository:test/image:pull""#;
let challenge = AuthChallenge::from_header(header);
assert!(challenge.is_none());

// Test malformed header
let header = r#"Bearer malformed_content"#;
let challenge = AuthChallenge::from_header(header);
assert!(challenge.is_none());
}

#[tokio::test]
async fn test_get_bearer_token_no_auth() {
init_logging();
let mock_server = MockServer::start().await;

let challenge = AuthChallenge {
realm: mock_server.uri() + "/token",
service: "registry.test.com".to_string(),
scope: "repository:test/image:pull".to_string(),
};

Mock::given(method("GET"))
.and(path("/token"))
.and(query_param("service", "registry.test.com"))
.and(query_param("scope", "repository:test/image:pull"))
.respond_with(ResponseTemplate::new(200).set_body_json(json!({
"token": "new-token",
"expires_in": 300
})))
.mount(&mock_server)
.await;

let checker = RegistryChecker::new(mock_server.uri(), None).await.unwrap();
let token = checker.get_bearer_token(&challenge).await;
assert!(token.is_ok());
assert_eq!(token.unwrap(), "new-token");
}

#[tokio::test]
async fn test_get_bearer_token_with_basic_auth() {
init_logging();
let mock_server = MockServer::start().await;

let challenge = AuthChallenge {
realm: mock_server.uri() + "/token",
service: "registry.test.com".to_string(),
scope: "repository:test/image:pull".to_string(),
};

Mock::given(method("GET"))
.and(path("/token"))
.and(query_param("service", "registry.test.com"))
.and(query_param("scope", "repository:test/image:pull"))
.and(header("authorization", "Basic dXNlcjpwYXNz"))
.respond_with(ResponseTemplate::new(200).set_body_json(json!({
"token": "new-token-with-auth",
"expires_in": 300
})))
.mount(&mock_server)
.await;

let checker =
RegistryChecker::new(mock_server.uri(), Some("Basic dXNlcjpwYXNz".to_string()))
.await
.unwrap();
let token = checker.get_bearer_token(&challenge).await;
assert!(token.is_ok());
assert_eq!(token.unwrap(), "new-token-with-auth");
}

#[tokio::test]
async fn test_get_bearer_token_failed_auth() {
init_logging();
let mock_server = MockServer::start().await;

let challenge = AuthChallenge {
realm: mock_server.uri() + "/token",
service: "registry.test.com".to_string(),
scope: "repository:test/image:pull".to_string(),
};

Mock::given(method("GET"))
.and(path("/token"))
.and(query_param("service", "registry.test.com"))
.and(query_param("scope", "repository:test/image:pull"))
.respond_with(ResponseTemplate::new(401))
.mount(&mock_server)
.await;

let checker = RegistryChecker::new(mock_server.uri(), None).await.unwrap();
let token = checker.get_bearer_token(&challenge).await;
assert!(token.is_err());
}
}

0 comments on commit f9eba9c

Please sign in to comment.