mirror of https://github.com/raftario/filite.git
Add a couple basic tests
This commit is contained in:
parent
2a0d41be07
commit
6da60a96b6
|
@ -42,7 +42,7 @@ jobs:
|
|||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: /tmp/.buildx-cache
|
||||
key: buildx-${{ github.sha }}
|
||||
key: buildx-${{ hashFiles('**/Cargo.lock') }}
|
||||
restore-keys: |
|
||||
buildx-
|
||||
|
||||
|
@ -55,7 +55,7 @@ jobs:
|
|||
cache-to: type=local,dest=/tmp/.buildx-cache
|
||||
labels: |
|
||||
org.opencontainers.image.title=${{ github.event.repository.name }}
|
||||
org.opencontainers.image.description=${{ github.event.repository.description }}
|
||||
org.opencontainers.image.description='${{ github.event.repository.description }}'
|
||||
org.opencontainers.image.url=${{ github.event.repository.html_url }}
|
||||
org.opencontainers.image.source=${{ github.event.repository.clone_url }}
|
||||
org.opencontainers.image.version=${{ steps.prep.outputs.version }}
|
||||
|
|
|
@ -1182,6 +1182,17 @@ dependencies = [
|
|||
"num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pin-project-lite 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-macros 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1666,6 +1677,7 @@ dependencies = [
|
|||
"checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
|
||||
"checksum time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
|
||||
"checksum tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd"
|
||||
"checksum tokio-macros 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389"
|
||||
"checksum tokio-rustls 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e12831b255bcfa39dc0436b01e19fea231a37db570686c06ee72c423479f889a"
|
||||
"checksum tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499"
|
||||
"checksum toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
|
||||
|
|
|
@ -28,7 +28,7 @@ serde = { version = "1.0.116", features = ["derive"] }
|
|||
serde_json = "1.0.57"
|
||||
sled = "0.34.4"
|
||||
structopt = "0.3.18"
|
||||
tokio = { version = "0.2.22", features = ["blocking", "fs", "rt-threaded"] }
|
||||
tokio = { version = "0.2.22", features = ["blocking", "fs", "macros", "rt-threaded"] }
|
||||
tracing = "0.1.19"
|
||||
tracing-futures = "0.2.4"
|
||||
tracing-subscriber = "0.2.12"
|
||||
|
|
|
@ -31,7 +31,7 @@ pub fn required(
|
|||
warp::header::header("Authorization").and_then(move |header| user(header, db, config))
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug")]
|
||||
#[tracing::instrument(level = "debug", skip(db))]
|
||||
async fn user(header: String, db: &Db, config: &Config) -> Result<User, Rejection> {
|
||||
if &header[..5] != "Basic" {
|
||||
return Err(crate::reject::unauthorized());
|
||||
|
|
12
src/db.rs
12
src/db.rs
|
@ -4,6 +4,7 @@ use chrono::{DateTime, Utc};
|
|||
use rand::{distributions::Alphanumeric, Rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sled::Db;
|
||||
use std::fmt;
|
||||
use tokio::task;
|
||||
|
||||
#[tracing::instrument(level = "debug")]
|
||||
|
@ -171,13 +172,22 @@ pub fn random_id(length: usize, db: &Db) -> Result<String> {
|
|||
})
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
#[derive(Clone, Deserialize, Serialize)]
|
||||
pub struct User {
|
||||
pub id: String,
|
||||
pub admin: bool,
|
||||
pub password_hash: String,
|
||||
}
|
||||
|
||||
impl fmt::Debug for User {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("User")
|
||||
.field("id", &self.id)
|
||||
.field("admin", &self.admin)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
struct DbUser {
|
||||
admin: bool,
|
||||
|
|
|
@ -6,7 +6,10 @@ use crate::{
|
|||
use bytes::Bytes;
|
||||
use sled::Db;
|
||||
use warp::reply::Response;
|
||||
use warp::{http::Uri, Filter, Rejection, Reply};
|
||||
use warp::{
|
||||
http::{StatusCode, Uri},
|
||||
Filter, Rejection, Reply,
|
||||
};
|
||||
|
||||
pub fn handler(
|
||||
config: &'static Config,
|
||||
|
@ -20,14 +23,14 @@ pub fn handler(
|
|||
.and(warp::post())
|
||||
.and(crate::auth::required(db, config))
|
||||
.and(warp::body::bytes())
|
||||
.and(warp::header("Content-Type"))
|
||||
.and(warp::header::optional("Content-Type"))
|
||||
.and(warp::header::optional("X-ID-Length"))
|
||||
.and_then(move |user, data, mime, len| post_file(user, data, mime, len, db));
|
||||
let put_file = warp::path!("f" / String)
|
||||
.and(warp::put())
|
||||
.and(crate::auth::required(db, config))
|
||||
.and(warp::body::bytes())
|
||||
.and(warp::header("Content-Type"))
|
||||
.and(warp::header::optional("Content-Type"))
|
||||
.and_then(move |id, user, data, mime| put_file(id, user, data, mime, db));
|
||||
|
||||
let post_link = warp::path!("l")
|
||||
|
@ -88,7 +91,7 @@ async fn filite(id: String, db: &Db) -> Result<impl Reply, Rejection> {
|
|||
async fn post_file(
|
||||
user: User,
|
||||
data: Bytes,
|
||||
mime: String,
|
||||
mime: Option<String>,
|
||||
len: Option<usize>,
|
||||
db: &Db,
|
||||
) -> Result<impl Reply, Rejection> {
|
||||
|
@ -101,13 +104,19 @@ async fn put_file(
|
|||
id: String,
|
||||
user: User,
|
||||
data: Bytes,
|
||||
mime: String,
|
||||
mime: Option<String>,
|
||||
db: &Db,
|
||||
) -> Result<impl Reply, Rejection> {
|
||||
crate::db::insert_file(&id, user.id, data.to_vec(), mime, db)
|
||||
.or_500()?
|
||||
.or_409()?;
|
||||
Ok(id)
|
||||
crate::db::insert_file(
|
||||
&id,
|
||||
user.id,
|
||||
data.to_vec(),
|
||||
mime.unwrap_or_else(|| "application/octet-stream".to_owned()),
|
||||
db,
|
||||
)
|
||||
.or_500()?
|
||||
.or_409()?;
|
||||
Ok(warp::reply::with_status(id, StatusCode::CREATED))
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(db))]
|
||||
|
@ -126,7 +135,7 @@ async fn put_link(id: String, user: User, location: Uri, db: &Db) -> Result<impl
|
|||
crate::db::insert_link(&id, user.id, location.to_string(), db)
|
||||
.or_500()?
|
||||
.or_409()?;
|
||||
Ok(id)
|
||||
Ok(warp::reply::with_status(id, StatusCode::CREATED))
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(db))]
|
||||
|
@ -145,5 +154,5 @@ async fn put_text(id: String, user: User, data: String, db: &Db) -> Result<impl
|
|||
crate::db::insert_text(&id, user.id, data, db)
|
||||
.or_500()?
|
||||
.or_409()?;
|
||||
Ok(id)
|
||||
Ok(warp::reply::with_status(id, StatusCode::CREATED))
|
||||
}
|
||||
|
|
111
src/tests.rs
111
src/tests.rs
|
@ -1 +1,110 @@
|
|||
// TODO
|
||||
use crate::config::Config;
|
||||
use sled::Db;
|
||||
use tracing_subscriber::fmt::format::FmtSpan;
|
||||
use warp::http::StatusCode;
|
||||
|
||||
fn setup() -> (&'static Config, &'static Db) {
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter("debug")
|
||||
.with_span_events(FmtSpan::CLOSE)
|
||||
.try_init()
|
||||
.ok();
|
||||
|
||||
let config = Box::leak(Box::new(Default::default()));
|
||||
let db = Box::leak(Box::new(
|
||||
sled::Config::default().temporary(true).open().unwrap(),
|
||||
));
|
||||
|
||||
crate::db::insert_user("user", "password", true, db, config).unwrap();
|
||||
|
||||
(config, db)
|
||||
}
|
||||
|
||||
const AUTH: &str = "Basic dXNlcjpwYXNzd29yZA==";
|
||||
|
||||
#[tokio::test(core_threads = 2)]
|
||||
async fn file() {
|
||||
let (config, db) = setup();
|
||||
let filter = crate::routes::handler(config, db);
|
||||
|
||||
let value = b"file";
|
||||
|
||||
let reply = warp::test::request()
|
||||
.path("/f")
|
||||
.method("POST")
|
||||
.body(value)
|
||||
.header("Authorization", AUTH)
|
||||
.reply(&filter)
|
||||
.await;
|
||||
assert_eq!(reply.status(), StatusCode::CREATED);
|
||||
|
||||
let id = std::str::from_utf8(reply.body()).unwrap();
|
||||
let reply = warp::test::request()
|
||||
.path(&format!("/{}", id))
|
||||
.reply(&filter)
|
||||
.await;
|
||||
assert_eq!(reply.status(), StatusCode::OK);
|
||||
assert_eq!(
|
||||
reply
|
||||
.headers()
|
||||
.get("Content-Type")
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap(),
|
||||
"application/octet-stream"
|
||||
);
|
||||
assert_eq!(reply.body().as_ref(), value);
|
||||
}
|
||||
|
||||
#[tokio::test(core_threads = 2)]
|
||||
async fn link() {
|
||||
let (config, db) = setup();
|
||||
let filter = crate::routes::handler(config, db);
|
||||
|
||||
let value = "https://google.com/";
|
||||
|
||||
let reply = warp::test::request()
|
||||
.path("/l")
|
||||
.method("POST")
|
||||
.body(value)
|
||||
.header("Authorization", AUTH)
|
||||
.reply(&filter)
|
||||
.await;
|
||||
assert_eq!(reply.status(), StatusCode::CREATED);
|
||||
|
||||
let id = std::str::from_utf8(reply.body()).unwrap();
|
||||
let reply = warp::test::request()
|
||||
.path(&format!("/{}", id))
|
||||
.reply(&filter)
|
||||
.await;
|
||||
assert_eq!(reply.status(), StatusCode::TEMPORARY_REDIRECT);
|
||||
assert_eq!(
|
||||
reply.headers().get("Location").unwrap().to_str().unwrap(),
|
||||
value
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test(core_threads = 2)]
|
||||
async fn text() {
|
||||
let (config, db) = setup();
|
||||
let filter = crate::routes::handler(config, db);
|
||||
|
||||
let value = "text";
|
||||
|
||||
let reply = warp::test::request()
|
||||
.path("/t")
|
||||
.method("POST")
|
||||
.body(value)
|
||||
.header("Authorization", AUTH)
|
||||
.reply(&filter)
|
||||
.await;
|
||||
assert_eq!(reply.status(), StatusCode::CREATED);
|
||||
|
||||
let id = std::str::from_utf8(reply.body()).unwrap();
|
||||
let reply = warp::test::request()
|
||||
.path(&format!("/{}", id))
|
||||
.reply(&filter)
|
||||
.await;
|
||||
assert_eq!(reply.status(), StatusCode::OK);
|
||||
assert_eq!(std::str::from_utf8(reply.body()).unwrap(), value);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue