ping_test.go

  1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
  2//
  3// SPDX-License-Identifier: AGPL-3.0-or-later
  4
  5package lunatask_test
  6
  7import (
  8	"context"
  9	"errors"
 10	"net/http"
 11	"net/http/httptest"
 12	"testing"
 13
 14	"git.secluded.site/go-lunatask"
 15)
 16
 17type pingTestCase struct {
 18	name           string
 19	statusCode     int
 20	responseBody   string
 21	wantMessage    string
 22	wantErr        error
 23	checkAuthToken string
 24}
 25
 26func TestPing(t *testing.T) {
 27	t.Parallel()
 28
 29	tests := []pingTestCase{
 30		{
 31			name:           "success",
 32			statusCode:     http.StatusOK,
 33			responseBody:   `{"message": "pong"}`,
 34			wantMessage:    "pong",
 35			wantErr:        nil,
 36			checkAuthToken: "test-token",
 37		},
 38		{
 39			name:           "unauthorized",
 40			statusCode:     http.StatusUnauthorized,
 41			responseBody:   `{"error": "unauthorized"}`,
 42			wantMessage:    "",
 43			wantErr:        lunatask.ErrUnauthorized,
 44			checkAuthToken: "bad-token",
 45		},
 46		{
 47			name:           "server_error",
 48			statusCode:     http.StatusInternalServerError,
 49			responseBody:   `{"error": "internal server error"}`,
 50			wantMessage:    "",
 51			wantErr:        lunatask.ErrServerError,
 52			checkAuthToken: "test-token",
 53		},
 54	}
 55
 56	for _, testCase := range tests {
 57		t.Run(testCase.name, func(t *testing.T) {
 58			t.Parallel()
 59			runPingTest(t, testCase)
 60		})
 61	}
 62}
 63
 64func runPingTest(t *testing.T, testCase pingTestCase) {
 65	t.Helper()
 66
 67	server := httptest.NewServer(makePingHandler(t, testCase.checkAuthToken, testCase.statusCode, testCase.responseBody))
 68	defer server.Close()
 69
 70	client := lunatask.NewClient(testCase.checkAuthToken, lunatask.BaseURL(server.URL))
 71	resp, err := client.Ping(context.Background())
 72
 73	if testCase.wantErr != nil {
 74		if err == nil {
 75			t.Fatalf("expected error %v, got nil", testCase.wantErr)
 76		}
 77
 78		if !errors.Is(err, testCase.wantErr) {
 79			t.Errorf("expected error %v, got %v", testCase.wantErr, err)
 80		}
 81
 82		return
 83	}
 84
 85	if err != nil {
 86		t.Fatalf("unexpected error: %v", err)
 87	}
 88
 89	if resp == nil {
 90		t.Fatal("expected response, got nil")
 91	}
 92
 93	if resp.Message != testCase.wantMessage {
 94		t.Errorf("expected message %q, got %q", testCase.wantMessage, resp.Message)
 95	}
 96}
 97
 98func makePingHandler(t *testing.T, expectedToken string, statusCode int, responseBody string) http.HandlerFunc {
 99	t.Helper()
100
101	return func(writer http.ResponseWriter, req *http.Request) {
102		if req.Method != http.MethodGet {
103			t.Errorf("expected GET request, got %s", req.Method)
104		}
105
106		if req.URL.Path != "/ping" {
107			t.Errorf("expected /ping path, got %s", req.URL.Path)
108		}
109
110		authHeader := req.Header.Get("Authorization")
111		expectedAuth := "bearer " + expectedToken
112
113		if authHeader != expectedAuth {
114			t.Errorf("expected Authorization header %q, got %q", expectedAuth, authHeader)
115		}
116
117		writer.WriteHeader(statusCode)
118
119		if _, err := writer.Write([]byte(responseBody)); err != nil {
120			t.Errorf("failed to write response: %v", err)
121		}
122	}
123}