From 303a4ab0bae27fd58df5d23aacc46dbb2bca7209 Mon Sep 17 00:00:00 2001 From: realaravinth Date: Mon, 14 Feb 2022 22:42:23 +0530 Subject: [PATCH] feat: helper method Data::new_gist to create new gist and tests DESCRIPTION Data::new_gist creates a bare repository in the supplied Data.settings.repository.root directory and saves metadata in the database See accompanying test for usage --- Cargo.toml | 4 +- database/db-core/src/tests.rs | 7 ++- src/data/api/v1/gists.rs | 114 ++++++++++++++++++++++++++++++++++ src/data/api/v1/mod.rs | 1 + 4 files changed, 121 insertions(+), 5 deletions(-) create mode 100644 src/data/api/v1/gists.rs diff --git a/Cargo.toml b/Cargo.toml index 32479c5..fd0d3b8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,12 +43,10 @@ rand = "0.8.4" serde = { version = "1", features = ["derive"]} serde_json = "1" sqlx = { version = "0.5.10", features = [ "runtime-actix-rustls", "uuid", "postgres", "time", "offline", "sqlite" ] } -tokio = "1.16.1" +tokio = { version = "1.16.1", features = ["fs"] } url = "2.2" urlencoding = "2.1.0" validator = { version = "0.14.0", features = ["derive"] } - - [dev-dependencies] actix-rt = "2" diff --git a/database/db-core/src/tests.rs b/database/db-core/src/tests.rs index d967dc7..1a65d40 100644 --- a/database/db-core/src/tests.rs +++ b/database/db-core/src/tests.rs @@ -69,7 +69,10 @@ pub async fn gists_work( } fn assert_gists(lhs: &CreateGist, rhs: &Gist) { - assert_eq!(lhs.description.as_ref().unwrap(), rhs.description.as_ref().unwrap()); + assert_eq!( + lhs.description.as_ref().unwrap(), + rhs.description.as_ref().unwrap() + ); assert_eq!(lhs.owner, rhs.owner); assert_eq!(lhs.public_id, rhs.public_id); assert_eq!(lhs.visibility, &rhs.visibility); @@ -114,7 +117,7 @@ pub async fn gists_work( // comment on gist let create_comment = CreateGistComment { owner: username.into(), - gist_public_id: create_gist.public_id.clone(), + gist_public_id: create_gist.public_id, comment: "foo".into(), }; db.new_comment(&create_comment).await.unwrap(); diff --git a/src/data/api/v1/gists.rs b/src/data/api/v1/gists.rs new file mode 100644 index 0000000..ccd0192 --- /dev/null +++ b/src/data/api/v1/gists.rs @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2022 Aravinth Manivannan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +use std::path::Path; + +use db_core::prelude::*; +use git2::*; +use tokio::fs; + +use super::*; +use crate::errors::*; +use crate::utils::*; +use crate::*; + +pub struct Gist { + pub id: String, + pub repository: git2::Repository, +} + +pub struct CreateGist<'a>{ + pub owner: &'a str, + pub description: Option<&'a str>, + pub visibility: &'a GistVisibility, + } + +impl Data { + pub async fn new_gist(&self, db: &T, msg: &CreateGist<'_>) -> ServiceResult { + loop { + let gist_id = get_random(32); + + if db.gist_exists(&gist_id).await? { + continue; + } + + let gist_path = Path::new(&self.settings.repository.root).join(&gist_id); + + if gist_path.exists() { + if Repository::open(&gist_path).is_ok() { + continue; + } + fs::remove_dir_all(&gist_path).await?; + } + + let create_gist = db_core::CreateGist { + owner: msg.owner, + description: msg.description, + visibility: msg.visibility, + public_id: &gist_id, + }; + + db.new_gist(&create_gist).await.unwrap(); + + fs::create_dir(&gist_path).await?; + return Ok(Gist { + id: gist_id, + repository: Repository::init_bare(&gist_path).unwrap(), + }); + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests::*; + + #[actix_rt::test] + async fn test_new_gist_works() { + let config = [ + sqlx_postgres::get_data().await, + sqlx_sqlite::get_data().await, + ]; + + for (db, data) in config.iter() { + + const NAME: &str = "gisttestuser"; + const EMAIL: &str = "gisttestuser@sss.com"; + const PASSWORD: &str = "longpassword2"; + + let _ = futures::join!( + data.delete_user(db, NAME, PASSWORD), + ); + + let _ = data.register_and_signin(db, NAME, EMAIL, PASSWORD).await; + + + let create_gist_msg = CreateGist { + owner: NAME, + description: None, + visibility: &GistVisibility::Public, + }; + let gist = data.new_gist(db, &create_gist_msg).await.unwrap(); + let path = Path::new(&data.settings.repository.root).join(&gist.id); + assert!(path.exists()); + assert!(db.gist_exists(&gist.id).await.unwrap()); + let repo = Repository::open(&path).unwrap(); + assert!(repo.is_bare()); + assert!(repo.is_empty().unwrap()); + } + } +} diff --git a/src/data/api/v1/mod.rs b/src/data/api/v1/mod.rs index ecb954b..083382e 100644 --- a/src/data/api/v1/mod.rs +++ b/src/data/api/v1/mod.rs @@ -16,5 +16,6 @@ */ pub mod account; pub mod auth; +pub mod gists; pub(crate) use crate::utils::get_random;