Skip to content

Commit

Permalink
feat: Allowlist identifiers API operations
Browse files Browse the repository at this point in the history
Added types for allowlist identifiers and API operations for Create,
Delete and List.
  • Loading branch information
gkats committed Feb 5, 2024
1 parent 60ff523 commit f20f555
Show file tree
Hide file tree
Showing 3 changed files with 194 additions and 0 deletions.
18 changes: 18 additions & 0 deletions allowlist_identifier.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package clerk

type AllowlistIdentifier struct {
APIResource
Object string `json:"object"`
ID string `json:"id"`
Identifier string `json:"identifier"`
IdentifierType string `json:"identifier_type"`
InvitationID *string `json:"invitation_id,omitempty"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
}

type AllowlistIdentifierList struct {
APIResource
AllowlistIdentifiers []*AllowlistIdentifier `json:"data"`
TotalCount int64 `json:"total_count"`
}
52 changes: 52 additions & 0 deletions allowlistidentifier/allowlist_identifier.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Package allowlistidentifier provides the Allowlist Identifiers API.
package allowlistidentifier

import (
"context"
"fmt"
"net/http"
"net/url"

"github.com/clerk/clerk-sdk-go/v2"
)

const path = "/allowlist_identifiers"

type CreateParams struct {
clerk.APIParams
Identifier *string `json:"identifier,omitempty"`
Notify *bool `json:"notify,omitempty"`
}

// Create adds a new identifier to the allowlist.
func Create(ctx context.Context, params *CreateParams) (*clerk.AllowlistIdentifier, error) {
req := clerk.NewAPIRequest(http.MethodPost, path)
req.SetParams(params)
identifier := &clerk.AllowlistIdentifier{}
err := clerk.GetBackend().Call(ctx, req, identifier)
return identifier, err
}

// Delete removes an identifier from the allowlist.
func Delete(ctx context.Context, id string) (*clerk.DeletedResource, error) {
path, err := url.JoinPath(path, id)
if err != nil {
return nil, err
}
req := clerk.NewAPIRequest(http.MethodDelete, path)
identifier := &clerk.DeletedResource{}
err = clerk.GetBackend().Call(ctx, req, identifier)
return identifier, err
}

type ListParams struct {
clerk.APIParams
}

// List returns all the identifiers in the allowlist.
func List(ctx context.Context, params *ListParams) (*clerk.AllowlistIdentifierList, error) {
req := clerk.NewAPIRequest(http.MethodGet, fmt.Sprintf("%s?paginated=true", path))
list := &clerk.AllowlistIdentifierList{}
err := clerk.GetBackend().Call(ctx, req, list)
return list, err
}
124 changes: 124 additions & 0 deletions allowlistidentifier/allowlist_identifier_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package allowlistidentifier

import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"testing"

"github.com/clerk/clerk-sdk-go/v2"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestAllowlistIdentifierCreate(t *testing.T) {
identifier := "[email protected]"
id := "alid_123"
clerk.SetBackend(clerk.NewBackend(&clerk.BackendConfig{
HTTPClient: &http.Client{
Transport: &mockRoundTripper{
T: t,
in: json.RawMessage(fmt.Sprintf(`{"identifier":"%s"}`, identifier)),
out: json.RawMessage(fmt.Sprintf(`{"id":"%s","identifier":"%s"}`, id, identifier)),
},
},
}))

allowlistIdentifier, err := Create(context.Background(), &CreateParams{
Identifier: clerk.String(identifier),
})
require.NoError(t, err)
assert.Equal(t, id, allowlistIdentifier.ID)
assert.Equal(t, identifier, allowlistIdentifier.Identifier)
}

func TestAllowlistIdentifierCreate_Error(t *testing.T) {
clerk.SetBackend(clerk.NewBackend(&clerk.BackendConfig{
HTTPClient: &http.Client{
Transport: &mockRoundTripper{
T: t,
status: http.StatusBadRequest,
out: json.RawMessage(`{
"errors":[{
"code":"create-error-code"
}],
"clerk_trace_id":"create-trace-id"
}`),
},
},
}))

_, err := Create(context.Background(), &CreateParams{})
require.Error(t, err)
apiErr, ok := err.(*clerk.APIErrorResponse)
require.True(t, ok)
assert.Equal(t, "create-trace-id", apiErr.TraceID)
require.Equal(t, 1, len(apiErr.Errors))
assert.Equal(t, "create-error-code", apiErr.Errors[0].Code)
}

func TestAllowlistIdentifierDelete(t *testing.T) {
id := "alid_456"
clerk.SetBackend(clerk.NewBackend(&clerk.BackendConfig{
HTTPClient: &http.Client{
Transport: &mockRoundTripper{
T: t,
out: json.RawMessage(fmt.Sprintf(`{"id":"%s","deleted":true}`, id)),
},
},
}))

allowlistIdentifier, err := Delete(context.Background(), id)
require.NoError(t, err)
assert.Equal(t, id, allowlistIdentifier.ID)
assert.True(t, allowlistIdentifier.Deleted)
}

func TestAllowlistIdentifierList(t *testing.T) {
clerk.SetBackend(clerk.NewBackend(&clerk.BackendConfig{
HTTPClient: &http.Client{
Transport: &mockRoundTripper{
T: t,
out: json.RawMessage(`{
"data": [{"id":"alid_123","identifier":"[email protected]"}],
"total_count": 1
}`),
},
},
}))

list, err := List(context.Background(), &ListParams{})
require.NoError(t, err)
assert.Equal(t, int64(1), list.TotalCount)
assert.Equal(t, 1, len(list.AllowlistIdentifiers))
assert.Equal(t, "alid_123", list.AllowlistIdentifiers[0].ID)
assert.Equal(t, "[email protected]", list.AllowlistIdentifiers[0].Identifier)
}

type mockRoundTripper struct {
T *testing.T
status int
in json.RawMessage
out json.RawMessage
}

func (rt *mockRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) {
if rt.status == 0 {
rt.status = http.StatusOK
}
if rt.in != nil {
body, err := io.ReadAll(r.Body)
if err != nil {
return nil, err
}
defer r.Body.Close()
assert.JSONEq(rt.T, string(rt.in), string(body))
}
return &http.Response{
StatusCode: rt.status,
Body: io.NopCloser(bytes.NewReader(rt.out)),
}, nil
}

0 comments on commit f20f555

Please sign in to comment.