use anyhow::Result;
use httpmock::MockServer;
use pdk_test::port::Port;
#[cfg(feature = "experimental")]
use pdk_test::services::flex::UpstreamServiceConfig;
use pdk_test::services::flex::{ApiConfig, Flex, FlexConfig, PolicyConfig};
use pdk_test::services::httpmock::{HttpMock, HttpMockConfig};
use pdk_test::{pdk_test, TestComposite};
use reqwest::StatusCode;
const COMMONS_DIR: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/tests/commons");
const FLEX_PORT: Port = 8081;
#[pdk_test]
async fn declarative_config() -> Result<()> {
let upstream_config = HttpMockConfig::builder().hostname("mock").port(80).build();
let policy_config = PolicyConfig::builder()
.name("header-injection-flex")
.configuration(serde_json::json!({"outboundHeaders": [{
"key": "custom",
"value": "value"
}]}))
.build();
let api_config = ApiConfig::builder()
.name("myApi")
.upstream(&upstream_config)
.path("/anything/echo/")
.port(FLEX_PORT)
.policies([policy_config])
.build();
let flex_config = FlexConfig::builder()
.version("1.10.0")
.with_api(api_config)
.config_mounts([(COMMONS_DIR, "common")])
.build();
let composite = TestComposite::builder()
.with_service(flex_config)
.with_service(upstream_config)
.build()
.await?;
let flex: Flex = composite.service()?;
let http_mock: HttpMock = composite.service()?;
let upstream = MockServer::connect_async(http_mock.socket()).await;
let flex_url = flex.external_url(FLEX_PORT).unwrap();
upstream
.mock_async(|when, then| {
when.path_contains("/hello");
then.status(202).body("World!");
})
.await;
let response = reqwest::get(format!("{flex_url}/hello")).await?;
let status = response.status();
let header = response
.headers()
.get("custom")
.unwrap()
.to_str()
.unwrap()
.to_string();
let body = response.text().await.unwrap();
assert_eq!(status, StatusCode::ACCEPTED);
assert_eq!(body, "World!");
assert_eq!(header.as_str(), "value");
Ok(())
}
#[pdk_test]
#[cfg(feature = "experimental")]
async fn declarative_config_with_service() -> Result<()> {
let upstream_config = HttpMockConfig::builder().hostname("mock").port(80).build();
let policy_config = PolicyConfig::builder()
.name("health-check")
.configuration(serde_json::json!({"endpoint": "http://healthcheck", "path": "/status", "statusCode": "200", "interval": 1}))
.build();
let api_config = ApiConfig::builder()
.name("myApi")
.upstream(&upstream_config)
.path("/anything/echo/")
.port(FLEX_PORT)
.policies([policy_config])
.build();
let service_config = UpstreamServiceConfig::builder()
.name("healthcheck")
.address("http://mock")
.build();
let flex_config = FlexConfig::builder()
.version("1.10.0")
.with_api(api_config)
.with_upstream_service(service_config)
.config_mounts([(COMMONS_DIR, "common")])
.build();
let composite = TestComposite::builder()
.with_service(flex_config)
.with_service(upstream_config)
.build()
.await?;
let flex: Flex = composite.service()?;
let http_mock: HttpMock = composite.service()?;
let upstream = MockServer::connect_async(http_mock.socket()).await;
let flex_url = flex.external_url(FLEX_PORT).unwrap();
upstream
.mock_async(|when, then| {
when.path_contains("/hello");
then.status(202).body("World!");
})
.await;
upstream
.mock_async(|when, then| {
when.path("/status");
then.status(200);
})
.await;
let response = reqwest::get(format!("{flex_url}/hello")).await?;
let status = response.status();
let body = response.text().await.unwrap();
assert_eq!(status, StatusCode::ACCEPTED);
assert_eq!(body, "World!");
Ok(())
}