diff --git a/client_test.go b/client_test.go index 48bc339..37fc0b0 100644 --- a/client_test.go +++ b/client_test.go @@ -173,7 +173,7 @@ func TestEnroll(t *testing.T) { ctx, cancel = context.WithTimeout(context.Background(), 1*time.Second) defer cancel() cfg, pkey, creds, meta, err = client.Enroll(ctx, testutil.NewTestLogger(), code, "") - require.Errorf(t, err, fmt.Sprintf("unexpected error during enrollment: %s", errorMsg)) + require.EqualError(t, err, "unexpected error during enrollment: "+errorMsg) assert.Nil(t, cfg) assert.Nil(t, pkey) diff --git a/message/message.go b/message/message.go index 8bceb09..e76b33a 100644 --- a/message/message.go +++ b/message/message.go @@ -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. diff --git a/message/message_test.go b/message/message_test.go new file mode 100644 index 0000000..57fd119 --- /dev/null +++ b/message/message_test.go @@ -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) +}