Files

355 lines
7.9 KiB
Go

package actions
import (
"testing"
)
func TestSlimActionRunner(t *testing.T) {
tests := []struct {
name string
runner *ActionRunner
expected map[string]interface{}
}{
{
name: "complete runner",
runner: &ActionRunner{
ID: 1,
Name: "metal",
UUID: "uuid-123",
Status: "online",
Online: true,
Busy: false,
Version: "1.22.5",
Labels: []string{"metal", "self-hosted"},
LastOnline: "2024-01-01T00:00:00Z",
},
expected: map[string]interface{}{
"id": int64(1),
"name": "metal",
"uuid": "uuid-123",
"status": "online",
"online": true,
"busy": false,
"version": "1.22.5",
"labels": []string{"metal", "self-hosted"},
},
},
{
name: "runner without labels",
runner: &ActionRunner{
ID: 2,
Name: "cloud-1",
UUID: "uuid-456",
Status: "offline",
Online: false,
Busy: false,
Version: "1.22.5",
},
expected: map[string]interface{}{
"id": int64(2),
"name": "cloud-1",
"uuid": "uuid-456",
"status": "offline",
"online": false,
"busy": false,
"version": "1.22.5",
"labels": []string{},
},
},
{
name: "nil runner",
runner: nil,
expected: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := slimActionRunner(tt.runner)
if !runnerMapsEqual(result, tt.expected) {
t.Fatalf("slimActionRunner() = %v, want %v", result, tt.expected)
}
})
}
}
func TestSlimActionRunners(t *testing.T) {
tests := []struct {
name string
runners []*ActionRunner
expected map[string]interface{}
}{
{
name: "multiple runners",
runners: []*ActionRunner{
{
ID: 1,
Name: "metal",
Status: "online",
Online: true,
Labels: []string{"metal"},
},
{
ID: 2,
Name: "cloud-1",
Status: "offline",
Online: false,
Labels: []string{"cloud-1"},
},
},
expected: map[string]interface{}{
"total_count": 2,
},
},
{
name: "empty list",
runners: []*ActionRunner{},
expected: map[string]interface{}{
"total_count": 0,
"runners": []interface{}{},
},
},
{
name: "nil runners",
runners: nil,
expected: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := slimActionRunners(tt.runners)
if result["total_count"] != tt.expected["total_count"] {
t.Fatalf("total_count = %v, want %v", result["total_count"], tt.expected["total_count"])
}
})
}
}
func TestSlimActionRunner_EdgeCases(t *testing.T) {
tests := []struct {
name string
runner *ActionRunner
check func(t *testing.T, result map[string]interface{})
}{
{
name: "runner with zero ID",
runner: &ActionRunner{
ID: 0,
Name: "zero-runner",
Status: "offline",
},
check: func(t *testing.T, result map[string]interface{}) {
if result["id"] != int64(0) {
t.Errorf("expected ID 0, got %v", result["id"])
}
},
},
{
name: "runner with empty name",
runner: &ActionRunner{
ID: 1,
Name: "",
Status: "online",
},
check: func(t *testing.T, result map[string]interface{}) {
if result["name"] != "" {
t.Errorf("expected empty name, got %v", result["name"])
}
},
},
{
name: "runner with empty labels",
runner: &ActionRunner{
ID: 2,
Name: "no-labels",
Status: "online",
Labels: []string{},
},
check: func(t *testing.T, result map[string]interface{}) {
labels, ok := result["labels"].([]string)
if !ok || len(labels) != 0 {
t.Errorf("expected empty labels slice, got %v", result["labels"])
}
},
},
{
name: "runner with empty LastOnline",
runner: &ActionRunner{
ID: 3,
Name: "never-online",
Status: "offline",
Online: false,
LastOnline: "",
},
check: func(t *testing.T, result map[string]interface{}) {
if _, exists := result["last_online"]; exists {
t.Error("should not have last_online when empty")
}
},
},
{
name: "runner with many labels",
runner: &ActionRunner{
ID: 4,
Name: "many-labels",
Status: "online",
Labels: []string{"label1", "label2", "label3", "label4", "label5"},
},
check: func(t *testing.T, result map[string]interface{}) {
labels, ok := result["labels"].([]string)
if !ok || len(labels) != 5 {
t.Errorf("expected 5 labels, got %v", result["labels"])
}
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := slimActionRunner(tt.runner)
if result == nil {
t.Fatal("slimActionRunner returned nil")
}
tt.check(t, result)
})
}
}
func TestSlimActionRunners_EdgeCases(t *testing.T) {
tests := []struct {
name string
runners []*ActionRunner
check func(t *testing.T, result map[string]interface{})
}{
{
name: "nil runners slice",
runners: nil,
check: func(t *testing.T, result map[string]interface{}) {
if result["total_count"] != 0 {
t.Errorf("expected total_count 0, got %v", result["total_count"])
}
runners, ok := result["runners"].([]interface{})
if !ok || len(runners) != 0 {
t.Errorf("expected empty runners slice, got %v", result["runners"])
}
},
},
{
name: "single runner",
runners: []*ActionRunner{{ID: 1, Name: "single"}},
check: func(t *testing.T, result map[string]interface{}) {
if result["total_count"] != 1 {
t.Errorf("expected total_count 1, got %v", result["total_count"])
}
runners, ok := result["runners"].([]map[string]interface{})
if !ok || len(runners) != 1 {
t.Errorf("expected 1 runner, got %v", result["runners"])
}
},
},
{
name: "many runners",
runners: []*ActionRunner{
{ID: 1, Name: "runner1"},
{ID: 2, Name: "runner2"},
{ID: 3, Name: "runner3"},
{ID: 4, Name: "runner4"},
{ID: 5, Name: "runner5"},
},
check: func(t *testing.T, result map[string]interface{}) {
if result["total_count"] != 5 {
t.Errorf("expected total_count 5, got %v", result["total_count"])
}
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := slimActionRunners(tt.runners)
tt.check(t, result)
})
}
}
func TestRunnerMapsEqual_EdgeCases(t *testing.T) {
tests := []struct {
name string
a map[string]interface{}
b map[string]interface{}
expected bool
}{
{
name: "both nil",
a: nil,
b: nil,
expected: true,
},
{
name: "one nil",
a: map[string]interface{}{"key": "value"},
b: nil,
expected: false,
},
{
name: "different lengths",
a: map[string]interface{}{"a": 1},
b: map[string]interface{}{"a": 1, "b": 2},
expected: false,
},
{
name: "same keys different values",
a: map[string]interface{}{"key": "value1"},
b: map[string]interface{}{"key": "value2"},
expected: false,
},
{
name: "empty maps",
a: map[string]interface{}{},
b: map[string]interface{}{},
expected: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := runnerMapsEqual(tt.a, tt.b)
if result != tt.expected {
t.Errorf("runnerMapsEqual() = %v, want %v", result, tt.expected)
}
})
}
}
// runnerMapsEqual compares two map[string]interface{} values for equality
func runnerMapsEqual(a, b map[string]interface{}) bool {
if len(a) != len(b) {
return false
}
for k, v := range a {
bv, ok := b[k]
if !ok {
return false
}
// Simple comparison for basic types
switch vv := v.(type) {
case []string:
bvv, ok := bv.([]string)
if !ok || len(vv) != len(bvv) {
return false
}
for i, sv := range vv {
if sv != bvv[i] {
return false
}
}
default:
if v != bv {
return false
}
}
}
return true
}