add test with warp
cargo devel CI / cargo CI (push) Failing after 1m46s Details

This commit is contained in:
Christoph J. Scherr 2024-03-08 19:49:40 +01:00
parent 77ced4b277
commit b17fcb8c41
Signed by: PlexSheep
GPG Key ID: 7CDD0B14851A08EF
2 changed files with 100 additions and 13 deletions

View File

@ -4,7 +4,9 @@ use crate::{store::Sequence, Item, Store};
use rand::seq::SliceRandom;
use serde::{Deserialize, Serialize};
const ALPHABET: &str = "qwertzuiopasdfghjklyxcvbnmQWERTZUIOPASDFGHJKLYXCVBNM";
pub const ALPHABET: &str = "qwertzuiopasdfghjklyxcvbnmQWERTZUIOPASDFGHJKLYXCVBNM";
pub const TOK_LEN: usize = 40;
pub const ID_LEN: usize = 20;
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct Client {
@ -61,20 +63,24 @@ impl Id {
pub fn new() -> Self {
let mut rng = rand::thread_rng();
let mut data = ALPHABET.to_string().into_bytes();
data.repeat(ID_LEN);
data.shuffle(&mut rng);
Self {
inner: String::from_utf8(data[..20].into()).unwrap(),
inner: String::from_utf8(data[..ID_LEN].into()).unwrap(),
}
}
pub fn len(&self) -> usize {
self.inner.len()
}
}
impl FromStr for Id {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self {
inner: s.to_string(),
})
let s = s.replace('"', "");
Ok(Self { inner: s })
}
}
@ -84,7 +90,7 @@ impl Display for Id {
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Token {
#[serde(rename = "token")]
inner: String,
@ -94,19 +100,29 @@ impl Token {
pub fn new() -> Self {
let mut rng = rand::thread_rng();
let mut data = ALPHABET.to_string().into_bytes();
data.repeat(TOK_LEN);
data.shuffle(&mut rng);
Self {
inner: String::from_utf8(data).unwrap(),
inner: String::from_utf8(data[..TOK_LEN].to_vec()).unwrap(),
}
}
pub fn len(&self) -> usize {
self.inner.len()
}
}
impl Display for Token {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.inner)
}
}
impl FromStr for Token {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self {
inner: s.to_string(),
})
let s = s.replace('"', "");
Ok(Self { inner: s })
}
}

View File

@ -5,7 +5,8 @@ use warp::{
filters::BoxedFilter,
http::StatusCode,
reject::{MissingHeader, Rejection},
reply, Filter, Reply,
reply::{self, Json},
Filter, Reply,
};
use crate::{Client, Id, Store, StoreErr, Token};
@ -62,7 +63,7 @@ pub async fn item_getter(
}
// GET /api/v1/items
pub fn get_items(store: Store) -> BoxedFilter<(impl Reply,)> {
pub fn get_items(store: Store) -> impl Filter<Extract = (Json,), Error = warp::Rejection> + Clone {
warp::path!("api" / "v1" / "items")
.and(warp::get())
.and(warp::query::<HashMap<String, String>>())
@ -74,7 +75,9 @@ pub fn get_items(store: Store) -> BoxedFilter<(impl Reply,)> {
}
// GET /api/v1/register
pub fn get_register(store: Store) -> BoxedFilter<(impl Reply,)> {
pub fn get_register(
store: Store,
) -> impl Filter<Extract = (Json,), Error = warp::Rejection> + Clone {
warp::path!("api" / "v1" / "register")
.and(warp::get())
.and(with_store(store))
@ -88,3 +91,71 @@ pub fn get_register(store: Store) -> BoxedFilter<(impl Reply,)> {
})
.boxed()
}
mod test {
use warp::{
http::StatusCode,
hyper::{self, body::*},
reply::{Json, Reply},
};
use std::str::FromStr;
#[tokio::test]
async fn test_register_and_get() {
let store = crate::Store::new();
let filter = super::get_register(store.clone());
let response: warp::reply::Response = warp::test::request()
.path("/api/v1/register")
.filter(&filter)
.await
.unwrap()
.into_response();
assert_eq!(response.status(), StatusCode::OK);
let body_raw: Bytes = hyper::body::to_bytes(response.into_body()).await.unwrap();
let body_json: serde_json::Value = serde_json::from_slice(&body_raw).unwrap();
assert!(body_json.is_object());
let id: crate::Id = crate::Id::from_str(
&body_json
.get("id")
.expect("response has no field 'id'")
.to_owned()
.to_string(),
)
.unwrap();
let token: crate::Token = crate::Token::from_str(
&body_json
.get("token")
.expect("response has no field 'token'")
.to_owned()
.to_string(),
)
.unwrap();
assert_eq!(id.len(), crate::ID_LEN);
assert_eq!(token.len(), crate::TOK_LEN);
let filter = super::get_items(store);
let response: warp::reply::Response = warp::test::request()
.path(format!("/api/v1/items/?id={id}").as_str())
.header("Token", token.to_string())
.filter(&filter)
.await
.unwrap()
.into_response();
assert_eq!(response.status(), StatusCode::OK);
let body_raw: Bytes = hyper::body::to_bytes(response.into_body()).await.unwrap();
let body_json: serde_json::Value = serde_json::from_slice(&body_raw).unwrap();
assert!(body_json.is_array());
for i in 0..2 {
assert!(body_json[i].is_object());
let item: crate::Item =
serde_json::from_value(body_json[i].clone().take()).unwrap();
assert_eq!(item.seq, i);
}
}
}