#!/usr/bin/env bats # tests/unit/config.bats — Config parsing tests setup() { export JOSH_SYNC_ROOT="$(cd "$BATS_TEST_DIRNAME/../.." && pwd)" source "$JOSH_SYNC_ROOT/lib/core.sh" source "$JOSH_SYNC_ROOT/lib/config.sh" FIXTURES="$JOSH_SYNC_ROOT/tests/fixtures" } @test "parse_config loads multi-target config" { cd "$(mktemp -d)" cp "$FIXTURES/multi-target.yml" .josh-sync.yml parse_config ".josh-sync.yml" [ "$JOSH_PROXY_URL" = "https://josh.test.local" ] [ "$MONOREPO_PATH" = "org/monorepo" ] [ "$BOT_NAME" = "test-bot" ] [ "$BOT_EMAIL" = "test-bot@test.local" ] [ "$BOT_TRAILER" = "Josh-Sync-Origin" ] } @test "parse_config derives gitea_host from HTTPS URL" { cd "$(mktemp -d)" cp "$FIXTURES/multi-target.yml" .josh-sync.yml parse_config ".josh-sync.yml" local host host=$(echo "$JOSH_SYNC_TARGETS" | jq -r '.[0].gitea_host') [ "$host" = "gitea.test.local" ] } @test "parse_config derives gitea_host from SSH URL" { cd "$(mktemp -d)" cp "$FIXTURES/multi-target.yml" .josh-sync.yml parse_config ".josh-sync.yml" local host host=$(echo "$JOSH_SYNC_TARGETS" | jq -r '.[1].gitea_host') [ "$host" = "gitea.test.local" ] } @test "parse_config derives subrepo_repo_path from HTTPS URL" { cd "$(mktemp -d)" cp "$FIXTURES/multi-target.yml" .josh-sync.yml parse_config ".josh-sync.yml" local path path=$(echo "$JOSH_SYNC_TARGETS" | jq -r '.[0].subrepo_repo_path') [ "$path" = "ext/app-a" ] } @test "parse_config derives subrepo_repo_path from SSH URL" { cd "$(mktemp -d)" cp "$FIXTURES/multi-target.yml" .josh-sync.yml parse_config ".josh-sync.yml" local path path=$(echo "$JOSH_SYNC_TARGETS" | jq -r '.[1].subrepo_repo_path') [ "$path" = "ext/app-b" ] } @test "parse_config auto-derives josh_filter from subfolder when not set" { cd "$(mktemp -d)" cp "$FIXTURES/minimal.yml" .josh-sync.yml parse_config ".josh-sync.yml" local filter filter=$(echo "$JOSH_SYNC_TARGETS" | jq -r '.[0].josh_filter') [ "$filter" = ":/services/example" ] } @test "parse_config preserves explicit josh_filter" { cd "$(mktemp -d)" cp "$FIXTURES/multi-target.yml" .josh-sync.yml parse_config ".josh-sync.yml" local filter filter=$(echo "$JOSH_SYNC_TARGETS" | jq -r '.[0].josh_filter') [ "$filter" = ":/services/app-a" ] } @test "parse_config reports correct target count" { cd "$(mktemp -d)" cp "$FIXTURES/multi-target.yml" .josh-sync.yml parse_config ".josh-sync.yml" local count count=$(echo "$JOSH_SYNC_TARGETS" | jq 'length') [ "$count" -eq 2 ] } @test "parse_config fails on missing config file" { cd "$(mktemp -d)" run bash -c 'source "$JOSH_SYNC_ROOT/lib/core.sh"; source "$JOSH_SYNC_ROOT/lib/config.sh"; parse_config "nonexistent.yml"' [ "$status" -ne 0 ] } @test "parse_config fails when schema_version is missing (no v1 fallback)" { cd "$(mktemp -d)" cat > .josh-sync.yml <<'YAML' josh: proxy_url: "https://josh.test.local" monorepo_path: "org/repo" monorepo_url: "git@gitea.test.local:org/repo.git" targets: - name: "x" subfolder: "x" subrepo_url: "git@gitea.test.local:ext/x.git" branches: { main: main } bot: name: "b" email: "b@b" trailer: "T" YAML run bash -c 'source "$JOSH_SYNC_ROOT/lib/core.sh"; source "$JOSH_SYNC_ROOT/lib/config.sh"; parse_config ".josh-sync.yml"' [ "$status" -ne 0 ] [[ "$output" == *"schema_version missing"* ]] } @test "parse_config rejects schema_version: 1" { cd "$(mktemp -d)" cat > .josh-sync.yml <<'YAML' schema_version: 1 josh: proxy_url: "https://josh.test.local" monorepo_path: "org/repo" monorepo_url: "git@gitea.test.local:org/repo.git" targets: - name: "x" subfolder: "x" subrepo_url: "git@gitea.test.local:ext/x.git" branches: { main: main } bot: name: "b" email: "b@b" trailer: "T" YAML run bash -c 'source "$JOSH_SYNC_ROOT/lib/core.sh"; source "$JOSH_SYNC_ROOT/lib/config.sh"; parse_config ".josh-sync.yml"' [ "$status" -ne 0 ] [[ "$output" == *"Unsupported schema_version"* ]] || [[ "$output" == *"requires schema_version 2"* ]] } @test "parse_config fails when josh.monorepo_url is missing" { cd "$(mktemp -d)" cat > .josh-sync.yml <<'YAML' schema_version: 2 josh: proxy_url: "https://josh.test.local" monorepo_path: "org/repo" targets: - name: "x" subfolder: "x" subrepo_url: "git@gitea.test.local:ext/x.git" branches: { main: main } bot: name: "b" email: "b@b" trailer: "T" YAML run bash -c 'source "$JOSH_SYNC_ROOT/lib/core.sh"; source "$JOSH_SYNC_ROOT/lib/config.sh"; parse_config ".josh-sync.yml"' [ "$status" -ne 0 ] [[ "$output" == *"monorepo_url"* ]] } @test "parse_config exports MONOREPO_URL, MONOREPO_AUTH, MONOREPO_GITEA_HOST, MONOREPO_REPO_PATH from SSH form" { cd "$(mktemp -d)" cp "$FIXTURES/minimal.yml" .josh-sync.yml parse_config ".josh-sync.yml" [ "$MONOREPO_URL" = "git@gitea.test.local:org/repo.git" ] [ "$MONOREPO_AUTH" = "https" ] [ "$MONOREPO_GITEA_HOST" = "gitea.test.local" ] [ "$MONOREPO_REPO_PATH" = "org/repo" ] } @test "parse_config derives MONOREPO_GITEA_HOST from HTTPS monorepo_url" { cd "$(mktemp -d)" cat > .josh-sync.yml <<'YAML' schema_version: 2 josh: proxy_url: "https://josh.test.local" monorepo_path: "org/repo" monorepo_url: "https://gitea.example.io/org/repo.git" targets: - name: "x" subfolder: "x" subrepo_url: "git@gitea.test.local:ext/x.git" branches: { main: main } bot: name: "b" email: "b@b" trailer: "T" YAML parse_config ".josh-sync.yml" [ "$MONOREPO_GITEA_HOST" = "gitea.example.io" ] [ "$MONOREPO_REPO_PATH" = "org/repo" ] } @test "parse_config derives MONOREPO_API from monorepo_url's host (cross-host: monorepo and target on different hosts)" { cd "$(mktemp -d)" cat > .josh-sync.yml <<'YAML' schema_version: 2 josh: proxy_url: "https://josh.example.io" monorepo_path: "org/repo" monorepo_url: "git@code.example.io:org/repo.git" targets: - name: "x" subfolder: "x" subrepo_url: "git@other-host.io:ext/x.git" branches: { main: main } bot: name: "b" email: "b@b" trailer: "T" YAML parse_config ".josh-sync.yml" [ "$MONOREPO_API" = "https://code.example.io/api/v1/repos/org/repo" ] } @test "parse_config rejects invalid monorepo_auth value" { cd "$(mktemp -d)" cat > .josh-sync.yml <<'YAML' schema_version: 2 josh: proxy_url: "https://josh.test.local" monorepo_path: "org/repo" monorepo_url: "git@gitea.test.local:org/repo.git" monorepo_auth: "weird" targets: - name: "x" subfolder: "x" subrepo_url: "git@gitea.test.local:ext/x.git" branches: { main: main } bot: name: "b" email: "b@b" trailer: "T" YAML run bash -c 'source "$JOSH_SYNC_ROOT/lib/core.sh"; source "$JOSH_SYNC_ROOT/lib/config.sh"; parse_config ".josh-sync.yml"' [ "$status" -ne 0 ] [[ "$output" == *"monorepo_auth"* ]] }