Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions message/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,10 @@ type ReauthenticateResponse struct {
}

// APIResponse is a standard format for the DN API. It does not apply to the DNClient API.
// The API sends exactly one of data or errors.
type APIResponse[T any] struct {
Data T `json:"data"`
Errors APIResponseErrors `json:"errors"`
Data T `json:"data,omitzero"`
Errors APIResponseErrors `json:"errors,omitempty"`
}

// APIResponseError represents a single error returned in an API error response.
Expand Down
37 changes: 37 additions & 0 deletions message/message_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package message

import (
"encoding/json"
"testing"

"github.com/stretchr/testify/require"
)

func TestAPIResponseErrorOnlyRoundTrip(t *testing.T) {
b, err := json.Marshal(APIResponse[EnrollResponseData]{
Errors: APIResponseErrors{{Code: "ERR_TEST", Message: "test error"}},
})
require.NoError(t, err)
require.NotContains(t, string(b), `"data"`)

var r APIResponse[EnrollResponseData]
require.NoError(t, json.Unmarshal(b, &r))
require.EqualError(t, r.Errors.Err(), "test error")
}

func TestAPIResponseDataOnlyOmitsErrors(t *testing.T) {
b, err := json.Marshal(APIResponse[EnrollResponseData]{
Data: EnrollResponseData{
HostID: "foobar",
// a valid curve is required for the decode below, as on the real API
Network: HostNetworkMetadata{Curve: NetworkCurve25519},
},
})
require.NoError(t, err)
require.NotContains(t, string(b), `"errors"`)

var r APIResponse[EnrollResponseData]
require.NoError(t, json.Unmarshal(b, &r))
require.NoError(t, r.Errors.Err())
require.Equal(t, "foobar", r.Data.HostID)
}
Loading