Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Allowlist identifiers API operations #218

Merged
merged 1 commit into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
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
}
Loading