assay-lua 0.17.6

General-purpose enhanced Lua runtime. Batteries-included scripting, automation, and web services.
Documentation
mod common;

use common::run_lua;
use wiremock::matchers::{header, method, path};
use wiremock::{Mock, MockServer, ResponseTemplate};

#[tokio::test]
async fn test_neutron_agents_list_sends_bearer() {
    let server = MockServer::start().await;
    Mock::given(method("GET"))
        .and(path("/api/admin/agents"))
        .and(header("authorization", "Bearer nck_test"))
        .respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
            "brand": "Demo",
            "agents": [{"id": "a1", "slug": "tom", "display_name": "Tom"}],
            "default_agent": {"stored": {}},
        })))
        .mount(&server)
        .await;

    let script = format!(
        r#"
        local neutron = require("assay.neutron")
        local c = neutron.client("{}", {{ token = "nck_test" }})
        local out = c.agents:list()
        assert.eq(out.brand, "Demo")
        assert.eq(#out.agents, 1)
        assert.eq(out.agents[1].slug, "tom")
        "#,
        server.uri()
    );
    run_lua(&script).await.unwrap();
}

#[tokio::test]
async fn test_neutron_secrets_set_and_list() {
    let server = MockServer::start().await;
    Mock::given(method("PUT"))
        .and(path("/api/admin/secrets/api-key"))
        .respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
            "secrets": [{"name": "api-key", "has_value": true, "preview": "v1a2…l3"}],
        })))
        .mount(&server)
        .await;

    let script = format!(
        r#"
        local neutron = require("assay.neutron")
        local c = neutron.client("{}", {{ token = "nck_test" }})
        local secrets = c.secrets:set("api-key", {{ value = "v1a2l3", agents = {{"tom"}} }})
        assert.eq(#secrets, 1)
        assert.eq(secrets[1].has_value, true)
        "#,
        server.uri()
    );
    run_lua(&script).await.unwrap();
}

#[tokio::test]
async fn test_neutron_cf_access_headers() {
    let server = MockServer::start().await;
    Mock::given(method("GET"))
        .and(path("/api/admin/tokens"))
        .and(header("cf-access-client-id", "cfid"))
        .and(header("cf-access-client-secret", "cfsecret"))
        .respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({"tokens": []})))
        .mount(&server)
        .await;

    let script = format!(
        r#"
        local neutron = require("assay.neutron")
        local c = neutron.client("{}", {{
            token = "nck_test", cf_client_id = "cfid", cf_client_secret = "cfsecret",
        }})
        assert.eq(#c.tokens:list(), 0)
        "#,
        server.uri()
    );
    run_lua(&script).await.unwrap();
}

#[tokio::test]
async fn test_neutron_http_error_surfaces() {
    let server = MockServer::start().await;
    Mock::given(method("DELETE"))
        .and(path("/api/admin/connections/nope"))
        .respond_with(
            ResponseTemplate::new(404).set_body_json(serde_json::json!({"error": "not found"})),
        )
        .mount(&server)
        .await;

    let script = format!(
        r#"
        local neutron = require("assay.neutron")
        local c = neutron.client("{}", {{ token = "nck_test" }})
        local ok, err = pcall(function() return c.connections:delete("nope") end)
        assert.eq(ok, false)
        assert.contains(tostring(err), "HTTP 404")
        "#,
        server.uri()
    );
    run_lua(&script).await.unwrap();
}

#[tokio::test]
async fn test_neutron_client_requires_token() {
    let script = r#"
        local neutron = require("assay.neutron")
        local ok, err = pcall(function() return neutron.client("http://x.example") end)
        assert.eq(ok, false)
        assert.contains(tostring(err), "no token")
    "#;
    run_lua(script).await.unwrap();
}