This commit is contained in:
2026-02-12 09:20:55 +03:00
commit 7c2d731399
24 changed files with 2123 additions and 0 deletions

16
tests/fixtures/minimal.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
# Test fixture: minimal single-target config
josh:
proxy_url: "https://josh.test.local"
monorepo_path: "org/repo"
targets:
- name: "example"
subfolder: "services/example"
subrepo_url: "https://gitea.test.local/ext/example.git"
branches:
main: main
bot:
name: "test-bot"
email: "test@test.local"
trailer: "Josh-Sync-Origin"

29
tests/fixtures/multi-target.yml vendored Normal file
View File

@@ -0,0 +1,29 @@
# Test fixture: multi-target config
josh:
proxy_url: "https://josh.test.local"
monorepo_path: "org/monorepo"
targets:
- name: "app-a"
subfolder: "services/app-a"
josh_filter: ":/services/app-a"
subrepo_url: "https://gitea.test.local/ext/app-a.git"
subrepo_auth: "https"
branches:
main: main
forward_only: []
- name: "app-b"
subfolder: "services/app-b"
subrepo_url: "git@gitea.test.local:ext/app-b.git"
subrepo_auth: "ssh"
subrepo_ssh_key_var: "APP_B_SSH_KEY"
branches:
main: main
develop: dev
forward_only: [develop]
bot:
name: "test-bot"
email: "test-bot@test.local"
trailer: "Josh-Sync-Origin"

39
tests/unit/auth.bats Normal file
View File

@@ -0,0 +1,39 @@
#!/usr/bin/env bats
# tests/unit/auth.bats — Auth URL construction tests
setup() {
export JOSH_SYNC_ROOT="$(cd "$BATS_TEST_DIRNAME/../.." && pwd)"
source "$JOSH_SYNC_ROOT/lib/core.sh"
source "$JOSH_SYNC_ROOT/lib/auth.sh"
# Set up env vars as parse_config + load_target would
export JOSH_PROXY_URL="https://josh.test.local"
export MONOREPO_PATH="org/monorepo"
export BOT_USER="sync-bot"
export GITEA_TOKEN="test-token-123"
export JOSH_FILTER=":/services/app-a"
export SUBREPO_URL="https://gitea.test.local/ext/app-a.git"
export SUBREPO_AUTH="https"
export SUBREPO_TOKEN="subrepo-token-456"
}
@test "josh_auth_url builds correct HTTPS URL with credentials and filter" {
local url
url=$(josh_auth_url)
[ "$url" = "https://sync-bot:test-token-123@josh.test.local/org/monorepo.git:/services/app-a.git" ]
}
@test "subrepo_auth_url injects credentials for HTTPS" {
local url
url=$(subrepo_auth_url)
[ "$url" = "https://sync-bot:subrepo-token-456@gitea.test.local/ext/app-a.git" ]
}
@test "subrepo_auth_url returns bare URL for SSH" {
export SUBREPO_AUTH="ssh"
export SUBREPO_URL="git@gitea.test.local:ext/app-a.git"
local url
url=$(subrepo_auth_url)
[ "$url" = "git@gitea.test.local:ext/app-a.git" ]
}

106
tests/unit/config.bats Normal file
View File

@@ -0,0 +1,106 @@
#!/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 ]
}

40
tests/unit/state.bats Normal file
View File

@@ -0,0 +1,40 @@
#!/usr/bin/env bats
# tests/unit/state.bats — State key generation tests
setup() {
export JOSH_SYNC_ROOT="$(cd "$BATS_TEST_DIRNAME/../.." && pwd)"
source "$JOSH_SYNC_ROOT/lib/core.sh"
source "$JOSH_SYNC_ROOT/lib/state.sh"
export JOSH_SYNC_TARGET_NAME="billing"
}
@test "state_key generates target/branch format" {
local key
key=$(state_key "main")
[ "$key" = "billing/main" ]
}
@test "state_key converts slashes to hyphens in branch name" {
local key
key=$(state_key "feature/my-branch")
[ "$key" = "billing/feature-my-branch" ]
}
@test "state_key works with different target names" {
export JOSH_SYNC_TARGET_NAME="auth-service"
local key
key=$(state_key "develop")
[ "$key" = "auth-service/develop" ]
}
@test "STATE_BRANCH defaults to josh-sync-state" {
[ "$STATE_BRANCH" = "josh-sync-state" ]
}
@test "STATE_BRANCH can be overridden via env" {
export JOSH_SYNC_STATE_BRANCH="custom-state"
# Re-source to pick up the new value
source "$JOSH_SYNC_ROOT/lib/state.sh"
[ "$STATE_BRANCH" = "custom-state" ]
}