mirror of https://github.com/realaravinth/gitpad
parent
4a8b72c7d5
commit
96be68c734
|
@ -14,6 +14,8 @@
|
||||||
//! - [errors](crate::auth): error data structures used in this crate
|
//! - [errors](crate::auth): error data structures used in this crate
|
||||||
//! - [ops](crate::ops): meta operations like connection pool creation, migrations and getting
|
//! - [ops](crate::ops): meta operations like connection pool creation, migrations and getting
|
||||||
//! connection from pool
|
//! connection from pool
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
|
@ -90,9 +92,13 @@ impl GistVisibility {
|
||||||
GistVisibility::Public => "public",
|
GistVisibility::Public => "public",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for GistVisibility {
|
||||||
|
type Err = DBError;
|
||||||
|
|
||||||
/// Convert [str] to [GistVisibility]
|
/// Convert [str] to [GistVisibility]
|
||||||
pub fn from_str(s: &str) -> DBResult<Self> {
|
fn from_str(s: &str) -> DBResult<Self> {
|
||||||
const PRIVATE: &str = GistVisibility::Private.to_str();
|
const PRIVATE: &str = GistVisibility::Private.to_str();
|
||||||
const PUBLIC: &str = GistVisibility::Public.to_str();
|
const PUBLIC: &str = GistVisibility::Public.to_str();
|
||||||
const UNLISTED: &str = GistVisibility::Unlisted.to_str();
|
const UNLISTED: &str = GistVisibility::Unlisted.to_str();
|
||||||
|
@ -366,7 +372,7 @@ impl GistDatabase for Box<dyn GistDatabase> {
|
||||||
/// Trait to clone GistDatabase
|
/// Trait to clone GistDatabase
|
||||||
pub trait CloneGistDatabase {
|
pub trait CloneGistDatabase {
|
||||||
/// clone DB
|
/// clone DB
|
||||||
fn clone_db<'a>(&self) -> Box<dyn GistDatabase>;
|
fn clone_db(&self) -> Box<dyn GistDatabase>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> CloneGistDatabase for T
|
impl<T> CloneGistDatabase for T
|
||||||
|
|
|
@ -88,13 +88,13 @@ pub async fn gists_work<T: GistDatabase>(
|
||||||
db.username_register(®ister_payload).await.unwrap();
|
db.username_register(®ister_payload).await.unwrap();
|
||||||
|
|
||||||
let create_gist = CreateGist {
|
let create_gist = CreateGist {
|
||||||
owner: username.into(),
|
owner: username,
|
||||||
description: Some("foo"),
|
description: Some("foo"),
|
||||||
public_id,
|
public_id,
|
||||||
visibility: &GistVisibility::Public,
|
visibility: &GistVisibility::Public,
|
||||||
};
|
};
|
||||||
|
|
||||||
assert!(!db.gist_exists(&create_gist.public_id).await.unwrap());
|
assert!(!db.gist_exists(create_gist.public_id).await.unwrap());
|
||||||
// create gist
|
// create gist
|
||||||
assert!(db.get_user_gists(username).await.unwrap().is_empty());
|
assert!(db.get_user_gists(username).await.unwrap().is_empty());
|
||||||
|
|
||||||
|
@ -104,9 +104,9 @@ pub async fn gists_work<T: GistDatabase>(
|
||||||
Some(DBError::GistIDTaken)
|
Some(DBError::GistIDTaken)
|
||||||
));
|
));
|
||||||
|
|
||||||
assert!(db.gist_exists(&create_gist.public_id).await.unwrap());
|
assert!(db.gist_exists(create_gist.public_id).await.unwrap());
|
||||||
// get gist
|
// get gist
|
||||||
let db_gist = db.get_gist(&create_gist.public_id).await.unwrap();
|
let db_gist = db.get_gist(create_gist.public_id).await.unwrap();
|
||||||
assert_gists(&create_gist, &db_gist);
|
assert_gists(&create_gist, &db_gist);
|
||||||
|
|
||||||
let mut gists = db.get_user_gists(username).await.unwrap();
|
let mut gists = db.get_user_gists(username).await.unwrap();
|
||||||
|
@ -116,14 +116,14 @@ pub async fn gists_work<T: GistDatabase>(
|
||||||
|
|
||||||
// comment on gist
|
// comment on gist
|
||||||
let create_comment = CreateGistComment {
|
let create_comment = CreateGistComment {
|
||||||
owner: username.into(),
|
owner: username,
|
||||||
gist_public_id: create_gist.public_id,
|
gist_public_id: create_gist.public_id,
|
||||||
comment: "foo".into(),
|
comment: "foo",
|
||||||
};
|
};
|
||||||
db.new_comment(&create_comment).await.unwrap();
|
db.new_comment(&create_comment).await.unwrap();
|
||||||
// get all comments on gist
|
// get all comments on gist
|
||||||
let mut comments = db
|
let mut comments = db
|
||||||
.get_comments_on_gist(&create_gist.public_id)
|
.get_comments_on_gist(create_gist.public_id)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(comments.len() == 1);
|
assert!(comments.len() == 1);
|
||||||
|
@ -144,14 +144,14 @@ pub async fn gists_work<T: GistDatabase>(
|
||||||
|
|
||||||
// visibility filters
|
// visibility filters
|
||||||
let create_unlisted_gist = CreateGist {
|
let create_unlisted_gist = CreateGist {
|
||||||
owner: username.into(),
|
owner: username,
|
||||||
description: Some("foo"),
|
description: Some("foo"),
|
||||||
public_id: &format!("{}unlisted", public_id),
|
public_id: &format!("{}unlisted", public_id),
|
||||||
visibility: &GistVisibility::Unlisted,
|
visibility: &GistVisibility::Unlisted,
|
||||||
};
|
};
|
||||||
db.new_gist(&create_unlisted_gist).await.unwrap();
|
db.new_gist(&create_unlisted_gist).await.unwrap();
|
||||||
let create_private_gist = CreateGist {
|
let create_private_gist = CreateGist {
|
||||||
owner: username.into(),
|
owner: username,
|
||||||
description: Some("foo"),
|
description: Some("foo"),
|
||||||
public_id: &format!("{}private", public_id),
|
public_id: &format!("{}private", public_id),
|
||||||
visibility: &GistVisibility::Private,
|
visibility: &GistVisibility::Private,
|
||||||
|
@ -186,15 +186,15 @@ pub async fn gists_work<T: GistDatabase>(
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete gist
|
// delete gist
|
||||||
db.delete_gist(username, &create_gist.public_id)
|
db.delete_gist(username, create_gist.public_id)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
db.get_gist(&create_gist.public_id).await.err().unwrap(),
|
db.get_gist(create_gist.public_id).await.err().unwrap(),
|
||||||
DBError::GistNotFound
|
DBError::GistNotFound
|
||||||
));
|
));
|
||||||
assert!(db
|
assert!(db
|
||||||
.get_comments_on_gist(&create_gist.public_id)
|
.get_comments_on_gist(create_gist.public_id)
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_empty());
|
.is_empty());
|
||||||
|
@ -269,7 +269,7 @@ pub async fn duplicate_secret_guard_works<T: GistDatabase>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// check if duplicate username and duplicate email guards are working on update workflows
|
/// check if duplicate username and duplicate email guards are working on update workflows
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub async fn duplicate_username_and_email<T: GistDatabase>(
|
pub async fn duplicate_username_and_email<T: GistDatabase>(
|
||||||
db: &T,
|
db: &T,
|
||||||
username: &str,
|
username: &str,
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
//! # `libadmin` database operations implemented using sqlx postgres
|
//! # `libadmin` database operations implemented using sqlx postgres
|
||||||
//!
|
//!
|
||||||
//! [`GistDatabase`](GistDatabase) is implemented on [Database].
|
//! [`GistDatabase`](GistDatabase) is implemented on [Database].
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use db_core::dev::*;
|
use db_core::dev::*;
|
||||||
|
|
||||||
|
@ -364,7 +365,7 @@ impl GistDatabase for Database {
|
||||||
Error::RowNotFound => DBError::GistNotFound,
|
Error::RowNotFound => DBError::GistNotFound,
|
||||||
e => DBError::DBError(Box::new(e)),
|
e => DBError::DBError(Box::new(e)),
|
||||||
})?;
|
})?;
|
||||||
res.to_gist()
|
res.into_gist()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve gists belonging to user from database
|
/// Retrieve gists belonging to user from database
|
||||||
|
@ -393,7 +394,7 @@ impl GistDatabase for Database {
|
||||||
|
|
||||||
let mut gists = Vec::with_capacity(res.len());
|
let mut gists = Vec::with_capacity(res.len());
|
||||||
for r in res.drain(..) {
|
for r in res.drain(..) {
|
||||||
gists.push(r.to_gist()?);
|
gists.push(r.into_gist()?);
|
||||||
}
|
}
|
||||||
Ok(gists)
|
Ok(gists)
|
||||||
}
|
}
|
||||||
|
@ -429,7 +430,7 @@ impl GistDatabase for Database {
|
||||||
|
|
||||||
let mut gists = Vec::with_capacity(res.len());
|
let mut gists = Vec::with_capacity(res.len());
|
||||||
for r in res.drain(..) {
|
for r in res.drain(..) {
|
||||||
gists.push(r.to_gist()?);
|
gists.push(r.into_gist()?);
|
||||||
}
|
}
|
||||||
Ok(gists)
|
Ok(gists)
|
||||||
}
|
}
|
||||||
|
@ -465,7 +466,7 @@ impl GistDatabase for Database {
|
||||||
|
|
||||||
let mut gists = Vec::with_capacity(res.len());
|
let mut gists = Vec::with_capacity(res.len());
|
||||||
for r in res.drain(..) {
|
for r in res.drain(..) {
|
||||||
gists.push(r.to_gist()?);
|
gists.push(r.into_gist()?);
|
||||||
}
|
}
|
||||||
Ok(gists)
|
Ok(gists)
|
||||||
}
|
}
|
||||||
|
@ -611,7 +612,7 @@ struct InnerGist {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InnerGist {
|
impl InnerGist {
|
||||||
fn to_gist(self) -> DBResult<Gist> {
|
fn into_gist(self) -> DBResult<Gist> {
|
||||||
Ok(Gist {
|
Ok(Gist {
|
||||||
owner: self.owner.unwrap(),
|
owner: self.owner.unwrap(),
|
||||||
description: self.description,
|
description: self.description,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use db_core::dev::*;
|
use db_core::dev::*;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use sqlx::sqlite::SqlitePool;
|
use sqlx::sqlite::SqlitePool;
|
||||||
use sqlx::sqlite::SqlitePoolOptions;
|
use sqlx::sqlite::SqlitePoolOptions;
|
||||||
|
@ -327,7 +328,7 @@ impl GistDatabase for Database {
|
||||||
Error::RowNotFound => DBError::GistNotFound,
|
Error::RowNotFound => DBError::GistNotFound,
|
||||||
e => DBError::DBError(Box::new(e)),
|
e => DBError::DBError(Box::new(e)),
|
||||||
})?;
|
})?;
|
||||||
res.to_gist()
|
res.into_gist()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve gists belonging to user from database
|
/// Retrieve gists belonging to user from database
|
||||||
|
@ -356,7 +357,7 @@ impl GistDatabase for Database {
|
||||||
|
|
||||||
let mut gists = Vec::with_capacity(res.len());
|
let mut gists = Vec::with_capacity(res.len());
|
||||||
for r in res.drain(..) {
|
for r in res.drain(..) {
|
||||||
gists.push(r.to_gist()?);
|
gists.push(r.into_gist()?);
|
||||||
}
|
}
|
||||||
Ok(gists)
|
Ok(gists)
|
||||||
}
|
}
|
||||||
|
@ -392,7 +393,7 @@ impl GistDatabase for Database {
|
||||||
|
|
||||||
let mut gists = Vec::with_capacity(res.len());
|
let mut gists = Vec::with_capacity(res.len());
|
||||||
for r in res.drain(..) {
|
for r in res.drain(..) {
|
||||||
gists.push(r.to_gist()?);
|
gists.push(r.into_gist()?);
|
||||||
}
|
}
|
||||||
Ok(gists)
|
Ok(gists)
|
||||||
}
|
}
|
||||||
|
@ -428,7 +429,7 @@ impl GistDatabase for Database {
|
||||||
|
|
||||||
let mut gists = Vec::with_capacity(res.len());
|
let mut gists = Vec::with_capacity(res.len());
|
||||||
for r in res.drain(..) {
|
for r in res.drain(..) {
|
||||||
gists.push(r.to_gist()?);
|
gists.push(r.into_gist()?);
|
||||||
}
|
}
|
||||||
Ok(gists)
|
Ok(gists)
|
||||||
}
|
}
|
||||||
|
@ -577,7 +578,7 @@ struct InnerGist {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InnerGist {
|
impl InnerGist {
|
||||||
fn to_gist(self) -> DBResult<Gist> {
|
fn into_gist(self) -> DBResult<Gist> {
|
||||||
Ok(Gist {
|
Ok(Gist {
|
||||||
owner: self.owner,
|
owner: self.owner,
|
||||||
description: self.description,
|
description: self.description,
|
||||||
|
|
|
@ -21,10 +21,8 @@ use actix_web::test;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::api::v1::ROUTES;
|
use crate::api::v1::ROUTES;
|
||||||
use crate::data::api::v1::account::*;
|
|
||||||
use crate::data::api::v1::auth::Password;
|
use crate::data::api::v1::auth::Password;
|
||||||
use crate::data::Data;
|
use crate::data::Data;
|
||||||
use crate::errors::*;
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
use crate::tests::*;
|
use crate::tests::*;
|
||||||
|
|
|
@ -38,7 +38,7 @@ impl CreateGistRequest {
|
||||||
pub fn to_create_gist<'a>(&'a self, owner: &'a str) -> CreateGist<'a> {
|
pub fn to_create_gist<'a>(&'a self, owner: &'a str) -> CreateGist<'a> {
|
||||||
CreateGist {
|
CreateGist {
|
||||||
owner,
|
owner,
|
||||||
description: self.description.as_ref().map(|s| s.as_str()),
|
description: self.description.as_deref(),
|
||||||
visibility: &self.visibility,
|
visibility: &self.visibility,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,12 @@ pub fn services(cfg: &mut web::ServiceConfig) {
|
||||||
cfg.service(post_comment);
|
cfg.service(post_comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct CreateGistResp {
|
||||||
|
/// public ID
|
||||||
|
pub id: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[my_codegen::post(
|
#[my_codegen::post(
|
||||||
path = "crate::V1_API_ROUTES.gist.new",
|
path = "crate::V1_API_ROUTES.gist.new",
|
||||||
wrap = "super::get_auth_middleware()"
|
wrap = "super::get_auth_middleware()"
|
||||||
|
@ -70,9 +76,8 @@ async fn new(
|
||||||
&payload.files,
|
&payload.files,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(HttpResponse::TemporaryRedirect()
|
let resp = CreateGistResp { id: gist.id };
|
||||||
.insert_header((http::header::LOCATION, gist.id))
|
Ok(HttpResponse::Ok().json(&resp))
|
||||||
.finish())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[my_codegen::get(path = "crate::V1_API_ROUTES.gist.get_file")]
|
#[my_codegen::get(path = "crate::V1_API_ROUTES.gist.get_file")]
|
||||||
|
@ -212,22 +217,18 @@ mod tests {
|
||||||
.to_request(),
|
.to_request(),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(create_gist_resp.status(), StatusCode::TEMPORARY_REDIRECT);
|
assert_eq!(create_gist_resp.status(), StatusCode::OK);
|
||||||
|
let gist_id: CreateGistResp = test::read_body_json(create_gist_resp).await;
|
||||||
|
let gist_id = gist_id.id;
|
||||||
|
|
||||||
let gist_id = create_gist_resp
|
data.gist_created_test_helper(db, &gist_id, NAME).await;
|
||||||
.headers()
|
data.gist_files_written_helper(db, &gist_id, &files).await;
|
||||||
.get(http::header::LOCATION)
|
|
||||||
.unwrap()
|
|
||||||
.to_str()
|
|
||||||
.unwrap();
|
|
||||||
data.gist_created_test_helper(db, gist_id, NAME).await;
|
|
||||||
data.gist_files_written_helper(db, gist_id, &files).await;
|
|
||||||
|
|
||||||
// get gists
|
// get gists
|
||||||
// 1. Public gists
|
// 1. Public gists
|
||||||
let mut get_file_path = GetFilePath {
|
let mut get_file_path = GetFilePath {
|
||||||
username: NAME.into(),
|
username: NAME.into(),
|
||||||
gist: gist_id.into(),
|
gist: gist_id.clone(),
|
||||||
file: "".into(),
|
file: "".into(),
|
||||||
};
|
};
|
||||||
for file in files.iter() {
|
for file in files.iter() {
|
||||||
|
@ -280,16 +281,11 @@ mod tests {
|
||||||
.to_request(),
|
.to_request(),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(create_gist_resp.status(), StatusCode::TEMPORARY_REDIRECT);
|
assert_eq!(create_gist_resp.status(), StatusCode::OK);
|
||||||
|
let unlisted: CreateGistResp = test::read_body_json(create_gist_resp).await;
|
||||||
|
let unlisted = unlisted.id;
|
||||||
|
|
||||||
let unlisted = create_gist_resp
|
get_file_path.gist = unlisted.clone();
|
||||||
.headers()
|
|
||||||
.get(http::header::LOCATION)
|
|
||||||
.unwrap()
|
|
||||||
.to_str()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
get_file_path.gist = unlisted.into();
|
|
||||||
for file in one_file.iter() {
|
for file in one_file.iter() {
|
||||||
// requesting user is owner
|
// requesting user is owner
|
||||||
get_file_path.file = file.filename.clone();
|
get_file_path.file = file.filename.clone();
|
||||||
|
@ -335,16 +331,11 @@ mod tests {
|
||||||
.to_request(),
|
.to_request(),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(create_gist_resp.status(), StatusCode::TEMPORARY_REDIRECT);
|
assert_eq!(create_gist_resp.status(), StatusCode::OK);
|
||||||
|
let private: CreateGistResp = test::read_body_json(create_gist_resp).await;
|
||||||
|
let private = private.id;
|
||||||
|
|
||||||
let private = create_gist_resp
|
get_file_path.gist = private.clone();
|
||||||
.headers()
|
|
||||||
.get(http::header::LOCATION)
|
|
||||||
.unwrap()
|
|
||||||
.to_str()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
get_file_path.gist = private.into();
|
|
||||||
for file in one_file.iter() {
|
for file in one_file.iter() {
|
||||||
get_file_path.file = file.filename.clone();
|
get_file_path.file = file.filename.clone();
|
||||||
let path = V1_API_ROUTES.gist.get_file_route(&get_file_path);
|
let path = V1_API_ROUTES.gist.get_file_route(&get_file_path);
|
||||||
|
@ -376,14 +367,14 @@ mod tests {
|
||||||
println!("testing comments");
|
println!("testing comments");
|
||||||
let mut create_comment = PostCommentPath {
|
let mut create_comment = PostCommentPath {
|
||||||
username: NAME2.into(),
|
username: NAME2.into(),
|
||||||
gist: gist_id.into(),
|
gist: gist_id.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut comment = PostCommentRequest { comment: "".into() };
|
let mut comment = PostCommentRequest { comment: "".into() };
|
||||||
println!("empty comment");
|
println!("empty comment");
|
||||||
// empty comment
|
// empty comment
|
||||||
data.bad_post_req_test(
|
data.bad_post_req_test(
|
||||||
&db,
|
db,
|
||||||
NAME,
|
NAME,
|
||||||
PASSWORD,
|
PASSWORD,
|
||||||
V1_API_ROUTES.gist.post_comment,
|
V1_API_ROUTES.gist.post_comment,
|
||||||
|
@ -398,17 +389,17 @@ mod tests {
|
||||||
let post_comment_path = V1_API_ROUTES.gist.get_post_comment_route(&create_comment);
|
let post_comment_path = V1_API_ROUTES.gist.get_post_comment_route(&create_comment);
|
||||||
println!("gist not found");
|
println!("gist not found");
|
||||||
data.bad_post_req_test(
|
data.bad_post_req_test(
|
||||||
&db,
|
db,
|
||||||
NAME,
|
NAME,
|
||||||
PASSWORD,
|
PASSWORD,
|
||||||
V1_API_ROUTES.gist.post_comment,
|
&post_comment_path,
|
||||||
&comment,
|
&comment,
|
||||||
ServiceError::GistNotFound,
|
ServiceError::GistNotFound,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
println!("comment OK");
|
println!("comment OK");
|
||||||
create_comment.gist = gist_id.into();
|
create_comment.gist = gist_id;
|
||||||
let post_comment_path = V1_API_ROUTES.gist.get_post_comment_route(&create_comment);
|
let post_comment_path = V1_API_ROUTES.gist.get_post_comment_route(&create_comment);
|
||||||
let resp = test::call_service(
|
let resp = test::call_service(
|
||||||
&app,
|
&app,
|
||||||
|
@ -420,7 +411,7 @@ mod tests {
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
|
|
||||||
println!("comment OK");
|
println!("comment OK");
|
||||||
create_comment.gist = unlisted.into();
|
create_comment.gist = unlisted;
|
||||||
let post_comment_path = V1_API_ROUTES.gist.get_post_comment_route(&create_comment);
|
let post_comment_path = V1_API_ROUTES.gist.get_post_comment_route(&create_comment);
|
||||||
let resp = test::call_service(
|
let resp = test::call_service(
|
||||||
&app,
|
&app,
|
||||||
|
@ -432,7 +423,7 @@ mod tests {
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
|
|
||||||
println!("comment OK");
|
println!("comment OK");
|
||||||
create_comment.gist = private.into();
|
create_comment.gist = private.clone();
|
||||||
let post_comment_path = V1_API_ROUTES.gist.get_post_comment_route(&create_comment);
|
let post_comment_path = V1_API_ROUTES.gist.get_post_comment_route(&create_comment);
|
||||||
let resp = test::call_service(
|
let resp = test::call_service(
|
||||||
&app,
|
&app,
|
||||||
|
@ -445,10 +436,10 @@ mod tests {
|
||||||
|
|
||||||
// commenting on private gist
|
// commenting on private gist
|
||||||
println!("private gist, not OK");
|
println!("private gist, not OK");
|
||||||
create_comment.gist = private.into();
|
create_comment.gist = private.clone();
|
||||||
let post_comment_path = V1_API_ROUTES.gist.get_post_comment_route(&create_comment);
|
let post_comment_path = V1_API_ROUTES.gist.get_post_comment_route(&create_comment);
|
||||||
data.bad_post_req_test(
|
data.bad_post_req_test(
|
||||||
&db,
|
db,
|
||||||
NAME2,
|
NAME2,
|
||||||
PASSWORD,
|
PASSWORD,
|
||||||
&post_comment_path,
|
&post_comment_path,
|
||||||
|
|
|
@ -103,7 +103,7 @@ mod tests {
|
||||||
|
|
||||||
for (db, data) in config.iter() {
|
for (db, data) in config.iter() {
|
||||||
let app = get_app!(data, db).await;
|
let app = get_app!(data, db).await;
|
||||||
let resp = get_request!(&app, &V1_API_ROUTES.meta.health);
|
let resp = get_request!(&app, V1_API_ROUTES.meta.health);
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
|
|
||||||
let health: Health = test::read_body_json(resp).await;
|
let health: Health = test::read_body_json(resp).await;
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
//! V1 API Routes
|
//! V1 API Routes
|
||||||
use actix_auth_middleware::{Authentication, GetLoginRoute};
|
use actix_auth_middleware::GetLoginRoute;
|
||||||
use serde::*;
|
use serde::*;
|
||||||
|
|
||||||
use super::meta::routes::Meta;
|
use super::meta::routes::Meta;
|
||||||
|
@ -168,9 +168,9 @@ impl Routes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_auth_middleware() -> Authentication<Routes> {
|
//pub fn get_auth_middleware() -> Authentication<Routes> {
|
||||||
Authentication::with_identity(ROUTES)
|
// Authentication::with_identity(ROUTES)
|
||||||
}
|
//}
|
||||||
|
|
||||||
impl GetLoginRoute for Routes {
|
impl GetLoginRoute for Routes {
|
||||||
fn get_login_route(&self, src: Option<&str>) -> String {
|
fn get_login_route(&self, src: Option<&str>) -> String {
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
//! Account management utility datastructures and methods
|
//! Account management utility datastructures and methods
|
||||||
use core::panic;
|
|
||||||
|
|
||||||
use db_core::prelude::*;
|
use db_core::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,12 @@ impl From<&'_ TreeEntry<'_>> for GitFileMode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<TreeEntry<'_>> for GitFileMode {
|
||||||
|
fn from(t: TreeEntry) -> Self {
|
||||||
|
GitFileMode::from(t.filemode() as isize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Gist {
|
pub struct Gist {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub repository: git2::Repository,
|
pub repository: git2::Repository,
|
||||||
|
@ -194,7 +200,7 @@ impl Data {
|
||||||
let escaped_filename = escape_spaces(&file.filename);
|
let escaped_filename = escape_spaces(&file.filename);
|
||||||
|
|
||||||
match &file.content {
|
match &file.content {
|
||||||
FileType::Dir(dir_contents) => unimplemented!(),
|
FileType::Dir(_dir_contents) => unimplemented!(),
|
||||||
FileType::File(f) => {
|
FileType::File(f) => {
|
||||||
let obj = odb.write(ObjectType::Blob, f.as_bytes()).unwrap();
|
let obj = odb.write(ObjectType::Blob, f.as_bytes()).unwrap();
|
||||||
tree_builder
|
tree_builder
|
||||||
|
@ -260,8 +266,6 @@ impl Data {
|
||||||
let head = repo.head().unwrap();
|
let head = repo.head().unwrap();
|
||||||
let tree = head.peel_to_tree().unwrap();
|
let tree = head.peel_to_tree().unwrap();
|
||||||
let entry = tree.get_path(Path::new(path)).unwrap();
|
let entry = tree.get_path(Path::new(path)).unwrap();
|
||||||
GitFileMode::Regular as i32;
|
|
||||||
|
|
||||||
fn read_file(id: Oid, repo: &git2::Repository) -> FileType {
|
fn read_file(id: Oid, repo: &git2::Repository) -> FileType {
|
||||||
let blob = repo.find_blob(id).unwrap();
|
let blob = repo.find_blob(id).unwrap();
|
||||||
FileType::File(ContentType::from_blob(&blob))
|
FileType::File(ContentType::from_blob(&blob))
|
||||||
|
@ -271,8 +275,9 @@ impl Data {
|
||||||
let tree = repo.find_tree(id).unwrap();
|
let tree = repo.find_tree(id).unwrap();
|
||||||
let mut items = Vec::with_capacity(tree.len());
|
let mut items = Vec::with_capacity(tree.len());
|
||||||
for item in tree.iter() {
|
for item in tree.iter() {
|
||||||
println!("{:?}", &item.name());
|
println!("{:?}", item.name());
|
||||||
if let Some(name) = item.name() {
|
if let Some(name) = item.name() {
|
||||||
|
#[allow(clippy::needless_borrow)]
|
||||||
let mode: GitFileMode = (&item).into();
|
let mode: GitFileMode = (&item).into();
|
||||||
let file = match mode {
|
let file = match mode {
|
||||||
GitFileMode::Dir => read_dir(item.id(), repo),
|
GitFileMode::Dir => read_dir(item.id(), repo),
|
||||||
|
@ -292,7 +297,7 @@ impl Data {
|
||||||
}
|
}
|
||||||
FileType::Dir(items)
|
FileType::Dir(items)
|
||||||
}
|
}
|
||||||
let mode: GitFileMode = (&entry).into();
|
let mode: GitFileMode = entry.clone().into();
|
||||||
if let Some(name) = entry.name() {
|
if let Some(name) = entry.name() {
|
||||||
let file = match mode {
|
let file = match mode {
|
||||||
GitFileMode::Dir => read_dir(entry.id(), repo),
|
GitFileMode::Dir => read_dir(entry.id(), repo),
|
||||||
|
@ -337,7 +342,7 @@ pub mod tests {
|
||||||
) {
|
) {
|
||||||
let path = self.get_repository_path(gist_id);
|
let path = self.get_repository_path(gist_id);
|
||||||
assert!(path.exists());
|
assert!(path.exists());
|
||||||
assert!(db.gist_exists(&gist_id).await.unwrap());
|
assert!(db.gist_exists(gist_id).await.unwrap());
|
||||||
let repo = Repository::open(&path).unwrap();
|
let repo = Repository::open(&path).unwrap();
|
||||||
assert!(repo.is_bare());
|
assert!(repo.is_bare());
|
||||||
assert_eq!(db.get_gist(gist_id).await.unwrap().owner, owner);
|
assert_eq!(db.get_gist(gist_id).await.unwrap().owner, owner);
|
||||||
|
@ -351,7 +356,7 @@ pub mod tests {
|
||||||
) {
|
) {
|
||||||
for file in files.iter() {
|
for file in files.iter() {
|
||||||
let content = self
|
let content = self
|
||||||
.read_file(db, GistID::ID(&gist_id), &escape_spaces(&file.filename))
|
.read_file(db, GistID::ID(gist_id), &escape_spaces(&file.filename))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let req_escaped_file = FileInfo {
|
let req_escaped_file = FileInfo {
|
||||||
|
|
|
@ -47,7 +47,7 @@ impl Data {
|
||||||
#[cfg(not(tarpaulin_include))]
|
#[cfg(not(tarpaulin_include))]
|
||||||
/// create new instance of app data
|
/// create new instance of app data
|
||||||
pub fn new(settings: Option<Settings>) -> Arc<Self> {
|
pub fn new(settings: Option<Settings>) -> Arc<Self> {
|
||||||
let settings = settings.unwrap_or(Settings::new().unwrap());
|
let settings = settings.unwrap_or_else(|| Settings::new().unwrap());
|
||||||
let creds = Self::get_creds();
|
let creds = Self::get_creds();
|
||||||
let c = creds.clone();
|
let c = creds.clone();
|
||||||
|
|
||||||
|
|
14
src/demo.rs
14
src/demo.rs
|
@ -20,8 +20,6 @@ use std::time::Duration;
|
||||||
use tokio::spawn;
|
use tokio::spawn;
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
|
|
||||||
use db_core::GistDatabase;
|
|
||||||
|
|
||||||
use crate::data::api::v1::auth::Register;
|
use crate::data::api::v1::auth::Register;
|
||||||
use crate::db::BoxDB;
|
use crate::db::BoxDB;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
@ -90,21 +88,17 @@ mod tests {
|
||||||
async fn postgrest_demo_works() {
|
async fn postgrest_demo_works() {
|
||||||
let (db, data) = sqlx_postgres::get_data().await;
|
let (db, data) = sqlx_postgres::get_data().await;
|
||||||
let (db2, _) = sqlx_postgres::get_data().await;
|
let (db2, _) = sqlx_postgres::get_data().await;
|
||||||
demo_account_works(data, &db, db2).await;
|
demo_account_works(data, &db, &db2).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn sqlite_demo_works() {
|
async fn sqlite_demo_works() {
|
||||||
let (db, data) = sqlx_sqlite::get_data().await;
|
let (db, data) = sqlx_sqlite::get_data().await;
|
||||||
let (db2, _) = sqlx_sqlite::get_data().await;
|
let (db2, _) = sqlx_sqlite::get_data().await;
|
||||||
demo_account_works(data, &db, db2).await;
|
demo_account_works(data, &db, &db2).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn demo_account_works(
|
async fn demo_account_works(data: Arc<Data>, db: &BoxDB, db2: &BoxDB) {
|
||||||
data: Arc<Data>,
|
|
||||||
db: &Box<dyn GistDatabase>,
|
|
||||||
db2: Box<dyn GistDatabase>,
|
|
||||||
) {
|
|
||||||
let _ = data.delete_user(db, DEMO_USER, DEMO_PASSWORD).await;
|
let _ = data.delete_user(db, DEMO_USER, DEMO_PASSWORD).await;
|
||||||
let data = AppData::new(data);
|
let data = AppData::new(data);
|
||||||
let duration = Duration::from_secs(DURATION);
|
let duration = Duration::from_secs(DURATION);
|
||||||
|
@ -121,7 +115,7 @@ mod tests {
|
||||||
// deletion works
|
// deletion works
|
||||||
assert!(super::delete_demo_user(db, &data).await.is_ok());
|
assert!(super::delete_demo_user(db, &data).await.is_ok());
|
||||||
assert!(!data.username_exists(db, DEMO_USER).await.unwrap().exists);
|
assert!(!data.username_exists(db, DEMO_USER).await.unwrap().exists);
|
||||||
run(db2, data.clone(), duration).await.unwrap();
|
run(db2.clone(), data.clone(), duration).await.unwrap();
|
||||||
|
|
||||||
sleep(Duration::from_secs(DURATION)).await;
|
sleep(Duration::from_secs(DURATION)).await;
|
||||||
assert!(data.username_exists(db, DEMO_USER).await.unwrap().exists);
|
assert!(data.username_exists(db, DEMO_USER).await.unwrap().exists);
|
||||||
|
|
13
src/utils.rs
13
src/utils.rs
|
@ -14,12 +14,6 @@
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
use tokio::fs;
|
|
||||||
|
|
||||||
use crate::errors::*;
|
|
||||||
|
|
||||||
/// Get random string of specific length
|
/// Get random string of specific length
|
||||||
pub(crate) fn get_random(len: usize) -> String {
|
pub(crate) fn get_random(len: usize) -> String {
|
||||||
use rand::{distributions::Alphanumeric, rngs::ThreadRng, thread_rng, Rng};
|
use rand::{distributions::Alphanumeric, rngs::ThreadRng, thread_rng, Rng};
|
||||||
|
@ -34,13 +28,6 @@ pub(crate) fn get_random(len: usize) -> String {
|
||||||
.collect::<String>()
|
.collect::<String>()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_dir_all_if_not_exists(path: &Path) -> ServiceResult<()> {
|
|
||||||
if !path.exists() {
|
|
||||||
fs::create_dir_all(&path).await?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn escape_spaces(name: &str) -> String {
|
pub fn escape_spaces(name: &str) -> String {
|
||||||
if name.contains(' ') {
|
if name.contains(' ') {
|
||||||
name.replace(' ', "\\ ")
|
name.replace(' ', "\\ ")
|
||||||
|
|
Loading…
Reference in New Issue