Luigit
repositories / bugabinga.net

bugabinga.net

personal infrastructure for bugabinga!

owned by admin

services/luci/internal/trigger/trigger_test.go

Raw
package trigger

import (
	"encoding/json"
	"testing"
)

func TestPushEventJSONAndValidation(t *testing.T) {
	data := []byte(`{"kind":"push","repo":"example","old":"0000000000000000000000000000000000000000","new":"abc123","ref":"refs/heads/main"}`)
	event, err := Decode(data)
	if err != nil {
		t.Fatalf("Decode() error = %v", err)
	}

	push, ok := event.(PushEvent)
	if !ok {
		t.Fatalf("event type = %T", event)
	}
	if push.Repo != "example" || push.Ref != "refs/heads/main" || push.New != "abc123" {
		t.Fatalf("push = %#v", push)
	}
	if err := push.Validate(); err != nil {
		t.Fatalf("Validate() error = %v", err)
	}
}

func TestPushEventValidationFailures(t *testing.T) {
	if (PushEvent{Kind: "manual", Repo: "repo", New: "abc", Ref: "refs/heads/main"}).EventKind() != "push" {
		t.Fatal("push event kind mismatch")
	}
	cases := []PushEvent{
		{Kind: "manual", Repo: "repo", New: "abc", Ref: "refs/heads/main"},
		{Kind: "push", New: "abc", Ref: "refs/heads/main"},
		{Kind: "push", Repo: "repo", Ref: "refs/heads/main"},
		{Kind: "push", Repo: "repo", New: "abc"},
	}
	for _, event := range cases {
		if err := event.Validate(); err == nil {
			t.Fatalf("invalid push accepted: %#v", event)
		}
	}
}

func TestScheduleEventJSONAndValidation(t *testing.T) {
	data := []byte(`{"kind":"schedule","repo":"example","job":"nightly","rev":"abc123","ref":"refs/heads/main","minute":"2026-03-04T03:00Z"}`)
	event, err := Decode(data)
	if err != nil {
		t.Fatal(err)
	}
	scheduled, ok := event.(ScheduleEvent)
	if !ok || scheduled.EventKind() != "schedule" || scheduled.Job != "nightly" {
		t.Fatalf("event=%#v", event)
	}
	invalid := scheduled
	invalid.Minute = "yesterday"
	if err := invalid.Validate(); err == nil {
		t.Fatal("invalid minute accepted")
	}
}

func TestManualEventRequiresExactlyOneRefOrRev(t *testing.T) {
	ref := "main"
	rev := "abc123"
	valid := ManualEvent{Kind: "manual", Repo: "example", Job: "check", Ref: &ref, RequestedBy: "oli"}
	if err := valid.Validate(); err != nil {
		t.Fatalf("valid manual rejected: %v", err)
	}

	both := ManualEvent{Kind: "manual", Repo: "example", Job: "check", Ref: &ref, Rev: &rev}
	if err := both.Validate(); err == nil {
		t.Fatal("manual with ref and rev accepted")
	}

	neither := ManualEvent{Kind: "manual", Repo: "example", Job: "check"}
	if err := neither.Validate(); err == nil {
		t.Fatal("manual without ref/rev accepted")
	}
}

func TestManualEventValidationFailures(t *testing.T) {
	ref := "main"
	if (ManualEvent{Kind: "manual", Repo: "repo", Job: "job", Ref: &ref}).EventKind() != "manual" {
		t.Fatal("manual event kind mismatch")
	}
	cases := []ManualEvent{
		{Kind: "push", Repo: "repo", Job: "job", Ref: &ref},
		{Kind: "manual", Job: "job", Ref: &ref},
		{Kind: "manual", Repo: "repo", Ref: &ref},
	}
	for _, event := range cases {
		if err := event.Validate(); err == nil {
			t.Fatalf("invalid manual accepted: %#v", event)
		}
	}
}

func TestDecodeRejectsUnknownKind(t *testing.T) {
	_, err := Decode([]byte(`{"kind":"timer","repo":"example"}`))
	if err == nil {
		t.Fatal("unknown kind accepted")
	}
	if got := err.Error(); got != "unknown trigger kind \"timer\"" {
		t.Fatalf("unexpected error: %s", got)
	}
}

func TestDecodeRejectsMalformedJSONAndInvalidEvents(t *testing.T) {
	cases := [][]byte{
		[]byte(`{`),
		[]byte(`{"kind":"push","repo":[]}`),
		[]byte(`{"kind":"manual","repo":[]}`),
		[]byte(`{"kind":"schedule","repo":[]}`),
		[]byte(`{"kind":"push","repo":"repo"}`),
		[]byte(`{"kind":"manual","repo":"repo","job":"job"}`),
	}
	for _, data := range cases {
		if _, err := Decode(data); err == nil {
			t.Fatalf("invalid JSON/event accepted: %s", data)
		}
	}
}

func TestManualEventEncodesNullRev(t *testing.T) {
	ref := "main"
	event := ManualEvent{Kind: "manual", Repo: "example", Job: "check", Ref: &ref, RequestedBy: "oli"}
	data, err := json.Marshal(event)
	if err != nil {
		t.Fatalf("Marshal() error = %v", err)
	}
	want := `{"kind":"manual","repo":"example","job":"check","ref":"main","rev":null,"requested_by":"oli"}`
	if string(data) != want {
		t.Fatalf("json = %s", data)
	}
}