Skip to content

Commit

Permalink
Merge pull request #35 from sebastienrousseau/feature/mini-functions
Browse files Browse the repository at this point in the history
test(mini-functions): ✅ Add unit tests covering vari…
  • Loading branch information
sebastienrousseau authored Dec 7, 2023
2 parents 5142c2d + 5872bf5 commit fd844a7
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 81 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ A Rust library of highly performant utility and wrapper functions

</center>

<!-- markdownlint-enable MD033 MD041 -->
## Overview

`Mini Functions` is a highly performant utility and wrapper functions library for Rust that has been carefully designed with optimization and efficiency in mind. By providing convenient wrapper functions, our library aims to provide a high-level interface for common tasks while still leveraging the performance benefits of Rust under the hood. These utility functions serve as an essential toolkit for any Rust developer, and the library's design abstractions allow for easy integration into a variety of projects and applications.
Expand Down
6 changes: 3 additions & 3 deletions cjwt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ use std::{fmt, string::ToString};
/// JWT is a struct that holds the JWT token and its associated claims.
/// Provides a set of utility functions for working with JSON Web Tokens
/// (JWTs) and JSON Web Signatures (JWSs).
#[derive(Clone, Debug, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JWT {
/// The header of the JWT.
pub header: Header,
Expand All @@ -81,7 +81,7 @@ pub struct JWT {
pub token: String,
}
/// The Header struct contains the header of the JWT.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize, PartialOrd)]
pub struct Header {
/// Indicates the algorithm used to sign the JWT. Defaults to HS256.
/// See the Algorithm enum for a list of supported algorithms.
Expand All @@ -96,7 +96,7 @@ pub struct Header {
}

/// The Algorithm enum contains a list of supported algorithms.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, Serialize, Deserialize, PartialOrd)]
pub enum Algorithm {
/// HMAC using SHA-256 hash algorithm.
HS256,
Expand Down
251 changes: 173 additions & 78 deletions cjwt/tests/cjwt.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
#[cfg(test)]

// FIXME: Add more tests to bring the code coverage to 100%
mod tests {
extern crate cjwt;
extern crate cclm;
Expand All @@ -9,45 +7,71 @@ mod tests {
use self::cclm::Claims;

#[test]
fn test_header_default() {
let header = Header::default();
assert_eq!(header.alg, Some(Algorithm::HS256));
assert_eq!(header.kid, None);
assert_eq!(header.typ, Some("JWT".to_string()));
assert_eq!(header.cty, None);
fn test_default_algorithm_is_hs256() {
let algorithm = Algorithm::default();
assert_eq!(algorithm, Algorithm::HS256);
}

#[test]
fn test_encode() {
let secret: &[u8; 6] = b"secret";
let header = Header::default();
let claims = Claims::default();
let result = JWT::encode(header, claims, secret);
assert!(result.is_ok(), "{}", true);
fn test_algorithm_to_string_variants() {
let algorithm = Algorithm::default();
assert_eq!(algorithm.to_string(), "HS256");

let algorithm_hs384 = Algorithm::HS384;
assert_eq!(algorithm_hs384.to_string(), "HS384");

let algorithm_hs512 = Algorithm::HS512;
assert_eq!(algorithm_hs512.to_string(), "HS512");

let algorithm_rs256 = Algorithm::RS256;
assert_eq!(algorithm_rs256.to_string(), "RS256");

let algorithm_rs384 = Algorithm::RS384;
assert_eq!(algorithm_rs384.to_string(), "RS384");

let algorithm_rs512 = Algorithm::RS512;
assert_eq!(algorithm_rs512.to_string(), "RS512");

let algorithm_es256 = Algorithm::ES256;
assert_eq!(algorithm_es256.to_string(), "ES256");

let algorithm_es384 = Algorithm::ES384;
assert_eq!(algorithm_es384.to_string(), "ES384");

let algorithm_es512 = Algorithm::ES512;
assert_eq!(algorithm_es512.to_string(), "ES512");
}

#[test]
fn test_decode() {
let mut jwt = JWT::default();
let secret: &[u8; 6] = b"secret";
fn test_algorithm_variants_are_defined() {
assert!(matches!(Algorithm::HS256, Algorithm::HS256));
assert!(matches!(Algorithm::HS384, Algorithm::HS384));
assert!(matches!(Algorithm::HS512, Algorithm::HS512));
assert!(matches!(Algorithm::RS256, Algorithm::RS256));
assert!(matches!(Algorithm::RS384, Algorithm::RS384));
assert!(matches!(Algorithm::RS512, Algorithm::RS512));
assert!(matches!(Algorithm::ES256, Algorithm::ES256));
assert!(matches!(Algorithm::ES384, Algorithm::ES384));
assert!(matches!(Algorithm::ES512, Algorithm::ES512));
}

#[test]
fn test_default_header_has_correct_fields() {
let header = Header::default();
let claims = Claims::default();
let encoded_result = JWT::encode(header, claims, secret);
let encoded = encoded_result.unwrap();
jwt.token.clone_from(&encoded);
let decoded = JWT::decode(&mut jwt, secret);
if let Ok(decoded_token) = decoded {
assert_eq!(decoded_token, encoded);
}
assert_eq!(header.alg, Some(Algorithm::HS256));
assert_eq!(header.kid, None);
assert_eq!(header.typ, Some("JWT".to_string()));
assert_eq!(header.cty, None);
}

#[test]
fn test_default() {
let jwt = JWT::default();
assert_eq!(jwt.header.alg, Some(Algorithm::HS256));
fn test_empty_claims_are_generated() {
let claims = self::JWT::claims();
assert!(claims.is_empty(), "{}", true);
}

#[test]
fn test_generate() {
fn test_generate_jwt_with_valid_secret() {
let secret = b"secret";
let jwt = JWT::generate(secret);
assert!(jwt.is_ok());
Expand All @@ -56,7 +80,7 @@ mod tests {
}

#[test]
fn test_get_token() {
fn test_get_token_from_jwt() {
let jwt = JWT {
header: Header::default(),
claims: Claims::default(),
Expand All @@ -68,7 +92,7 @@ mod tests {
}

#[test]
fn test_get_token_header() {
fn test_get_token_header_from_jwt() {
let jwt = JWT {
header: Header {
alg: Some(Algorithm::HS256),
Expand All @@ -86,8 +110,9 @@ mod tests {
assert_eq!(result.typ, Some("example_type".to_string()));
assert_eq!(result.cty, Some("example_cty".to_string()));
}

#[test]
fn test_get_token_length() {
fn test_get_token_length_from_jwt() {
let jwt = JWT {
header: Header::default(),
claims: Claims::default(),
Expand All @@ -97,6 +122,46 @@ mod tests {
let result = JWT::get_token_length(jwt);
assert_eq!(result, 5);
}

#[test]
fn test_encode() {
let secret: &[u8; 6] = b"secret";
let header = Header::default();
let claims = Claims::default();
let result = JWT::encode(header, claims, secret);
assert!(result.is_ok(), "{}", true);
}

#[test]
fn test_decode() {
let mut jwt = JWT::default();
let secret: &[u8; 6] = b"secret";
let header = Header::default();
let claims = Claims::default();
let encoded_result = JWT::encode(header, claims, secret);
let encoded = encoded_result.unwrap();
jwt.token.clone_from(&encoded);
let decoded = JWT::decode(&mut jwt, secret);
if let Ok(decoded_token) = decoded {
assert_eq!(decoded_token, encoded);
}
}

#[test]
fn test_to_string() {
let jwt = JWT {
header: Header::default(),
claims: Claims::default(),
signature: vec![],
token: "example_token".to_owned(),
};
let result = jwt.to_string();
assert_eq!(
result,
"JWT { header: Header { alg: Some(HS256), kid: None, typ: Some(\"JWT\"), cty: None }, claims: Claims { }, signature: [], token: example_token }"
);
}

#[test]
fn test_validate_success() {
let secret: &[u8; 6] = b"secret";
Expand Down Expand Up @@ -130,68 +195,98 @@ mod tests {
let result = jwt.validate(secret);
assert!(result.is_err());
}

#[test]
fn test_to_string() {
let jwt = JWT {
header: Header::default(),
claims: Claims::default(),
signature: vec![],
token: "example_token".to_owned(),
fn test_decode_invalid_token() {
let mut jwt = JWT {
token: "invalid.token.structure".to_owned(),
..JWT::default()
};
let result = jwt.to_string();
assert_eq!(result, "JWT { header: Header { alg: Some(HS256), kid: None, typ: Some(\"JWT\"), cty: None }, claims: Claims { }, signature: [], token: example_token }");
let secret = b"secret";
assert!(JWT::decode(&mut jwt, secret).is_err());
}

#[test]
fn test_claims_default() {
let claims = self::JWT::claims();
assert!(claims.is_empty(), "{}", true);
fn test_decode_with_invalid_header() {
let mut jwt = JWT::default();
jwt.token = "invalid.header.structure".to_owned();
let secret = b"secret";
assert!(JWT::decode(&mut jwt, secret).is_err());
}

#[test]
fn test_algorithm_variants() {
assert!(matches!(Algorithm::HS256, Algorithm::HS256));
assert!(matches!(Algorithm::HS384, Algorithm::HS384));
assert!(matches!(Algorithm::HS512, Algorithm::HS512));
assert!(matches!(Algorithm::RS256, Algorithm::RS256));
assert!(matches!(Algorithm::RS384, Algorithm::RS384));
assert!(matches!(Algorithm::RS512, Algorithm::RS512));
assert!(matches!(Algorithm::ES256, Algorithm::ES256));
assert!(matches!(Algorithm::ES384, Algorithm::ES384));
assert!(matches!(Algorithm::ES512, Algorithm::ES512));
fn test_decode_with_invalid_claims() {
let mut jwt = JWT::default();
jwt.token = "invalid.claims.structure".to_owned();
let secret = b"secret";
assert!(JWT::decode(&mut jwt, secret).is_err());
}

#[test]
fn test_algorithm_default() {
let algorithm = Algorithm::default();
assert_eq!(algorithm, Algorithm::HS256);
fn test_validate_with_invalid_claims() {
let mut jwt = JWT::default();
jwt.token = "invalid.claims.structure".to_string();
let secret = b"secret";
assert!(JWT::validate(&jwt, secret).is_err());
}
#[test]
fn test_algorithm_to_string() {
let algorithm = Algorithm::default();
assert_eq!(algorithm.to_string(), "HS256");

let algorithm_hs384 = Algorithm::HS384;
assert_eq!(algorithm_hs384.to_string(), "HS384");

let algorithm_hs512 = Algorithm::HS512;
assert_eq!(algorithm_hs512.to_string(), "HS512");

let algorithm_rs256 = Algorithm::RS256;
assert_eq!(algorithm_rs256.to_string(), "RS256");
#[test]
fn test_decode_with_invalid_signature() {
let mut jwt = JWT::default();
jwt.token = "invalid.signature.value".to_owned();
let secret = b"secret";
assert!(JWT::decode(&mut jwt, secret).is_err());
}

let algorithm_rs384 = Algorithm::RS384;
assert_eq!(algorithm_rs384.to_string(), "RS384");
#[test]
fn test_validate_with_invalid_signature() {
let jwt = JWT {
header: Header::default(),
claims: Claims::default(),
signature: vec![],
token: "invalid.signature.value".to_string(),
};
let secret = b"secret";
assert!(JWT::validate(&jwt, secret).is_err());
}

let algorithm_rs512 = Algorithm::RS512;
assert_eq!(algorithm_rs512.to_string(), "RS512");
#[test]
fn test_decode_with_expired_iat() {
let mut jwt = JWT::default();
jwt.token = "expired.iat.jwt".to_owned();
let secret = b"secret";
assert!(JWT::decode(&mut jwt, secret).is_err());
}

let algorithm_es256 = Algorithm::ES256;
assert_eq!(algorithm_es256.to_string(), "ES256");
#[test]
fn test_decode_with_expired_exp() {
let mut jwt = JWT::default();
jwt.token = "expired.exp.jwt".to_owned();
let secret = b"secret";
assert!(JWT::decode(&mut jwt, secret).is_err());
}

let algorithm_es384 = Algorithm::ES384;
assert_eq!(algorithm_es384.to_string(), "ES384");
#[test]
fn test_validate_with_expired_iat() {
let jwt = JWT {
header: Header::default(),
claims: Claims::default(),
signature: vec![],
token: "expired.iat.jwt".to_string(),
};
let secret = b"secret";
assert!(JWT::validate(&jwt, secret).is_err());
}

let algorithm_es512 = Algorithm::ES512;
assert_eq!(algorithm_es512.to_string(), "ES512");
#[test]
fn test_validate_with_expired_exp() {
let jwt = JWT {
header: Header::default(),
claims: Claims::default(),
signature: vec![],
token: "expired.exp.jwt".to_owned(),
};
let secret = b"secret";
assert!(JWT::validate(&jwt, secret).is_err());
}
}

0 comments on commit fd844a7

Please sign in to comment.