Files
go-iar-notificator/client/client_test.go
Alex Savin cd17d3ae7f
All checks were successful
Golan Testing / testing (1.25.x, ubuntu-latest) (push) Successful in 24s
Add KeepAlive duration to IaR struct and update related functionality; remove obsolete test file
2025-09-09 21:40:33 -04:00

236 lines
6.1 KiB
Go

package client_test
import (
"context"
"io"
"log/slog"
"net/http"
"net/http/httptest"
"testing"
"time"
"git.savin.nyc/alex/go-iar-notificator/client"
"git.savin.nyc/alex/go-iar-notificator/config"
)
const keepAliveResponse = `{
"data": {
"getMutualPagerGroupsList": [
{
"_id": "672783715f6ed07deb857afb",
"subscriberId": 536873008,
"name": "NPFD - 672783715f6ed07deb857afb",
"type": "ab tone",
"tone_tolerance": 0.02,
"gaplength": 0,
"ignore_after": 60,
"record_delay": 2,
"record_seconds": 15,
"release_time": 3,
"playback_during_record": 0,
"post_email_command": "",
"alert_command": "",
"atone": 1656.4,
"btone": 656.1,
"atonelength": 0.9,
"btonelength": 3,
"longtone": null,
"longtonelength": null,
"createDate": "2024-11-03T14:06:41.765Z"
}
],
"getTTDSetting": {
"keySetting": "pollingSeconds",
"keyValue": "900"
}
}
}`
const preAlertResponse = `{
"data": {
"addAlert": {
"_id": "68bb90e0b91373858dd8f214",
"textAlert": "NPFD Received at 21:39:44 09/05/2025",
"pagerGroup": "NPFD",
"subscriberId": 536873008
}
}
}`
const alertResponse = `{
"data": {
"addAlert": {
"_id": "68bb90e0b91373858dd8f214",
"textAlert": "NPFD Received at 21:40:05 09/05/2025",
"pagerGroup": "NPFD",
"audioUrl": "https://storage.iamresponding.com/v3/xzPAzU4ZEXlRtMLtj2NlquvalB26xQfS.mp3",
"subscriberId": 536873008
}
}
}`
// mockLogger returns a no-op slog.Logger for testing
func mockLogger() *slog.Logger {
return slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{}))
}
// mockCredentials returns dummy credentials for testing
func mockCredentials() *config.Credentials {
return &config.Credentials{
SecretKey: "dummy-secret",
TTDApiKey: "dummy-api-key",
}
}
func TestNewClient(t *testing.T) {
logger := mockLogger()
creds := mockCredentials()
c, err := client.New(creds, logger)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if c == nil {
t.Fatal("expected client, got nil")
}
}
func TestIsAliveDefault(t *testing.T) {
logger := mockLogger()
creds := mockCredentials()
c, _ := client.New(creds, logger)
if c.IsAlive() {
t.Error("expected isAlive to be false by default")
}
}
func TestServeKeepAliveCancel(t *testing.T) {
logger := mockLogger()
creds := mockCredentials()
c, _ := client.New(creds, logger)
ctx, cancel := context.WithCancel(context.Background())
go c.ServeKeepAlive(ctx)
// Let it run briefly
time.Sleep(20 * time.Millisecond)
cancel()
// No panic or deadlock expected
}
// patchClientHTTP replaces the HTTPClient's transport with a test server
func patchClientHTTP(c *client.Client, handler http.HandlerFunc) {
ts := httptest.NewServer(handler)
c.HTTPClient.SetBaseURL(ts.URL)
}
func TestClient_KeepAlive_Success(t *testing.T) {
logger := mockLogger()
creds := mockCredentials()
c, err := client.New(creds, logger)
if err != nil {
t.Fatalf("New() error: %v", err)
}
patchClientHTTP(c, func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write([]byte(keepAliveResponse))
})
err = c.KeepAlive()
if err != nil {
t.Errorf("KeepAlive() error = %v, want nil", err)
}
if !c.IsAlive() {
t.Error("expected client to be alive after successful KeepAlive")
}
// Check if IAR is set
if c.IAR.PagerGroupID != "672783715f6ed07deb857afb" {
t.Errorf("expected PagerGroupID to be set, got %s", c.IAR.PagerGroupID)
}
// Check if KeepAlive duration is set from API response (900 seconds = 15 minutes)
expectedDuration := 900 * time.Second
if c.IAR.KeepAlive != expectedDuration {
t.Errorf("expected KeepAlive duration to be %v, got %v", expectedDuration, c.IAR.KeepAlive)
}
}
func TestClient_KeepAlive_Failure(t *testing.T) {
logger := mockLogger()
creds := mockCredentials()
c, err := client.New(creds, logger)
if err != nil {
t.Fatalf("New() error: %v", err)
}
patchClientHTTP(c, func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(`{"error": "fail"}`))
})
err = c.KeepAlive()
if err == nil {
t.Error("expected error from KeepAlive, got nil")
}
if c.IsAlive() {
t.Error("expected client to not be alive after failed KeepAlive")
}
}
func TestClient_PreAlert_Success(t *testing.T) {
logger := mockLogger()
creds := mockCredentials()
c, err := client.New(creds, logger)
if err != nil {
t.Fatalf("New() error: %v", err)
}
// Set IAR
c.IAR.PagerGroupID = "test_group"
patchClientHTTP(c, func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write([]byte(preAlertResponse))
})
alertID, err := c.PreAlert()
if err != nil {
t.Errorf("PreAlert() error = %v, want nil", err)
}
expectedID := "68bb90e0b91373858dd8f214"
if alertID != expectedID {
t.Errorf("expected alertID %s, got %s", expectedID, alertID)
}
}
func TestClient_Alert_Success(t *testing.T) {
logger := mockLogger()
creds := mockCredentials()
c, err := client.New(creds, logger)
if err != nil {
t.Fatalf("New() error: %v", err)
}
// Set IAR
c.IAR.PagerGroupID = "test_group"
callCount := 0
patchClientHTTP(c, func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
if callCount == 0 {
// First call is preAlert
w.Write([]byte(preAlertResponse))
} else {
// Second call is Alert
w.Write([]byte(alertResponse))
}
callCount++
})
err = c.Alert("base64_audio")
if err != nil {
t.Errorf("Alert() error = %v, want nil", err)
}
if callCount != 2 {
t.Errorf("expected 2 HTTP calls, got %d", callCount)
}
}