use mcai_worker_sdk::{ job::*, parameter::media_segment::MediaSegment, MessageError, ParametersContainer, }; use schemars::JsonSchema; #[test] fn test_string_credential_request_value() { std::env::set_var("BACKEND_HOSTNAME", mockito::server_url()); use mockito::mock; let _m = mock("POST", "/sessions") .with_header("content-type", "application/json") .with_body(r#"{"access_token": "fake_access_token"}"#) .create(); let _m = mock("GET", "/credentials/TEST_CREDENTIAL_KEY") .with_header("content-type", "application/json") .with_body( r#"{"data": { "id": 666, "key": "TEST_CREDENTIAL_KEY", "value": "TEST_CREDENTIAL_VALUE", "inserted_at": "today" }}"#, ) .create(); let message = r#"{ "job_id": 123, "parameters": [ { "id":"test_credential", "type":"string", "store":"BACKEND", "value":"TEST_CREDENTIAL_KEY" } ] }"#; let job = Job::new(message).unwrap(); let credential = job.get_parameter::("test_credential").unwrap(); assert_eq!("TEST_CREDENTIAL_VALUE".to_string(), credential); } #[test] fn test_integer_credential_request_value_from_string() { std::env::set_var("BACKEND_HOSTNAME", mockito::server_url()); use mockito::mock; let _m = mock("POST", "/sessions") .with_header("content-type", "application/json") .with_body(r#"{"access_token": "fake_access_token"}"#) .create(); let _m = mock("GET", "/credentials/TEST_CREDENTIAL_KEY") .with_header("content-type", "application/json") .with_body( r#"{"data": { "id": 666, "key": "TEST_CREDENTIAL_KEY", "value": "12345", "inserted_at": "today" }}"#, ) .create(); let message = r#"{ "job_id": 123, "parameters": [ { "id":"test_credential", "type":"integer", "store":"BACKEND", "value":"TEST_CREDENTIAL_KEY" } ] }"#; let job = Job::new(message).unwrap(); let credential = job.get_parameter::("test_credential").unwrap(); assert_eq!(12345, credential); } #[test] fn test_integer_credential_request_value_from_integer() { std::env::set_var("BACKEND_HOSTNAME", mockito::server_url()); use mockito::mock; let _m = mock("POST", "/sessions") .with_header("content-type", "application/json") .with_body(r#"{"access_token": "fake_access_token"}"#) .create(); let _m = mock("GET", "/credentials/TEST_CREDENTIAL_KEY") .with_header("content-type", "application/json") .with_body( r#"{"data": { "id": 666, "key": "TEST_CREDENTIAL_KEY", "value": 12345, "inserted_at": "today" }}"#, ) .create(); let message = r#"{ "job_id": 123, "parameters": [ { "id":"test_credential", "type":"integer", "store":"BACKEND", "value":"TEST_CREDENTIAL_KEY" } ] }"#; let job = Job::new(message).unwrap(); let credential = job.get_parameter::("test_credential").unwrap(); assert_eq!(12345, credential); } #[test] fn test_boolean_credential_request_value_from_string() { std::env::set_var("BACKEND_HOSTNAME", mockito::server_url()); use mockito::mock; let _m = mock("POST", "/sessions") .with_header("content-type", "application/json") .with_body(r#"{"access_token": "fake_access_token"}"#) .create(); let _m = mock("GET", "/credentials/TEST_CREDENTIAL_KEY") .with_header("content-type", "application/json") .with_body( r#"{"data": { "id": 666, "key": "TEST_CREDENTIAL_KEY", "value": "true", "inserted_at": "today" }}"#, ) .create(); let message = r#"{ "job_id": 123, "parameters": [ { "id":"test_credential", "type":"boolean", "store":"BACKEND", "value":"TEST_CREDENTIAL_KEY" } ] }"#; let job = Job::new(message).unwrap(); let credential = job.get_parameter::("test_credential").unwrap(); assert!(credential); } #[test] fn test_boolean_credential_request_value_from_boolean() { std::env::set_var("BACKEND_HOSTNAME", mockito::server_url()); use mockito::mock; let _m = mock("POST", "/sessions") .with_header("content-type", "application/json") .with_body(r#"{"access_token": "fake_access_token"}"#) .create(); let _m = mock("GET", "/credentials/TEST_CREDENTIAL_KEY") .with_header("content-type", "application/json") .with_body( r#"{"data": { "id": 666, "key": "TEST_CREDENTIAL_KEY", "value": true, "inserted_at": "today" }}"#, ) .create(); let message = r#"{ "job_id": 123, "parameters": [ { "id":"test_credential", "type":"boolean", "store":"BACKEND", "value":"TEST_CREDENTIAL_KEY" } ] }"#; let job = Job::new(message).unwrap(); let credential = job.get_parameter::("test_credential").unwrap(); assert!(credential); } #[test] fn test_array_credential_request_value_from_array_of_strings() { std::env::set_var("BACKEND_HOSTNAME", mockito::server_url()); use mockito::mock; let _m = mock("POST", "/sessions") .with_header("content-type", "application/json") .with_body(r#"{"access_token": "fake_access_token"}"#) .create(); let _m = mock("GET", "/credentials/TEST_CREDENTIAL_KEY") .with_header("content-type", "application/json") .with_body( r#"{"data": { "id": 666, "key": "TEST_CREDENTIAL_KEY", "value": [ "value_1", "value_2" ], "inserted_at": "today" }}"#, ) .create(); let message = r#"{ "job_id": 123, "parameters": [ { "id":"test_credential", "type":"array_of_strings", "store":"BACKEND", "value":"TEST_CREDENTIAL_KEY" } ] }"#; let job = Job::new(message).unwrap(); let credential: Vec = job.get_parameter("test_credential").unwrap(); assert_eq!(2, credential.len()); assert_eq!(&"value_1".to_string(), credential.get(0).unwrap()); assert_eq!(&"value_2".to_string(), credential.get(1).unwrap()); } #[test] fn test_object_credential_request_value_from_media_segments() { std::env::set_var("BACKEND_HOSTNAME", mockito::server_url()); use mockito::mock; let _m = mock("POST", "/sessions") .with_header("content-type", "application/json") .with_body(r#"{"access_token": "fake_access_token"}"#) .create(); let _m = mock("GET", "/credentials/TEST_CREDENTIAL_KEY") .with_header("content-type", "application/json") .with_body( r#"{"data": { "id": 666, "key": "TEST_CREDENTIAL_KEY", "value": [ { "start": 0, "end": 999 }, { "start": 1000, "end": 1999 } ], "inserted_at": "today" }}"#, ) .create(); let message = r#"{ "job_id": 123, "parameters": [ { "id":"test_credential", "type":"array_of_media_segments", "store":"BACKEND", "value":"TEST_CREDENTIAL_KEY" } ] }"#; let job = Job::new(message).unwrap(); let credential: Vec = job.get_parameter("test_credential").unwrap(); assert_eq!(2, credential.len()); assert_eq!(&MediaSegment::new(0, 999), credential.get(0).unwrap()); assert_eq!(&MediaSegment::new(1000, 1999), credential.get(1).unwrap()); } #[test] fn test_string_credential_request_value_no_session() { std::env::set_var("BACKEND_HOSTNAME", mockito::server_url()); use mockito::mock; let _m = mock("POST", "/sessions").with_status(404).create(); let message = r#"{ "job_id": 123, "parameters": [ { "id":"test_credential", "type":"string", "store":"BACKEND", "value":"TEST_CREDENTIAL_KEY" } ] }"#; let job = Job::new(message).unwrap(); assert_eq!( job.get_parameter::("test_credential"), Err(MessageError::ParameterValueError(format!( "Http(HttpError {{ cause: \"HTTP status client error (404 Not Found) for url ({}/sessions)\" }})", mockito::server_url() ))) ); } #[test] fn test_string_credential_request_value_invalid_session() { std::env::set_var("BACKEND_HOSTNAME", mockito::server_url()); use mockito::mock; let _m = mock("POST", "/sessions") .with_header("content-type", "application/json") .with_body(r#"{"bad_token_key": "token"}"#) .create(); let message = r#"{ "job_id": 123, "parameters": [ { "id":"test_credential", "type":"string", "store":"BACKEND", "value":"TEST_CREDENTIAL_KEY" } ] }"#; let job = Job::new(message).unwrap(); assert_eq!( job.get_parameter::("test_credential"), Err(MessageError::ParameterValueError( "Http(HttpError { cause: \"error decoding response body: missing field `access_token` at line 1 column 26\" })".to_string() )) ); } #[test] fn test_string_credential_request_value_no_credential() { std::env::set_var("BACKEND_HOSTNAME", mockito::server_url()); use mockito::mock; let _m = mock("POST", "/sessions") .with_header("content-type", "application/json") .with_body(r#"{"access_token": "fake_access_token"}"#) .create(); let _m = mock("GET", "/credentials/TEST_CREDENTIAL_KEY") .with_status(404) .create(); let message = r#"{ "job_id": 123, "parameters": [ { "id":"test_credential", "type":"string", "store":"BACKEND", "value":"TEST_CREDENTIAL_KEY" } ] }"#; let job = Job::new(message).unwrap(); assert_eq!( job.get_parameter::("test_credential"), Err(MessageError::ParameterValueError(format!( "Http(HttpError {{ cause: \"HTTP status client error (404 Not Found) for url ({}/credentials/TEST_CREDENTIAL_KEY)\" }})", mockito::server_url() ))) ); } #[test] fn test_string_credential_request_value_unauthorized() { std::env::set_var("BACKEND_HOSTNAME", mockito::server_url()); use mockito::mock; let _m = mock("POST", "/sessions") .with_header("content-type", "application/json") .with_body(r#"{"access_token": "fake_access_token"}"#) .create(); let _m = mock("GET", "/credentials/TEST_CREDENTIAL_KEY") .with_status(401) .create(); let message = r#"{ "job_id": 123, "parameters": [ { "id":"test_credential", "type":"string", "store":"BACKEND", "value":"TEST_CREDENTIAL_KEY" } ] }"#; let job = Job::new(message).unwrap(); assert_eq!( job.get_parameter::("test_credential"), Err(MessageError::ParameterValueError( format!("Http(HttpError {{ cause: \"HTTP status client error (401 Unauthorized) for url ({}/credentials/TEST_CREDENTIAL_KEY)\" }})", mockito::server_url()) )) ); } #[test] fn test_string_credential_request_value_invalid_credential() { std::env::set_var("BACKEND_HOSTNAME", mockito::server_url()); use mockito::mock; let _m = mock("POST", "/sessions") .with_header("content-type", "application/json") .with_body(r#"{"access_token": "fake_access_token"}"#) .create(); let _m = mock("GET", "/credentials/TEST_CREDENTIAL_KEY") .with_header("content-type", "application/json") .with_body(r#"{"data": {}}"#) .create(); let message = r#"{ "job_id": 123, "parameters": [ { "id":"test_credential", "type":"string", "store":"BACKEND", "value":"TEST_CREDENTIAL_KEY" } ] }"#; let job = Job::new(message).unwrap(); assert_eq!( job.get_parameter::("test_credential"), Err(MessageError::ParameterValueError( "Http(HttpError { cause: \"error decoding response body: missing field `id` at line 1 column 11\" })".to_string() )) ); } #[test] fn test_string_credential_request_value_without_store() { std::env::set_var("BACKEND_HOSTNAME", mockito::server_url()); use mockito::mock; let _m = mock("POST", "/sessions") .with_header("content-type", "application/json") .with_body(r#"{"access_token": "fake_access_token"}"#) .create(); let _m = mock("GET", "/credentials/TEST_CREDENTIAL_KEY") .with_header("content-type", "application/json") .with_body( r#"{"data": { "id": 666, "key": "TEST_CREDENTIAL_KEY", "value": "TEST_CREDENTIAL_VALUE", "inserted_at": "today" }}"#, ) .create(); let message = r#"{ "job_id": 123, "parameters": [ { "id":"test_credential", "type":"string", "value":"TEST_CREDENTIAL_KEY" } ] }"#; let job = Job::new(message).unwrap(); assert_eq!( job.get_parameter::("test_credential"), Ok("TEST_CREDENTIAL_KEY".to_string()) ); } #[test] fn test_string_credential_request_value_with_other_store() { std::env::set_var("OTHER_HOSTNAME", mockito::server_url()); use mockito::mock; let _m = mock("POST", "/sessions") .with_header("content-type", "application/json") .with_body(r#"{"access_token": "fake_access_token"}"#) .create(); let _m = mock("GET", "/credentials/TEST_CREDENTIAL_KEY") .with_header("content-type", "application/json") .with_body( r#"{"data": { "id": 666, "key": "TEST_CREDENTIAL_KEY", "value": "TEST_CREDENTIAL_VALUE", "inserted_at": "today" }}"#, ) .create(); let message = r#"{ "job_id": 123, "parameters": [ { "id":"test_credential", "type":"string", "store":"OTHER", "value":"TEST_CREDENTIAL_KEY" } ] }"#; let job = Job::new(message).unwrap(); assert_eq!( job.get_parameter::("test_credential"), Ok("TEST_CREDENTIAL_VALUE".to_string()) ); } #[test] fn test_string_credential_request_value_with_invalid_store() { std::env::set_var("BACKEND_HOSTNAME", mockito::server_url()); use mockito::mock; let _m = mock("POST", "/sessions") .with_header("content-type", "application/json") .with_body(r#"{"access_token": "fake_access_token"}"#) .create(); let _m = mock("GET", "/credentials/TEST_CREDENTIAL_KEY") .with_header("content-type", "application/json") .with_body( r#"{"data": { "id": 666, "key": "TEST_CREDENTIAL_KEY", "value": "TEST_CREDENTIAL_VALUE", "inserted_at": "today" }}"#, ) .create(); let message = r#"{ "job_id": 123, "parameters": [ { "id":"test_credential", "type":"string", "store":"UNKNOWN", "value":"TEST_CREDENTIAL_KEY" } ] }"#; let job = Job::new(message).unwrap(); #[cfg(target_os = "linux")] let code = 111; #[cfg(target_os = "macos")] let code = 61; let part_1 = "error sending request for url (http://127.0.0.1:4000/api/sessions): "; let part_2 = "error trying to connect: tcp connect error: Connection refused (os error"; let error_message = format!(r#"Http(HttpError {{ cause: "{part_1}{part_2} {code})" }})"#); assert_eq!( job.get_parameter::("test_credential"), Err(MessageError::ParameterValueError(error_message)) ); } #[test] fn test_string_credential_request_value_from_vault_store() { use mockito::mock; use serde::Deserialize; use std::collections::HashMap; std::env::set_var("VAULT_HOSTNAME", mockito::server_url()); let vault_token = "s.123456789abcdefghijklmnop"; std::env::set_var("VAULT_TOKEN", vault_token); let _m = mock("GET", "/secret/data/TEST_CREDENTIAL_KEY") .with_header("X-Vault-Token", vault_token) .with_body( r#"{ "some_field": 123, "data": { "data": { "key_1": "value_1", "key_2": "value_2", "key_3": "value_3" }, "metadata": { "some": "metadata" } }, "some_other_field": "some_value" }"#, ) .create(); let message = r#"{ "job_id": 123, "parameters": [ { "id":"test_credential", "type":"string", "store":"VAULT", "value":"TEST_CREDENTIAL_KEY" } ] }"#; #[derive(JsonSchema, Deserialize)] struct JobParameters { test_credential: HashMap, } let job = Job::new(message).unwrap(); let job_parameters = job.get_parameters::().unwrap(); assert_eq!( Some(&"value_1".to_string()), job_parameters.test_credential.get("key_1") ); assert_eq!( Some(&"value_2".to_string()), job_parameters.test_credential.get("key_2") ); assert_eq!( Some(&"value_3".to_string()), job_parameters.test_credential.get("key_3") ); }