homelabby/internal/netbox/client_test.go
Mikkel Georgsen 6040ecc3cc feat(02-01): install go-openai and add CreateDevice to NetBox client
- go get github.com/sashabaranov/go-openai v1.41.2
- Add CreateDevice(ctx, name, assetTag, deviceTypeID, roleID, siteID) → (int64, error)
- Add DeleteDevice(ctx, id) for test cleanup
- Use Int32As* oneOf helpers for go-netbox v4 FK fields
- TestCreateDeviceValidation PASS; TestCreateDeviceLive SKIP (no live token)
2026-04-10 05:42:51 +00:00

118 lines
3.3 KiB
Go

package netbox_test
import (
"context"
"fmt"
"os"
"testing"
"git.georgsen.dk/hwlab/internal/netbox"
)
func TestNewClientValidation(t *testing.T) {
_, err := netbox.NewClient("", "token")
if err == nil {
t.Error("expected error for empty url")
}
_, err = netbox.NewClient("http://10.5.0.130:8000/api", "")
if err == nil {
t.Error("expected error for empty token")
}
c, err := netbox.NewClient("http://10.5.0.130:8000/api", "sometoken")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if c == nil {
t.Error("expected non-nil client")
}
}
// integrationToken returns the real NetBox token from env, or skips the test
// if only the placeholder is present (placeholder is never 40 hex chars).
func integrationToken(t *testing.T) string {
t.Helper()
token := os.Getenv("HWLAB_NETBOX_TOKEN")
if len(token) != 40 {
t.Skip("HWLAB_NETBOX_TOKEN is not a real 40-char token — skipping integration test")
}
return token
}
func TestPingLive(t *testing.T) {
token := integrationToken(t)
c, err := netbox.NewClient("http://10.5.0.130:8000/api", token)
if err != nil {
t.Fatalf("NewClient: %v", err)
}
if err := c.Ping(context.Background()); err != nil {
t.Fatalf("Ping: %v", err)
}
}
func TestListDevicesLive(t *testing.T) {
token := integrationToken(t)
c, _ := netbox.NewClient("http://10.5.0.130:8000/api", token)
devices, err := c.ListDevices(context.Background(), 5)
if err != nil {
t.Fatalf("ListDevices: %v", err)
}
t.Logf("found %d devices in NetBox", len(devices))
// Not asserting count — NetBox may be empty; just assert no error
}
// TestCreateDeviceValidation verifies that CreateDevice rejects an empty name
// without making any NetBox API call.
func TestCreateDeviceValidation(t *testing.T) {
c, err := netbox.NewClient("http://10.5.0.130:8000/api", "sometoken")
if err != nil {
t.Fatalf("NewClient: %v", err)
}
_, err = c.CreateDevice(context.Background(), "", "HW-00001", 1, 1, 1)
if err == nil {
t.Error("expected error for empty device name")
}
}
// TestCreateDeviceLive creates a real device in NetBox and deletes it as cleanup.
// Requires HWLAB_NETBOX_TOKEN (40 chars) and HWLAB_TEST_SITE_ID to be set.
func TestCreateDeviceLive(t *testing.T) {
token := integrationToken(t)
siteIDStr := os.Getenv("HWLAB_TEST_SITE_ID")
if siteIDStr == "" {
t.Skip("HWLAB_TEST_SITE_ID not set — skipping live CreateDevice test")
}
// Parse site ID
var siteID int32
if _, err := fmt.Sscanf(siteIDStr, "%d", &siteID); err != nil {
t.Fatalf("HWLAB_TEST_SITE_ID is not a valid int: %v", err)
}
// These must exist in the NetBox instance used for integration testing.
// Device type 1 and role 1 are typically pre-provisioned.
const (
testDeviceTypeID int32 = 1
testRoleID int32 = 1
)
c, err := netbox.NewClient("http://10.5.0.130:8000/api", token)
if err != nil {
t.Fatalf("NewClient: %v", err)
}
id, err := c.CreateDevice(context.Background(), "hwlab-test-device", "HW-TEST-01", testDeviceTypeID, testRoleID, siteID)
if err != nil {
t.Fatalf("CreateDevice: %v", err)
}
if id <= 0 {
t.Errorf("expected positive device ID, got %d", id)
}
t.Logf("created device id=%d — will clean up", id)
// Cleanup: delete the test device
if err := c.DeleteDevice(context.Background(), id); err != nil {
t.Logf("cleanup warning: DeleteDevice(%d): %v", id, err)
}
}