From 20c3ee1f11ea4cb6fa75a7dbce13d952f01bab8b Mon Sep 17 00:00:00 2001 From: Aravinth Manivannan Date: Tue, 15 Nov 2022 20:51:34 +0530 Subject: [PATCH] feat: test for unique event names and return event IDs on update API calls --- sqlx-data.json | 84 ++++++++++++++++++++++++++++++++++++++++- src/ctx/api/v1/pages.rs | 12 +++++- src/db.rs | 12 +++++- src/deploy.rs | 15 +++++++- 4 files changed, 115 insertions(+), 8 deletions(-) diff --git a/sqlx-data.json b/sqlx-data.json index d284c65..76487ff 100644 --- a/sqlx-data.json +++ b/sqlx-data.json @@ -1,5 +1,20 @@ { "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": { "describe": { "columns": [ @@ -97,6 +112,39 @@ }, "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": { "describe": { "columns": [], @@ -347,6 +395,38 @@ }, "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": { "describe": { "columns": [ @@ -367,7 +447,7 @@ }, "query": "SELECT EXISTS (SELECT 1 from librepages_deploy_event_type WHERE name = $1)" }, - "ed935cd75e805ddd7223ea8ba298ff94018cf305c519120279a5d1f7bb99e23e": { + "f651da8f411b7977cb87dd8d4bd5d167661d7ef1d865747e76219453d386d593": { "describe": { "columns": [], "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": { "describe": { diff --git a/src/ctx/api/v1/pages.rs b/src/ctx/api/v1/pages.rs index 5e711f9..abbdf83 100644 --- a/src/ctx/api/v1/pages.rs +++ b/src/ctx/api/v1/pages.rs @@ -17,8 +17,10 @@ use actix_web::web; use serde::{Deserialize, Serialize}; use tokio::sync::oneshot; +use uuid::Uuid; use crate::ctx::Ctx; +use crate::db; use crate::db::Site; use crate::errors::*; use crate::page::Page; @@ -58,10 +60,13 @@ impl Ctx { if let Some(_config) = page_config::Config::load(&page.path, &page.branch) { unimplemented!(); } + self.db + .log_event(&page.domain, &db::EVENT_TYPE_CREATE) + .await?; Ok(page) } - pub async fn update_site(&self, secret: &str, branch: Option) -> ServiceResult<()> { + pub async fn update_site(&self, secret: &str, branch: Option) -> ServiceResult { if let Ok(db_site) = self.db.get_site_from_secret(secret).await { let page = Page::from_site(&self.settings, db_site); let (tx, rx) = oneshot::channel(); @@ -81,7 +86,10 @@ impl Ctx { if let Some(_config) = page_config::Config::load(&page.path, &page.branch) { unimplemented!(); } - Ok(()) + println!("{}", page.domain); + self.db + .log_event(&page.domain, &db::EVENT_TYPE_UPDATE) + .await } else { Err(ServiceError::WebsiteNotFound) } diff --git a/src/db.rs b/src/db.rs index a4ee94e..cf2f318 100644 --- a/src/db.rs +++ b/src/db.rs @@ -408,7 +408,7 @@ impl Database { if !self.event_type_exists(&e).await? { sqlx::query!( "INSERT INTO librepages_deploy_event_type - (name) VALUES ($1);", + (name) VALUES ($1) ON CONFLICT (name) DO NOTHING;", e.name ) .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_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 { name: String, @@ -671,9 +671,17 @@ fn map_register_err(e: sqlx::Error) -> ServiceError { #[cfg(test)] mod tests { + use std::collections::HashSet; + use super::*; 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] async fn db_works() { let settings = Settings::new().unwrap(); diff --git a/src/deploy.rs b/src/deploy.rs index 31127c6..69f9e8e 100644 --- a/src/deploy.rs +++ b/src/deploy.rs @@ -16,6 +16,7 @@ */ use actix_web::{web, HttpResponse, Responder}; use serde::{Deserialize, Serialize}; +use uuid::Uuid; use crate::errors::*; use crate::page::Page; @@ -43,13 +44,19 @@ pub struct DeployEvent { 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")] #[tracing::instrument(name = "Update webpages", skip(payload, ctx))] async fn update(payload: web::Json, ctx: AppCtx) -> ServiceResult { let payload = payload.into_inner(); - ctx.update_site(&payload.secret, Some(payload.branch)) + let id = ctx + .update_site(&payload.secret, Some(payload.branch)) .await?; - Ok(HttpResponse::Ok()) + Ok(HttpResponse::Ok().json(DeployEventResp { id })) } #[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)] @@ -131,6 +138,10 @@ mod tests { ) .await; 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();