feat: add many things

Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
2026-03-08 23:00:03 +01:00
parent 45353089c2
commit 5a5f9a3003
104 changed files with 23417 additions and 2027 deletions

View File

@@ -4,7 +4,9 @@ use axum::Router;
use chrono::Utc;
use forage_core::auth::*;
use forage_core::platform::{
Artifact, ArtifactContext, Destination, ForestPlatform, Organisation, OrgMember, PlatformError,
Artifact, ArtifactContext, CreatePolicyInput, CreateReleasePipelineInput, CreateTriggerInput,
Destination, Environment, ForestPlatform, Organisation, OrgMember, PlatformError, Policy,
ReleasePipeline, Trigger, UpdatePolicyInput, UpdateReleasePipelineInput, UpdateTriggerInput,
};
use forage_core::session::{
CachedOrg, CachedUser, InMemorySessionStore, SessionData, SessionStore,
@@ -41,7 +43,16 @@ pub(crate) struct MockPlatformBehavior {
pub remove_member_result: Option<Result<(), PlatformError>>,
pub update_member_role_result: Option<Result<OrgMember, PlatformError>>,
pub get_artifact_by_slug_result: Option<Result<Artifact, PlatformError>>,
pub list_environments_result: Option<Result<Vec<Environment>, PlatformError>>,
pub list_destinations_result: Option<Result<Vec<Destination>, PlatformError>>,
pub list_triggers_result: Option<Result<Vec<Trigger>, PlatformError>>,
pub create_trigger_result: Option<Result<Trigger, PlatformError>>,
pub update_trigger_result: Option<Result<Trigger, PlatformError>>,
pub delete_trigger_result: Option<Result<(), PlatformError>>,
pub list_release_pipelines_result: Option<Result<Vec<ReleasePipeline>, PlatformError>>,
pub create_release_pipeline_result: Option<Result<ReleasePipeline, PlatformError>>,
pub update_release_pipeline_result: Option<Result<ReleasePipeline, PlatformError>>,
pub delete_release_pipeline_result: Option<Result<(), PlatformError>>,
}
pub(crate) fn ok_tokens() -> AuthTokens {
@@ -214,6 +225,18 @@ impl ForestAuth for MockForestClient {
}))
}
async fn get_user_by_username(
&self,
_access_token: &str,
username: &str,
) -> Result<UserProfile, AuthError> {
Ok(UserProfile {
user_id: "user-123".into(),
username: username.into(),
created_at: Some("2025-01-15T10:00:00Z".into()),
})
}
async fn remove_email(
&self,
_access_token: &str,
@@ -386,6 +409,15 @@ impl ForestPlatform for MockPlatformClient {
}))
}
async fn list_environments(
&self,
_access_token: &str,
_organisation: &str,
) -> Result<Vec<Environment>, PlatformError> {
let b = self.behavior.lock().unwrap();
b.list_environments_result.clone().unwrap_or(Ok(vec![]))
}
async fn list_destinations(
&self,
_access_token: &str,
@@ -394,6 +426,255 @@ impl ForestPlatform for MockPlatformClient {
let b = self.behavior.lock().unwrap();
b.list_destinations_result.clone().unwrap_or(Ok(vec![]))
}
async fn create_environment(
&self,
_access_token: &str,
organisation: &str,
name: &str,
description: Option<&str>,
sort_order: i32,
) -> Result<Environment, PlatformError> {
Ok(Environment {
id: format!("env-{name}"),
organisation: organisation.into(),
name: name.into(),
description: description.map(|s| s.to_string()),
sort_order,
created_at: "2026-03-08T00:00:00Z".into(),
})
}
async fn create_destination(
&self,
_access_token: &str,
_organisation: &str,
_name: &str,
_environment: &str,
_metadata: &std::collections::HashMap<String, String>,
_dest_type: Option<&forage_core::platform::DestinationType>,
) -> Result<(), PlatformError> {
Ok(())
}
async fn update_destination(
&self,
_access_token: &str,
_name: &str,
_metadata: &std::collections::HashMap<String, String>,
) -> Result<(), PlatformError> {
Ok(())
}
async fn get_destination_states(
&self,
_access_token: &str,
_organisation: &str,
_project: Option<&str>,
) -> Result<forage_core::platform::DeploymentStates, PlatformError> {
Ok(forage_core::platform::DeploymentStates {
destinations: vec![],
})
}
async fn get_release_intent_states(
&self,
_access_token: &str,
_organisation: &str,
_project: Option<&str>,
_include_completed: bool,
) -> Result<Vec<forage_core::platform::ReleaseIntentState>, PlatformError> {
Ok(vec![])
}
async fn release_artifact(
&self,
_access_token: &str,
_artifact_id: &str,
_destinations: &[String],
_environments: &[String],
_use_pipeline: bool,
) -> Result<(), PlatformError> {
Ok(())
}
async fn list_triggers(
&self,
_access_token: &str,
_organisation: &str,
_project: &str,
) -> Result<Vec<Trigger>, PlatformError> {
let b = self.behavior.lock().unwrap();
b.list_triggers_result.clone().unwrap_or(Ok(vec![]))
}
async fn create_trigger(
&self,
_access_token: &str,
_organisation: &str,
_project: &str,
input: &CreateTriggerInput,
) -> Result<Trigger, PlatformError> {
let b = self.behavior.lock().unwrap();
b.create_trigger_result.clone().unwrap_or(Ok(Trigger {
id: "trigger-1".into(),
name: input.name.clone(),
enabled: true,
branch_pattern: input.branch_pattern.clone(),
title_pattern: input.title_pattern.clone(),
author_pattern: input.author_pattern.clone(),
commit_message_pattern: input.commit_message_pattern.clone(),
source_type_pattern: input.source_type_pattern.clone(),
target_environments: input.target_environments.clone(),
target_destinations: input.target_destinations.clone(),
force_release: input.force_release,
use_pipeline: input.use_pipeline,
created_at: "2026-03-08T00:00:00Z".into(),
updated_at: "2026-03-08T00:00:00Z".into(),
}))
}
async fn update_trigger(
&self,
_access_token: &str,
_organisation: &str,
_project: &str,
name: &str,
input: &UpdateTriggerInput,
) -> Result<Trigger, PlatformError> {
let b = self.behavior.lock().unwrap();
b.update_trigger_result.clone().unwrap_or(Ok(Trigger {
id: "trigger-1".into(),
name: name.into(),
enabled: input.enabled.unwrap_or(true),
branch_pattern: input.branch_pattern.clone(),
title_pattern: input.title_pattern.clone(),
author_pattern: input.author_pattern.clone(),
commit_message_pattern: input.commit_message_pattern.clone(),
source_type_pattern: input.source_type_pattern.clone(),
target_environments: input.target_environments.clone(),
target_destinations: input.target_destinations.clone(),
force_release: input.force_release.unwrap_or(false),
use_pipeline: input.use_pipeline.unwrap_or(false),
created_at: "2026-03-08T00:00:00Z".into(),
updated_at: "2026-03-08T00:00:00Z".into(),
}))
}
async fn delete_trigger(
&self,
_access_token: &str,
_organisation: &str,
_project: &str,
_name: &str,
) -> Result<(), PlatformError> {
let b = self.behavior.lock().unwrap();
b.delete_trigger_result.clone().unwrap_or(Ok(()))
}
async fn list_policies(
&self,
_access_token: &str,
_organisation: &str,
_project: &str,
) -> Result<Vec<Policy>, PlatformError> {
Ok(vec![])
}
async fn create_policy(
&self,
_access_token: &str,
_organisation: &str,
_project: &str,
_input: &CreatePolicyInput,
) -> Result<Policy, PlatformError> {
Err(PlatformError::Other("not implemented in mock".into()))
}
async fn update_policy(
&self,
_access_token: &str,
_organisation: &str,
_project: &str,
_name: &str,
_input: &UpdatePolicyInput,
) -> Result<Policy, PlatformError> {
Err(PlatformError::Other("not implemented in mock".into()))
}
async fn delete_policy(
&self,
_access_token: &str,
_organisation: &str,
_project: &str,
_name: &str,
) -> Result<(), PlatformError> {
Ok(())
}
async fn list_release_pipelines(
&self,
_access_token: &str,
_organisation: &str,
_project: &str,
) -> Result<Vec<ReleasePipeline>, PlatformError> {
let b = self.behavior.lock().unwrap();
b.list_release_pipelines_result
.clone()
.unwrap_or(Ok(vec![]))
}
async fn create_release_pipeline(
&self,
_access_token: &str,
_organisation: &str,
_project: &str,
input: &CreateReleasePipelineInput,
) -> Result<ReleasePipeline, PlatformError> {
let b = self.behavior.lock().unwrap();
b.create_release_pipeline_result
.clone()
.unwrap_or(Ok(ReleasePipeline {
id: "pipeline-1".into(),
name: input.name.clone(),
enabled: true,
stages: input.stages.clone(),
created_at: "2026-03-08T00:00:00Z".into(),
updated_at: "2026-03-08T00:00:00Z".into(),
}))
}
async fn update_release_pipeline(
&self,
_access_token: &str,
_organisation: &str,
_project: &str,
name: &str,
input: &UpdateReleasePipelineInput,
) -> Result<ReleasePipeline, PlatformError> {
let b = self.behavior.lock().unwrap();
b.update_release_pipeline_result
.clone()
.unwrap_or(Ok(ReleasePipeline {
id: "pipeline-1".into(),
name: name.into(),
enabled: input.enabled.unwrap_or(true),
stages: input.stages.clone().unwrap_or_default(),
created_at: "2026-03-08T00:00:00Z".into(),
updated_at: "2026-03-08T00:00:00Z".into(),
}))
}
async fn delete_release_pipeline(
&self,
_access_token: &str,
_organisation: &str,
_project: &str,
_name: &str,
) -> Result<(), PlatformError> {
let b = self.behavior.lock().unwrap();
b.delete_release_pipeline_result.clone().unwrap_or(Ok(()))
}
}
pub(crate) fn make_templates() -> TemplateEngine {