2021-02-19 20:23:48 +00:00
|
|
|
package internal
|
|
|
|
|
|
|
|
import (
|
2023-05-05 07:49:38 +00:00
|
|
|
"context"
|
2021-02-19 20:23:48 +00:00
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
2023-05-05 07:49:38 +00:00
|
|
|
func setupTest(t *testing.T, handler func(http.ResponseWriter, *http.Request)) *Client {
|
2021-02-19 20:23:48 +00:00
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
mux := http.NewServeMux()
|
|
|
|
server := httptest.NewServer(mux)
|
|
|
|
t.Cleanup(server.Close)
|
|
|
|
|
|
|
|
mux.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) {
|
|
|
|
if req.Method != http.MethodPost {
|
|
|
|
http.Error(rw, fmt.Sprintf("unsupported method: %s", req.Method), http.StatusMethodNotAllowed)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-05-05 07:49:38 +00:00
|
|
|
token := req.Header.Get(authorizationHeader)
|
2021-02-19 20:23:48 +00:00
|
|
|
if token != "Njalla secret" {
|
|
|
|
_, _ = rw.Write([]byte(`{"jsonrpc":"2.0", "Error": {"code": 403, "message": "Invalid token."}}`))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if handler != nil {
|
|
|
|
handler(rw, req)
|
|
|
|
} else {
|
|
|
|
_, _ = rw.Write([]byte(`{"jsonrpc":"2.0"}`))
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
client := NewClient("secret")
|
|
|
|
client.apiEndpoint = server.URL
|
|
|
|
|
|
|
|
return client
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestClient_AddRecord(t *testing.T) {
|
2023-05-05 07:49:38 +00:00
|
|
|
client := setupTest(t, func(rw http.ResponseWriter, req *http.Request) {
|
2021-02-19 20:23:48 +00:00
|
|
|
apiReq := struct {
|
|
|
|
Method string `json:"method"`
|
|
|
|
Params Record `json:"params"`
|
|
|
|
}{}
|
|
|
|
|
|
|
|
err := json.NewDecoder(req.Body).Decode(&apiReq)
|
|
|
|
if err != nil {
|
|
|
|
http.Error(rw, "failed to marshal test request body", http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-08-03 23:06:25 +00:00
|
|
|
apiReq.Params.ID = "123"
|
2021-02-19 20:23:48 +00:00
|
|
|
|
|
|
|
resp := map[string]interface{}{
|
|
|
|
"jsonrpc": "2.0",
|
|
|
|
"id": "897",
|
|
|
|
"result": apiReq.Params,
|
|
|
|
}
|
|
|
|
|
|
|
|
err = json.NewEncoder(rw).Encode(resp)
|
|
|
|
if err != nil {
|
|
|
|
http.Error(rw, "failed to marshal test response", http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
record := Record{
|
|
|
|
Content: "foobar",
|
|
|
|
Domain: "test",
|
|
|
|
Name: "example.com",
|
|
|
|
TTL: 300,
|
|
|
|
Type: "TXT",
|
|
|
|
}
|
|
|
|
|
2023-05-05 07:49:38 +00:00
|
|
|
result, err := client.AddRecord(context.Background(), record)
|
2021-02-19 20:23:48 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
expected := &Record{
|
2022-08-03 23:06:25 +00:00
|
|
|
ID: "123",
|
2021-02-19 20:23:48 +00:00
|
|
|
Content: "foobar",
|
|
|
|
Domain: "test",
|
|
|
|
Name: "example.com",
|
|
|
|
TTL: 300,
|
|
|
|
Type: "TXT",
|
|
|
|
}
|
|
|
|
assert.Equal(t, expected, result)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestClient_AddRecord_error(t *testing.T) {
|
2023-05-05 07:49:38 +00:00
|
|
|
client := setupTest(t, nil)
|
2021-02-19 20:23:48 +00:00
|
|
|
client.token = "invalid"
|
|
|
|
|
|
|
|
record := Record{
|
|
|
|
Content: "test",
|
|
|
|
Domain: "test01",
|
|
|
|
Name: "example.com",
|
|
|
|
TTL: 300,
|
|
|
|
Type: "TXT",
|
|
|
|
}
|
|
|
|
|
2023-05-05 07:49:38 +00:00
|
|
|
result, err := client.AddRecord(context.Background(), record)
|
2021-02-19 20:23:48 +00:00
|
|
|
require.Error(t, err)
|
|
|
|
|
|
|
|
assert.Nil(t, result)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestClient_ListRecords(t *testing.T) {
|
2023-05-05 07:49:38 +00:00
|
|
|
client := setupTest(t, func(rw http.ResponseWriter, req *http.Request) {
|
2021-02-19 20:23:48 +00:00
|
|
|
apiReq := struct {
|
|
|
|
Method string `json:"method"`
|
|
|
|
Params Record `json:"params"`
|
|
|
|
}{}
|
|
|
|
|
|
|
|
err := json.NewDecoder(req.Body).Decode(&apiReq)
|
|
|
|
if err != nil {
|
|
|
|
http.Error(rw, "failed to marshal test request body", http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
resp := map[string]interface{}{
|
|
|
|
"jsonrpc": "2.0",
|
|
|
|
"id": "897",
|
|
|
|
"result": Records{
|
|
|
|
Records: []Record{
|
|
|
|
{
|
2022-08-03 23:06:25 +00:00
|
|
|
ID: "1",
|
2021-02-19 20:23:48 +00:00
|
|
|
Domain: apiReq.Params.Domain,
|
|
|
|
Content: "test",
|
|
|
|
Name: "test01",
|
|
|
|
TTL: 300,
|
|
|
|
Type: "TXT",
|
|
|
|
},
|
|
|
|
{
|
2022-08-03 23:06:25 +00:00
|
|
|
ID: "2",
|
2021-02-19 20:23:48 +00:00
|
|
|
Domain: apiReq.Params.Domain,
|
|
|
|
Content: "txtTxt",
|
|
|
|
Name: "test02",
|
|
|
|
TTL: 120,
|
|
|
|
Type: "TXT",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
err = json.NewEncoder(rw).Encode(resp)
|
|
|
|
if err != nil {
|
|
|
|
http.Error(rw, "failed to marshal test response", http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2023-05-05 07:49:38 +00:00
|
|
|
records, err := client.ListRecords(context.Background(), "example.com")
|
2021-02-19 20:23:48 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
expected := []Record{
|
|
|
|
{
|
2022-08-03 23:06:25 +00:00
|
|
|
ID: "1",
|
2021-02-19 20:23:48 +00:00
|
|
|
Domain: "example.com",
|
|
|
|
Content: "test",
|
|
|
|
Name: "test01",
|
|
|
|
TTL: 300,
|
|
|
|
Type: "TXT",
|
|
|
|
},
|
|
|
|
{
|
2022-08-03 23:06:25 +00:00
|
|
|
ID: "2",
|
2021-02-19 20:23:48 +00:00
|
|
|
Domain: "example.com",
|
|
|
|
Content: "txtTxt",
|
|
|
|
Name: "test02",
|
|
|
|
TTL: 120,
|
|
|
|
Type: "TXT",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.Equal(t, expected, records)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestClient_ListRecords_error(t *testing.T) {
|
2023-05-05 07:49:38 +00:00
|
|
|
client := setupTest(t, nil)
|
2021-02-19 20:23:48 +00:00
|
|
|
client.token = "invalid"
|
|
|
|
|
2023-05-05 07:49:38 +00:00
|
|
|
records, err := client.ListRecords(context.Background(), "example.com")
|
2021-02-19 20:23:48 +00:00
|
|
|
require.Error(t, err)
|
|
|
|
|
|
|
|
assert.Empty(t, records)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestClient_RemoveRecord(t *testing.T) {
|
2023-05-05 07:49:38 +00:00
|
|
|
client := setupTest(t, func(rw http.ResponseWriter, req *http.Request) {
|
2021-02-19 20:23:48 +00:00
|
|
|
apiReq := struct {
|
|
|
|
Method string `json:"method"`
|
|
|
|
Params Record `json:"params"`
|
|
|
|
}{}
|
|
|
|
|
|
|
|
err := json.NewDecoder(req.Body).Decode(&apiReq)
|
|
|
|
if err != nil {
|
|
|
|
http.Error(rw, "failed to marshal test request body", http.StatusInternalServerError)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-08-03 23:06:25 +00:00
|
|
|
if apiReq.Params.ID == "" {
|
2021-02-19 20:23:48 +00:00
|
|
|
_, _ = rw.Write([]byte(`{"jsonrpc":"2.0", "Error": {"code": 400, "message": ""missing ID"}}`))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if apiReq.Params.Domain == "" {
|
|
|
|
_, _ = rw.Write([]byte(`{"jsonrpc":"2.0", "Error": {"code": 400, "message": ""missing domain"}}`))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
_, _ = rw.Write([]byte(`{"jsonrpc":"2.0"}`))
|
|
|
|
})
|
|
|
|
|
2023-05-05 07:49:38 +00:00
|
|
|
err := client.RemoveRecord(context.Background(), "123", "example.com")
|
2021-02-19 20:23:48 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestClient_RemoveRecord_error(t *testing.T) {
|
2023-05-05 07:49:38 +00:00
|
|
|
client := setupTest(t, nil)
|
2021-02-19 20:23:48 +00:00
|
|
|
client.token = "invalid"
|
|
|
|
|
2023-05-05 07:49:38 +00:00
|
|
|
err := client.RemoveRecord(context.Background(), "123", "example.com")
|
2021-02-19 20:23:48 +00:00
|
|
|
require.Error(t, err)
|
|
|
|
}
|