Skip to content
This repository has been archived by the owner on Aug 13, 2024. It is now read-only.

Commit

Permalink
wip: write some backend tests
Browse files Browse the repository at this point in the history
  • Loading branch information
evoxmusic committed Dec 6, 2023
1 parent 7d5884a commit 1e05501
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 31 deletions.
50 changes: 27 additions & 23 deletions backend/examples/config.yaml
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
catalog:
- slug: new-testing-environment
name: new testing environment
description: spin up a testing environment
icon: https://example.com/icon.png
fields:
- title: environment name
description: provide a name for your environment
placeholder: testing-123
type: string
default: testing-123
required: true
autocomplete-fetcher: ./your-script.py
validation:
- validation-script-1.sh # executed first
- validation-script-2.sh # AND then this one
post-validation:
- script: post-validation-script-1.sh # executed first
model: string (optional) # model name
- script: post-validation-script-2.sh # AND then this one
model: string (optional) # model name
- script: post-validation-script-3.sh # AND finally this one
model: string (optional) # model name
catalogs:
- slug: default
name: Default
description: Default catalog
services:
- slug: new-testing-environment
name: new testing environment
description: spin up a testing environment
icon: https://example.com/icon.png
fields:
- title: environment name
description: provide a name for your environment
placeholder: testing-123
type: string
default: testing-123
required: true
autocomplete-fetcher: ./your-script.py
validation:
- validation-script-1.sh # executed first
- validation-script-2.sh # AND then this one
post-validation:
- script: post-validation-script-1.sh # executed first
model: string (optional) # model name
- script: post-validation-script-2.sh # AND then this one
model: string (optional) # model name
- script: post-validation-script-3.sh # AND finally this one
model: string (optional) # model name
models:
- name: string
description: string (optional)
Expand Down
17 changes: 17 additions & 0 deletions backend/examples/dumb_script_ko.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash


# This script is a dumb example of a script that can be run by the backend.
# It is not meant to be run by the user, but rather by the backend.
set -e

echo "This is a superrrrr powerful script!!!! It does nothing but print this message."

echo "The arguments passed to this script are: $@"

echo "The environment variables set for this script are:"
env

echo "The current working directory is: $(pwd)"

exit 1
17 changes: 17 additions & 0 deletions backend/examples/dumb_script_ok.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash


# This script is a dumb example of a script that can be run by the backend.
# It is not meant to be run by the user, but rather by the backend.
set -e

echo "This is a superrrrr powerful script!!!! It does nothing but print this message."

echo "The arguments passed to this script are: $@"

echo "The environment variables set for this script are:"
env

echo "The current working directory is: $(pwd)"

exit 0
9 changes: 9 additions & 0 deletions backend/examples/validation_script_ok.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import json
import sys

if __name__ == '__main__':
arg_json = sys.argv[1]

json.loads(arg_json)

print('OK')
104 changes: 98 additions & 6 deletions backend/src/catalog.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,112 @@
use std::sync::Arc;

use axum::{debug_handler, Extension, Json};
use axum::extract::Path;
use axum::http::StatusCode;
use serde::{Deserialize, Serialize};

use crate::yaml_config::{CatalogYamlConfig, YamlConfig};
use crate::yaml_config::{CatalogServiceYamlConfig, CatalogYamlConfig, YamlConfig};

#[derive(Serialize, Deserialize)]
pub struct Response<T> {
pub struct ResultsResponse<T> {
results: Vec<T>,
}

#[derive(Serialize, Deserialize)]
pub struct SimpleResponse {
message: Option<String>,
}

fn find_catalog_by_slug<'a>(catalogs: &'a Vec<CatalogYamlConfig>, catalog_slug: &str) -> Option<&'a CatalogYamlConfig> {
catalogs.iter().find(|catalog| catalog.slug == catalog_slug)
}

fn find_catalog_service_by_slug<'a>(catalog: &'a CatalogYamlConfig, service_slug: &str) -> Option<&'a CatalogServiceYamlConfig> {
catalog.services.as_ref().unwrap().iter().find(|service| service.slug == service_slug)
}

#[debug_handler]
pub async fn list_catalog_services(
Path(catalog_slug): Path<String>,
Extension(yaml_config): Extension<Arc<YamlConfig>>,
) -> (StatusCode, Json<ResultsResponse<CatalogServiceYamlConfig>>) {
let catalog = match find_catalog_by_slug(&yaml_config.catalogs, catalog_slug.as_str()) {
Some(catalog) => catalog,
None => return (StatusCode::NOT_FOUND, Json(ResultsResponse { results: vec![] }))
};

(StatusCode::OK, Json(ResultsResponse { results: catalog.services.clone().unwrap_or(vec![]) }))
}

#[debug_handler]
pub async fn list_catalogs(
Extension(yaml_config): Extension<Arc<YamlConfig>>
) -> (StatusCode, Json<Response<CatalogYamlConfig>>) {
(StatusCode::OK, Json(Response { results: yaml_config.catalog.clone() }))
pub async fn exec_catalog_service_validate_scripts(
Path((catalog_slug, service_slug)): Path<(String, String)>,
Extension(yaml_config): Extension<Arc<YamlConfig>>,
) -> (StatusCode, Json<SimpleResponse>) {
let catalog = match find_catalog_by_slug(&yaml_config.catalogs, catalog_slug.as_str()) {
Some(catalog) => catalog,
None => return (StatusCode::NOT_FOUND, Json(SimpleResponse { message: Some("Service not found".to_string()) }))
};

let service = match find_catalog_service_by_slug(catalog, service_slug.as_str()) {
Some(service) => service,
None => return (StatusCode::NOT_FOUND, Json(SimpleResponse { message: Some("Service not found".to_string()) }))
};

(StatusCode::OK, Json(SimpleResponse { message: None }))
}

#[cfg(test)]
mod tests {
use crate::catalog::{find_catalog_by_slug, find_catalog_service_by_slug};
use crate::yaml_config::{CatalogServiceYamlConfig, CatalogYamlConfig};

#[test]
fn test_find_catalog_by_slug() {
let catalogs = vec![
CatalogYamlConfig {
name: "Catalog 1".to_string(),
slug: "catalog-1".to_string(),
description: None,
services: None,
},
CatalogYamlConfig {
name: "Catalog 2".to_string(),
slug: "catalog-2".to_string(),
description: None,
services: None,
},
];

assert_eq!(find_catalog_by_slug(&catalogs, "catalog-1"), Some(&catalogs[0]));
assert_eq!(find_catalog_by_slug(&catalogs, "catalog-2"), Some(&catalogs[1]));
assert_eq!(find_catalog_by_slug(&catalogs, "catalog-3"), None);
}

#[test]
fn test_find_catalog_service_by_slug() {
let catalog = CatalogYamlConfig {
name: "Catalog 1".to_string(),
slug: "catalog-1".to_string(),
description: None,
services: Some(vec![
CatalogServiceYamlConfig {
name: "Service 1".to_string(),
slug: "service-1".to_string(),
description: None,
fields: None,
},
CatalogServiceYamlConfig {
name: "Service 2".to_string(),
slug: "service-2".to_string(),
description: None,
fields: None,
},
]),
};

assert_eq!(find_catalog_service_by_slug(&catalog, "service-1"), Some(&catalog.services.unwrap()[0]));
assert_eq!(find_catalog_service_by_slug(&catalog, "service-2"), Some(&catalog.services.unwrap()[1]));
assert_eq!(find_catalog_service_by_slug(&catalog, "service-3"), None);
}
}
3 changes: 2 additions & 1 deletion backend/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ async fn main() {
.fallback(unknown_route)
.route("/", get(|| async { "OK" }))
.route("/healthz", get(|| async { "OK" }))
.route("/catalog", get(catalog::list_catalogs))
.route("/catalogs/:slug/services", get(catalog::list_catalog_services))
.route("/catalogs/:slug/services/:slug/validate", get(catalog::exec_catalog_service_validate_scripts))
.layer(Extension(yaml_config));
//.route("/catalog/:id", get(catalog::get_catalog_by_id))
//.route("/catalog", post(catalog::create_catalog));
Expand Down
11 changes: 10 additions & 1 deletion backend/src/yaml_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,21 @@ use serde::{Deserialize, Serialize};

#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct YamlConfig {
pub catalog: Vec<CatalogYamlConfig>,
pub catalogs: Vec<CatalogYamlConfig>,
}

#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct CatalogYamlConfig {
pub name: String,
pub slug: String,
pub description: Option<String>,
pub services: Option<Vec<CatalogServiceYamlConfig>>,
}

#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct CatalogServiceYamlConfig {
pub name: String,
pub slug: String,
pub description: Option<String>,
pub fields: Option<Vec<CatalogFieldYamlConfig>>,
}
Expand Down

0 comments on commit 1e05501

Please sign in to comment.