feat: test for unique event names and return event IDs on update API calls

This commit is contained in:
Aravinth Manivannan 2022-11-15 20:51:34 +05:30
parent f89b3e6d4c
commit 20c3ee1f11
Signed by: realaravinth
GPG key ID: AD9F0F08E855ED88
4 changed files with 115 additions and 8 deletions

View file

@ -1,5 +1,20 @@
{ {
"db": "PostgreSQL", "db": "PostgreSQL",
"14cdc724af64942e93994f97e9eafc8272d15605eff7aab9e5177d01f2bf6118": {
"describe": {
"columns": [],
"nullable": [],
"parameters": {
"Left": [
"Text",
"Timestamptz",
"Text",
"Uuid"
]
}
},
"query": "INSERT INTO librepages_site_deploy_events\n (event_type, time, site, pub_id) VALUES (\n (SELECT iD from librepages_deploy_event_type WHERE name = $1),\n $2,\n (SELECT ID from librepages_sites WHERE hostname = $3),\n $4\n );\n "
},
"1ac91b492001493430c686d9cd7d6be03ada4b4c431d7bc112ef2105eba0e82d": { "1ac91b492001493430c686d9cd7d6be03ada4b4c431d7bc112ef2105eba0e82d": {
"describe": { "describe": {
"columns": [ "columns": [
@ -97,6 +112,39 @@
}, },
"query": "SELECT EXISTS (SELECT 1 from librepages_sites WHERE hostname = $1)" "query": "SELECT EXISTS (SELECT 1 from librepages_sites WHERE hostname = $1)"
}, },
"39854fcbfb0247377c6c5ca70c2c0fa7804548848bf56f881eea2f8242e7a09d": {
"describe": {
"columns": [
{
"name": "name",
"ordinal": 0,
"type_info": "Varchar"
},
{
"name": "time",
"ordinal": 1,
"type_info": "Timestamptz"
},
{
"name": "pub_id",
"ordinal": 2,
"type_info": "Uuid"
}
],
"nullable": [
false,
false,
false
],
"parameters": {
"Left": [
"Text",
"Uuid"
]
}
},
"query": "SELECT\n librepages_deploy_event_type.name,\n librepages_site_deploy_events.time,\n librepages_site_deploy_events.pub_id\n FROM\n librepages_site_deploy_events\n INNER JOIN librepages_deploy_event_type ON\n librepages_deploy_event_type.ID = librepages_site_deploy_events.event_type\n WHERE\n librepages_site_deploy_events.site = (\n SELECT ID FROM librepages_sites WHERE hostname = $1\n )\n AND\n librepages_site_deploy_events.pub_id = $2\n "
},
"416b9f0412f0d7ee05d4a350839c5a6d1e06c1d7f8942744f6d806ddc47084c2": { "416b9f0412f0d7ee05d4a350839c5a6d1e06c1d7f8942744f6d806ddc47084c2": {
"describe": { "describe": {
"columns": [], "columns": [],
@ -347,6 +395,38 @@
}, },
"query": "SELECT email FROM librepages_users WHERE name = $1" "query": "SELECT email FROM librepages_users WHERE name = $1"
}, },
"d2327c1bcb40e18518c2112413a19a9b26eb0f54f83c53e968c9752d70c8dd4e": {
"describe": {
"columns": [
{
"name": "name",
"ordinal": 0,
"type_info": "Varchar"
},
{
"name": "time",
"ordinal": 1,
"type_info": "Timestamptz"
},
{
"name": "pub_id",
"ordinal": 2,
"type_info": "Uuid"
}
],
"nullable": [
false,
false,
false
],
"parameters": {
"Left": [
"Text"
]
}
},
"query": "SELECT\n librepages_deploy_event_type.name,\n librepages_site_deploy_events.time,\n librepages_site_deploy_events.pub_id\n FROM\n librepages_site_deploy_events\n INNER JOIN librepages_deploy_event_type ON\n librepages_deploy_event_type.ID = librepages_site_deploy_events.event_type\n WHERE\n librepages_site_deploy_events.site = (\n SELECT ID FROM librepages_sites WHERE hostname = $1\n );\n "
},
"e4adf1bc9175eeb9d61b495653bb452039cc38818c8792acdc6a1c732b6f4554": { "e4adf1bc9175eeb9d61b495653bb452039cc38818c8792acdc6a1c732b6f4554": {
"describe": { "describe": {
"columns": [ "columns": [
@ -367,7 +447,7 @@
}, },
"query": "SELECT EXISTS (SELECT 1 from librepages_deploy_event_type WHERE name = $1)" "query": "SELECT EXISTS (SELECT 1 from librepages_deploy_event_type WHERE name = $1)"
}, },
"ed935cd75e805ddd7223ea8ba298ff94018cf305c519120279a5d1f7bb99e23e": { "f651da8f411b7977cb87dd8d4bd5d167661d7ef1d865747e76219453d386d593": {
"describe": { "describe": {
"columns": [], "columns": [],
"nullable": [], "nullable": [],
@ -377,7 +457,7 @@
] ]
} }
}, },
"query": "INSERT INTO librepages_deploy_event_type\n (name) VALUES ($1);" "query": "INSERT INTO librepages_deploy_event_type\n (name) VALUES ($1) ON CONFLICT (name) DO NOTHING;"
}, },
"faa4170a309f19a4abf1ca3f8dd3c0526945aa00f028ebf8bd7063825d448f5b": { "faa4170a309f19a4abf1ca3f8dd3c0526945aa00f028ebf8bd7063825d448f5b": {
"describe": { "describe": {

View file

@ -17,8 +17,10 @@
use actix_web::web; use actix_web::web;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tokio::sync::oneshot; use tokio::sync::oneshot;
use uuid::Uuid;
use crate::ctx::Ctx; use crate::ctx::Ctx;
use crate::db;
use crate::db::Site; use crate::db::Site;
use crate::errors::*; use crate::errors::*;
use crate::page::Page; use crate::page::Page;
@ -58,10 +60,13 @@ impl Ctx {
if let Some(_config) = page_config::Config::load(&page.path, &page.branch) { if let Some(_config) = page_config::Config::load(&page.path, &page.branch) {
unimplemented!(); unimplemented!();
} }
self.db
.log_event(&page.domain, &db::EVENT_TYPE_CREATE)
.await?;
Ok(page) Ok(page)
} }
pub async fn update_site(&self, secret: &str, branch: Option<String>) -> ServiceResult<()> { pub async fn update_site(&self, secret: &str, branch: Option<String>) -> ServiceResult<Uuid> {
if let Ok(db_site) = self.db.get_site_from_secret(secret).await { if let Ok(db_site) = self.db.get_site_from_secret(secret).await {
let page = Page::from_site(&self.settings, db_site); let page = Page::from_site(&self.settings, db_site);
let (tx, rx) = oneshot::channel(); let (tx, rx) = oneshot::channel();
@ -81,7 +86,10 @@ impl Ctx {
if let Some(_config) = page_config::Config::load(&page.path, &page.branch) { if let Some(_config) = page_config::Config::load(&page.path, &page.branch) {
unimplemented!(); unimplemented!();
} }
Ok(()) println!("{}", page.domain);
self.db
.log_event(&page.domain, &db::EVENT_TYPE_UPDATE)
.await
} else { } else {
Err(ServiceError::WebsiteNotFound) Err(ServiceError::WebsiteNotFound)
} }

View file

@ -408,7 +408,7 @@ impl Database {
if !self.event_type_exists(&e).await? { if !self.event_type_exists(&e).await? {
sqlx::query!( sqlx::query!(
"INSERT INTO librepages_deploy_event_type "INSERT INTO librepages_deploy_event_type
(name) VALUES ($1);", (name) VALUES ($1) ON CONFLICT (name) DO NOTHING;",
e.name e.name
) )
.execute(&self.pool) .execute(&self.pool)
@ -603,7 +603,7 @@ pub const EVENT_TYPE_CREATE: Event = Event::new("site.event.create");
pub const EVENT_TYPE_UPDATE: Event = Event::new("site.event.update"); pub const EVENT_TYPE_UPDATE: Event = Event::new("site.event.update");
pub const EVENT_TYPE_DELETE: Event = Event::new("site.event.delete"); pub const EVENT_TYPE_DELETE: Event = Event::new("site.event.delete");
pub const EVENTS: [Event; 3] = [EVENT_TYPE_DELETE, EVENT_TYPE_DELETE, EVENT_TYPE_CREATE]; pub const EVENTS: [Event; 3] = [EVENT_TYPE_CREATE, EVENT_TYPE_DELETE, EVENT_TYPE_UPDATE];
struct InnerLibrepagesEvent { struct InnerLibrepagesEvent {
name: String, name: String,
@ -671,9 +671,17 @@ fn map_register_err(e: sqlx::Error) -> ServiceError {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::collections::HashSet;
use super::*; use super::*;
use crate::settings::Settings; use crate::settings::Settings;
#[test]
fn event_names_are_unique() {
let mut uniq = HashSet::new();
assert!(EVENTS.into_iter().all(move |x| uniq.insert(x.name)));
}
#[actix_rt::test] #[actix_rt::test]
async fn db_works() { async fn db_works() {
let settings = Settings::new().unwrap(); let settings = Settings::new().unwrap();

View file

@ -16,6 +16,7 @@
*/ */
use actix_web::{web, HttpResponse, Responder}; use actix_web::{web, HttpResponse, Responder};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::errors::*; use crate::errors::*;
use crate::page::Page; use crate::page::Page;
@ -43,13 +44,19 @@ pub struct DeployEvent {
pub branch: String, pub branch: String,
} }
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct DeployEventResp {
pub id: Uuid,
}
#[actix_web_codegen_const_routes::post(path = "crate::V1_API_ROUTES.deploy.update")] #[actix_web_codegen_const_routes::post(path = "crate::V1_API_ROUTES.deploy.update")]
#[tracing::instrument(name = "Update webpages", skip(payload, ctx))] #[tracing::instrument(name = "Update webpages", skip(payload, ctx))]
async fn update(payload: web::Json<DeployEvent>, ctx: AppCtx) -> ServiceResult<impl Responder> { async fn update(payload: web::Json<DeployEvent>, ctx: AppCtx) -> ServiceResult<impl Responder> {
let payload = payload.into_inner(); let payload = payload.into_inner();
ctx.update_site(&payload.secret, Some(payload.branch)) let id = ctx
.update_site(&payload.secret, Some(payload.branch))
.await?; .await?;
Ok(HttpResponse::Ok()) Ok(HttpResponse::Ok().json(DeployEventResp { id }))
} }
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)] #[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
@ -131,6 +138,10 @@ mod tests {
) )
.await; .await;
check_status!(resp, StatusCode::OK); check_status!(resp, StatusCode::OK);
let event_id: DeployEventResp = actix_web::test::read_body_json(resp).await;
let update_event = ctx.db.get_event(&page.domain, &event_id.id).await.unwrap();
assert_eq!(&update_event.site, &page.domain);
assert_eq!(update_event.id, event_id.id);
payload.secret = page.branch.clone(); payload.secret = page.branch.clone();