package internal import ( "context" "fmt" "io" "net/http" "net/http/httptest" "net/url" "os" "path/filepath" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func setupTest(t *testing.T) (*Client, *http.ServeMux) { t.Helper() mux := http.NewServeMux() server := httptest.NewServer(mux) t.Cleanup(server.Close) client := NewClient("secret") client.baseURL, _ = url.Parse(server.URL) client.zoneEndpoint = server.URL client.HTTPClient = server.Client() return client, mux } func testHandler(method string, statusCode int, filename string) func(rw http.ResponseWriter, req *http.Request) { return func(rw http.ResponseWriter, req *http.Request) { if req.Method != method { http.Error(rw, fmt.Sprintf("unsupported method %s", req.Method), http.StatusBadRequest) return } username, password, ok := req.BasicAuth() if !ok { http.Error(rw, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return } if username != "api" { http.Error(rw, fmt.Sprintf("username: want %s got %s", username, "user"), http.StatusUnauthorized) return } if password != "secret" { http.Error(rw, fmt.Sprintf("password: want %s got %s", password, "secret"), http.StatusUnauthorized) return } file, err := os.Open(filepath.Join("fixtures", filename)) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } defer func() { _ = file.Close() }() rw.WriteHeader(statusCode) _, err = io.Copy(rw, file) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } } } func TestGetRecords(t *testing.T) { client, mux := setupTest(t) mux.HandleFunc("/zones/47c0ecf6c91243308c649ad1d2d618dd/dnsrecords", testHandler(http.MethodGet, http.StatusOK, "records-GET.json")) records, err := client.GetRecords(context.Background(), "47c0ecf6c91243308c649ad1d2d618dd", &GetRecordsParameters{DNSType: "TXT", Content: `"test"'`}) require.NoError(t, err) excepted := &GetRecordsResponse{Data: []Record{ { Type: "A", Host: "example.com", Content: "188.114.97.3", ID: "812bee17a0b440b0bd5ee099a78b839c", }, { Type: "A", Host: "example.com", Content: "188.114.96.3", ID: "90e6029da45d4a36bf31056cf85d0cab", }, { Type: "AAAA", Host: "example.com", Content: "2a06:98c1:3121::7", ID: "0ac0320da0d24b5ca4f1648986a17340", }, { Type: "AAAA", Host: "example.com", Content: "2a06:98c1:3120::7", ID: "c91599694aea413498a0b3cd0a54a585", }, { Type: "A", Host: "www", Content: "188.114.96.7", ID: "c21f974992d549499f92e768bc468374", }, { Type: "A", Host: "www", Content: "188.114.97.7", ID: "90c3c1f05dca426893f10f122d18ad7a", }, { Type: "AAAA", Host: "www", Content: "2a06:98c1:3121::", ID: "379ab0ac0e434bc9aee5287e497f88a5", }, { Type: "AAAA", Host: "www", Content: "2a06:98c1:3120::", ID: "a1c4f9e50ba74791a4d70dc96999474c", }, }, Count: 8} assert.Equal(t, excepted, records) } func TestGetRecords_error(t *testing.T) { client, mux := setupTest(t) mux.HandleFunc("/zones/47c0ecf6c91243308c649ad1d2d618dd/dnsrecords", testHandler(http.MethodGet, http.StatusUnauthorized, "error.json")) _, err := client.GetRecords(context.Background(), "47c0ecf6c91243308c649ad1d2d618dd", &GetRecordsParameters{DNSType: "TXT", Content: `"test"'`}) require.Error(t, err) } func TestGetRecord(t *testing.T) { client, mux := setupTest(t) mux.HandleFunc("/zones/47c0ecf6c91243308c649ad1d2d618dd/dnsrecords/812bee17a0b440b0bd5ee099a78b839c", testHandler(http.MethodGet, http.StatusOK, "record-GET.json")) record, err := client.GetRecord(context.Background(), "47c0ecf6c91243308c649ad1d2d618dd", "812bee17a0b440b0bd5ee099a78b839c") require.NoError(t, err) excepted := &Record{ Type: "A", Host: "example.com", Content: "188.114.97.3", ID: "812bee17a0b440b0bd5ee099a78b839c", } assert.Equal(t, excepted, record) } func TestGetRecord_error(t *testing.T) { client, mux := setupTest(t) mux.HandleFunc("/zones/47c0ecf6c91243308c649ad1d2d618dd/dnsrecords/812bee17a0b440b0bd5ee099a78b839c", testHandler(http.MethodGet, http.StatusUnauthorized, "error.json")) _, err := client.GetRecord(context.Background(), "47c0ecf6c91243308c649ad1d2d618dd", "812bee17a0b440b0bd5ee099a78b839c") require.Error(t, err) } func TestCreateRecord(t *testing.T) { client, mux := setupTest(t) mux.HandleFunc("/zones/47c0ecf6c91243308c649ad1d2d618dd/dnsrecords", testHandler(http.MethodPut, http.StatusCreated, "record-PUT.json")) r := Record{ Type: "TXT", Host: "test", Content: "test", TTL: 120, } record, err := client.CreateRecord(context.Background(), "47c0ecf6c91243308c649ad1d2d618dd", r) require.NoError(t, err) excepted := &Record{ Type: "A", Host: "example.com", Content: "188.114.97.3", ID: "812bee17a0b440b0bd5ee099a78b839c", } assert.Equal(t, excepted, record) } func TestCreateRecord_error(t *testing.T) { client, mux := setupTest(t) mux.HandleFunc("/zones/47c0ecf6c91243308c649ad1d2d618dd/dnsrecords", testHandler(http.MethodPut, http.StatusUnauthorized, "error.json")) r := Record{ Type: "TXT", Host: "test", Content: "test", TTL: 120, } _, err := client.CreateRecord(context.Background(), "47c0ecf6c91243308c649ad1d2d618dd", r) require.Error(t, err) } func TestEditRecord(t *testing.T) { client, mux := setupTest(t) mux.HandleFunc("/zones/47c0ecf6c91243308c649ad1d2d618dd/dnsrecords/eebc813de2f94d67b09d91e10e2d65c2", testHandler(http.MethodPatch, http.StatusOK, "record-PATCH.json")) record, err := client.EditRecord(context.Background(), "47c0ecf6c91243308c649ad1d2d618dd", "eebc813de2f94d67b09d91e10e2d65c2", Record{ Content: "foo", }) require.NoError(t, err) excepted := &Record{ Type: "A", Host: "example.com", Content: "188.114.97.3", ID: "812bee17a0b440b0bd5ee099a78b839c", } assert.Equal(t, excepted, record) } func TestEditRecord_error(t *testing.T) { client, mux := setupTest(t) mux.HandleFunc("/zones/47c0ecf6c91243308c649ad1d2d618dd/dnsrecords/eebc813de2f94d67b09d91e10e2d65c2", testHandler(http.MethodPatch, http.StatusUnauthorized, "error.json")) _, err := client.EditRecord(context.Background(), "47c0ecf6c91243308c649ad1d2d618dd", "eebc813de2f94d67b09d91e10e2d65c2", Record{ Content: "foo", }) require.Error(t, err) } func TestDeleteRecord(t *testing.T) { client, mux := setupTest(t) mux.HandleFunc("/zones/47c0ecf6c91243308c649ad1d2d618dd/dnsrecords/653464211b7447a1bee6b8fcb9fb86df", testHandler(http.MethodDelete, http.StatusOK, "record-DELETE.json")) err := client.DeleteRecord(context.Background(), "47c0ecf6c91243308c649ad1d2d618dd", "653464211b7447a1bee6b8fcb9fb86df") require.NoError(t, err) } func TestDeleteRecord_error(t *testing.T) { client, mux := setupTest(t) mux.HandleFunc("/zones/47c0ecf6c91243308c649ad1d2d618dd/dnsrecords/653464211b7447a1bee6b8fcb9fb86df", testHandler(http.MethodDelete, http.StatusUnauthorized, "error.json")) err := client.DeleteRecord(context.Background(), "47c0ecf6c91243308c649ad1d2d618dd", "653464211b7447a1bee6b8fcb9fb86df") require.Error(t, err) } func TestGetZones(t *testing.T) { client, mux := setupTest(t) mux.HandleFunc("/", testHandler(http.MethodGet, http.StatusOK, "service-cdn-zones.json")) zones, err := client.GetZones(context.Background()) require.NoError(t, err) excepted := []Zone{{ ID: "47c0ecf6c91243308c649ad1d2d618dd", Tags: []string{}, ContextID: "47c0ecf6c91243308c649ad1d2d618dd", ContextType: "CDN", HumanReadable: "example.com", Serial: "2301449956", CreationTime: 1679090659902, CreationTimeDate: time.Date(2023, time.March, 17, 22, 4, 19, 902000000, time.UTC), Status: "active", IsMoved: true, Paused: false, ServiceType: "CDN", Limbo: false, TeamName: "test", TeamID: "640ef58496738d38fa7246a4", MyTeam: true, RoleName: "owner", IsBoard: true, BoardRole: []string{"owner"}, }} assert.Equal(t, excepted, zones) } func TestGetZones_error(t *testing.T) { client, mux := setupTest(t) mux.HandleFunc("/", testHandler(http.MethodGet, http.StatusUnauthorized, "error.json")) _, err := client.GetZones(context.Background()) require.Error(t, err) }