mirror of https://github.com/realaravinth/gitpad
feat: gist creation form
parent
ff01303bea
commit
b698884b49
|
@ -41,6 +41,7 @@ pub fn register_templates(t: &mut tera::Tera) {
|
|||
|
||||
pub fn services(cfg: &mut web::ServiceConfig) {
|
||||
cfg.service(new);
|
||||
cfg.service(new_submit);
|
||||
}
|
||||
|
||||
pub struct NewGist {
|
||||
|
@ -84,7 +85,6 @@ impl NewGist {
|
|||
ctx.insert(PAYLOAD_KEY, &[FieldNames::<&'static str>::default()]);
|
||||
}
|
||||
|
||||
println!("{:?}", ctx.get(PAYLOAD_KEY));
|
||||
let ctx = RefCell::new(ctx);
|
||||
Self { ctx }
|
||||
}
|
||||
|
@ -200,6 +200,117 @@ fn get_description(payload: &serde_json::Value) -> Option<&str> {
|
|||
None
|
||||
}
|
||||
|
||||
fn is_add_file(payload: &serde_json::Value) -> bool {
|
||||
payload.get("add_file").is_some()
|
||||
}
|
||||
|
||||
struct FormExtractedData<'a> {
|
||||
description: Option<&'a str>,
|
||||
visibility: GistVisibility,
|
||||
files: Vec<FieldNames<&'a str>>,
|
||||
username: String,
|
||||
}
|
||||
|
||||
fn extract_form<'a>(
|
||||
id: &Identity,
|
||||
data: &AppData,
|
||||
payload: &'a serde_json::Value,
|
||||
) -> PageResult<FormExtractedData<'a>, NewGist> {
|
||||
let username = id.identity().unwrap();
|
||||
let description = get_description(payload);
|
||||
let gist = FieldNames::<&str>::from_serde_json(payload).map_err(|(resp, e)| {
|
||||
PageError::new(
|
||||
NewGist::new(&username, &data.settings, description, Some(&resp)),
|
||||
e,
|
||||
)
|
||||
})?;
|
||||
let visibility = get_visibility(payload)
|
||||
.map_err(|e| map_err(&username, data, description, Some(&gist), e))?;
|
||||
let resp = FormExtractedData {
|
||||
description,
|
||||
visibility,
|
||||
files: gist,
|
||||
username,
|
||||
};
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
fn map_err(
|
||||
username: &str,
|
||||
data: &AppData,
|
||||
description: Option<&str>,
|
||||
gist: Option<&[FieldNames<&str>]>,
|
||||
e: ServiceError,
|
||||
) -> PageError<NewGist> {
|
||||
PageError::new(NewGist::new(username, &data.settings, description, gist), e)
|
||||
}
|
||||
|
||||
#[my_codegen::post(path = "PAGES.gist.new", wrap = "super::get_auth_middleware()")]
|
||||
async fn new_submit(
|
||||
data: AppData,
|
||||
db: crate::DB,
|
||||
payload: web::Form<serde_json::Value>,
|
||||
id: Identity,
|
||||
) -> PageResult<impl Responder, NewGist> {
|
||||
let mut form_data = extract_form(&id, &data, &payload)?;
|
||||
let html = ContentType::html();
|
||||
|
||||
if is_add_file(&payload) {
|
||||
form_data.files.push(FieldNames::<&str>::default());
|
||||
let page = NewGist::new(
|
||||
&form_data.username,
|
||||
&data.settings,
|
||||
form_data.description,
|
||||
Some(&form_data.files),
|
||||
)
|
||||
.render();
|
||||
return Ok(HttpResponse::Ok().content_type(html).body(page));
|
||||
};
|
||||
|
||||
let mut files: Vec<FileInfo> = Vec::with_capacity(form_data.files.len());
|
||||
form_data
|
||||
.files
|
||||
.clone()
|
||||
.drain(..)
|
||||
.for_each(|f| files.push(f.into()));
|
||||
|
||||
let map_err = |e: ServiceError| -> PageError<NewGist> {
|
||||
map_err(
|
||||
&form_data.username,
|
||||
&data,
|
||||
form_data.description,
|
||||
Some(&form_data.files),
|
||||
e,
|
||||
)
|
||||
};
|
||||
let msg = CreateGist {
|
||||
owner: &form_data.username,
|
||||
description: form_data.description,
|
||||
visibility: &form_data.visibility,
|
||||
};
|
||||
|
||||
let mut db_gist = data.new_gist(db.as_ref(), &msg).await.map_err(&map_err)?;
|
||||
|
||||
data.write_file(
|
||||
db.as_ref(),
|
||||
GistID::Repository(&mut db_gist.repository),
|
||||
&files,
|
||||
)
|
||||
.await
|
||||
.map_err(&map_err)?;
|
||||
|
||||
Ok(HttpResponse::Found()
|
||||
.insert_header((
|
||||
http::header::LOCATION,
|
||||
PAGES.gist.get_gist_route(&PostCommentPath {
|
||||
username: form_data.username,
|
||||
gist: db_gist.id,
|
||||
}),
|
||||
))
|
||||
.finish())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json::json;
|
||||
|
@ -324,5 +435,8 @@ mod tests {
|
|||
f.content,
|
||||
FileType::File(GistContentType::Text(fields1.content.to_owned()))
|
||||
);
|
||||
|
||||
assert!(!is_add_file(&json!({ "foo": "bar"})));
|
||||
assert!(is_add_file(&json!({ "add_file": "bar"})));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,20 +17,22 @@
|
|||
use actix_web::http::StatusCode;
|
||||
use actix_web::test;
|
||||
|
||||
use super::*;
|
||||
use db_core::prelude::*;
|
||||
|
||||
use super::new::*;
|
||||
|
||||
use crate::data::Data;
|
||||
use crate::tests::*;
|
||||
use crate::*;
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn postgres_gists_work() {
|
||||
async fn postgres_pages_gists_work() {
|
||||
let (db, data) = sqlx_postgres::get_data().await;
|
||||
gists_new_route_works(data.clone(), db.clone()).await;
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn sqlite_gists_work() {
|
||||
async fn sqlite_pages_gists_work() {
|
||||
let (db, data) = sqlx_sqlite::get_data().await;
|
||||
gists_new_route_works(data.clone(), db.clone()).await;
|
||||
}
|
||||
|
@ -48,4 +50,40 @@ async fn gists_new_route_works(data: Arc<Data>, db: BoxDB) {
|
|||
let app = get_app!(data, db).await;
|
||||
let new_gist = get_request!(&app, PAGES.gist.new, cookies.clone());
|
||||
assert_eq!(new_gist.status(), StatusCode::OK);
|
||||
let files = FieldNames::<String>::new(1);
|
||||
|
||||
// create gist
|
||||
let payload = serde_json::json!({
|
||||
"description": "",
|
||||
"visibility": GistVisibility::Private.to_str(),
|
||||
files.filename.clone() : "foo.md",
|
||||
files.content.clone() : "foo.md",
|
||||
});
|
||||
|
||||
let resp = test::call_service(
|
||||
&app,
|
||||
post_request!(&payload, PAGES.gist.new, FORM)
|
||||
.cookie(cookies.clone())
|
||||
.to_request(),
|
||||
)
|
||||
.await;
|
||||
assert_eq!(resp.status(), StatusCode::FOUND);
|
||||
|
||||
// add new file during gist creation
|
||||
let payload = serde_json::json!({
|
||||
"description": "",
|
||||
"visibility": GistVisibility::Private.to_str(),
|
||||
files.filename.clone() : "foo.md",
|
||||
files.content.clone() : "foo.md",
|
||||
"add_file": "",
|
||||
});
|
||||
|
||||
let resp = test::call_service(
|
||||
&app,
|
||||
post_request!(&payload, PAGES.gist.new, FORM)
|
||||
.cookie(cookies)
|
||||
.to_request(),
|
||||
)
|
||||
.await;
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue