Fork channel

Create a new channel as a copy of main.

Rename channel

Rename main to:

Delete channel

Delete main? This cannot be undone.

isnight_test.go
package calls

import (
	"testing"
	"time"

	"github.com/sixdouglas/suncalc"
)

func TestIsNightOutputString(t *testing.T) {
	output := IsNightOutput{
		FilePath:     "/data/test.WAV",
		TimestampUTC: "2025-06-15T08:00:00Z",
		MidpointUTC:  "2025-06-15T08:30:00Z",
		DurationSec:  600,
		TimestampSrc: "filename",
		SolarNight:   false,
		CivilNight:   false,
		MoonPhase:    0.75,
		SunriseUTC:   "2025-06-15T07:30:00Z",
		SunsetUTC:    "2025-06-15T17:15:00Z",
	}

	s := output.String()

	if !contains(s, "/data/test.WAV") {
		t.Error("String() missing file path")
	}
	if !contains(s, "2025-06-15T08:00:00Z") {
		t.Error("String() missing timestamp")
	}
	if !contains(s, "600.0 seconds") {
		t.Error("String() missing duration")
	}
	if !contains(s, "filename") {
		t.Error("String() missing source")
	}
	if !contains(s, "Solar night: false") {
		t.Error("String() missing solar night")
	}
	if !contains(s, "0.75") {
		t.Error("String() missing moon phase")
	}
	if !contains(s, "Sunrise (UTC):") {
		t.Error("String() missing sunrise")
	}
	if !contains(s, "Sunset (UTC):") {
		t.Error("String() missing sunset")
	}
}

func TestIsNightOutputString_OmitsEmptySunTimes(t *testing.T) {
	output := IsNightOutput{
		FilePath:     "test.WAV",
		TimestampUTC: "2025-01-01T00:00:00Z",
		MidpointUTC:  "2025-01-01T00:30:00Z",
		DurationSec:  60,
		TimestampSrc: "file_mod_time",
		SolarNight:   true,
		CivilNight:   true,
		MoonPhase:    0.1,
	}

	s := output.String()

	if contains(s, "Sunrise") {
		t.Error("String() should not contain Sunrise when empty")
	}
	if contains(s, "Sunset") {
		t.Error("String() should not contain Sunset when empty")
	}
	if contains(s, "Dawn") {
		t.Error("String() should not contain Dawn when empty")
	}
	if contains(s, "Dusk") {
		t.Error("String() should not contain Dusk when empty")
	}
}

func TestSunTimeUTC(t *testing.T) {
	ts := time.Date(2025, 6, 15, 7, 30, 0, 0, time.UTC)
	sunTimes := map[suncalc.DayTimeName]suncalc.DayTime{
		suncalc.Sunrise: {Value: ts},
		suncalc.Sunset:  {Value: time.Time{}}, // zero value
	}

	t.Run("valid sun time returns RFC3339", func(t *testing.T) {
		got := sunTimeUTC(sunTimes, suncalc.Sunrise)
		want := "2025-06-15T07:30:00Z"
		if got != want {
			t.Errorf("got %q, want %q", got, want)
		}
	})

	t.Run("zero time returns empty string", func(t *testing.T) {
		got := sunTimeUTC(sunTimes, suncalc.Sunset)
		if got != "" {
			t.Errorf("got %q, want empty string for zero time", got)
		}
	})

	t.Run("missing key returns empty string", func(t *testing.T) {
		got := sunTimeUTC(sunTimes, suncalc.Dawn)
		if got != "" {
			t.Errorf("got %q, want empty string for missing key", got)
		}
	})
}

func contains(s, substr string) bool {
	for i := 0; i <= len(s)-len(substr); i++ {
		if s[i:i+len(substr)] == substr {
			return true
		}
	}
	return false
}