integration_test.go

  1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
  2//
  3// SPDX-License-Identifier: AGPL-3.0-or-later
  4
  5//go:build integration
  6
  7package lunatask_test
  8
  9import (
 10	"os"
 11	"testing"
 12	"time"
 13
 14	lunatask "git.secluded.site/go-lunatask"
 15)
 16
 17var (
 18	integrationClient *lunatask.Client
 19	testAreaID        string
 20)
 21
 22func TestMain(m *testing.M) {
 23	apiKey := os.Getenv("LUNATASK_API_KEY")
 24	if apiKey == "" {
 25		panic("LUNATASK_API_KEY environment variable required for integration tests")
 26	}
 27
 28	testAreaID = os.Getenv("LUNATASK_TEST_AREA")
 29	if testAreaID == "" {
 30		panic("LUNATASK_TEST_AREA environment variable required for integration tests")
 31	}
 32
 33	integrationClient = lunatask.NewClient(apiKey)
 34
 35	os.Exit(m.Run())
 36}
 37
 38// testName generates a unique name for test entities.
 39func testName(prefix string) string {
 40	return prefix + "-" + time.Now().Format("20060102-150405.000")
 41}
 42
 43func TestIntegration_Ping(t *testing.T) {
 44	resp, err := integrationClient.Ping(ctx())
 45	if err != nil {
 46		t.Fatalf("Ping() error = %v", err)
 47	}
 48
 49	t.Logf("Ping response: %+v", resp)
 50}
 51
 52func TestIntegration_ListTasks(t *testing.T) {
 53	tasks, err := integrationClient.ListTasks(ctx(), nil)
 54	if err != nil {
 55		t.Fatalf("ListTasks() error = %v", err)
 56	}
 57
 58	t.Logf("Found %d tasks", len(tasks))
 59}
 60
 61func TestIntegration_ListNotes(t *testing.T) {
 62	notes, err := integrationClient.ListNotes(ctx(), nil)
 63	if err != nil {
 64		t.Fatalf("ListNotes() error = %v", err)
 65	}
 66
 67	t.Logf("Found %d notes", len(notes))
 68}
 69
 70func TestIntegration_ListPeople(t *testing.T) {
 71	people, err := integrationClient.ListPeople(ctx(), nil)
 72	if err != nil {
 73		t.Fatalf("ListPeople() error = %v", err)
 74	}
 75
 76	t.Logf("Found %d people", len(people))
 77}
 78
 79func TestIntegration_TaskRoundTrip(t *testing.T) {
 80	name := testName("integration-task")
 81
 82	task, err := integrationClient.NewTask(name).
 83		InArea(testAreaID).
 84		WithStatus(lunatask.StatusNext).
 85		WithEstimate(15).
 86		Create(ctx())
 87	if err != nil {
 88		t.Fatalf("NewTask().Create() error = %v", err)
 89	}
 90
 91	if task == nil {
 92		t.Fatal("NewTask().Create() returned nil (duplicate?)")
 93	}
 94
 95	t.Cleanup(func() {
 96		if _, err := integrationClient.DeleteTask(ctx(), task.ID); err != nil {
 97			t.Errorf("DeleteTask() cleanup error = %v", err)
 98		}
 99	})
100
101	t.Logf("Created task: %s", task.ID)
102
103	// Verify we can fetch it
104	fetched, err := integrationClient.GetTask(ctx(), task.ID)
105	if err != nil {
106		t.Fatalf("GetTask() error = %v", err)
107	}
108
109	if fetched.ID != task.ID {
110		t.Errorf("GetTask().ID = %s, want %s", fetched.ID, task.ID)
111	}
112
113	// Update it
114	updated, err := integrationClient.NewTaskUpdate(task.ID).
115		WithEstimate(30).
116		Update(ctx())
117	if err != nil {
118		t.Fatalf("NewTaskUpdate().Update() error = %v", err)
119	}
120
121	if updated.Estimate == nil || *updated.Estimate != 30 {
122		t.Errorf("updated estimate = %v, want 30", updated.Estimate)
123	}
124
125	t.Logf("Updated task estimate to 30 minutes")
126}
127
128func TestIntegration_NoteRoundTrip(t *testing.T) {
129	name := testName("integration-note")
130
131	note, err := integrationClient.NewNote().
132		WithName(name).
133		WithContent("# Test Note\n\nThis is a test.").
134		Create(ctx())
135	if err != nil {
136		t.Fatalf("NewNote().Create() error = %v", err)
137	}
138
139	if note == nil {
140		t.Fatal("NewNote().Create() returned nil (duplicate?)")
141	}
142
143	t.Cleanup(func() {
144		if _, err := integrationClient.DeleteNote(ctx(), note.ID); err != nil {
145			t.Errorf("DeleteNote() cleanup error = %v", err)
146		}
147	})
148
149	t.Logf("Created note: %s", note.ID)
150
151	// Verify we can fetch it
152	fetched, err := integrationClient.GetNote(ctx(), note.ID)
153	if err != nil {
154		t.Fatalf("GetNote() error = %v", err)
155	}
156
157	if fetched.ID != note.ID {
158		t.Errorf("GetNote().ID = %s, want %s", fetched.ID, note.ID)
159	}
160
161	// Update it
162	updated, err := integrationClient.NewNoteUpdate(note.ID).
163		WithContent("# Updated\n\nNew content.").
164		Update(ctx())
165	if err != nil {
166		t.Fatalf("NewNoteUpdate().Update() error = %v", err)
167	}
168
169	t.Logf("Updated note: %s", updated.ID)
170}