Skip to content

Commit

Permalink
Add 'License Key Instances' implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
AchoArnold committed Apr 22, 2023
1 parent 8863f9e commit 1af38c0
Show file tree
Hide file tree
Showing 7 changed files with 289 additions and 0 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ import "github.com/NdoleStudio/lemonsqueezy-go"
- **License Keys**
- `GET /v1/license-keys/:id`: Retrieve a license key
- `GET /v1/license-keys`: List all license keys
- **License Key Instances**
- `GET /v1/license-key-instances/:id`: Retrieve a license key instance
- `GET /v1/license-key-instances`: List all license keys instance
- **Checkouts**
- `POST /v1/checkouts`: Create a checkout
- `GET /v1/checkouts/:id`: Retrieve a checkout
Expand Down Expand Up @@ -123,3 +126,5 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
- In the payload of https://docs.lemonsqueezy.com/api/order-items#list-all-order-items, remove extra `,` in the `links` property.
- In the payload of https://docs.lemonsqueezy.com/api/subscription-invoices#list-all-subscription-invoices, remove extra `,` in the `links` property.
- In the payload of https://docs.lemonsqueezy.com/api/discount-redemptions#list-all-discount-redemptions, remove extra `,` in the `links` property.
- In the payload of https://docs.lemonsqueezy.com/api/license-key-instances#list-all-license-key-instances, remove extra `,` in the `links` property.
- In the payload of https://docs.lemonsqueezy.com/api/license-keys#list-all-license-keys, remove extra `,` in the `links` property.
2 changes: 2 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type Client struct {
Discounts *DiscountsService
Checkouts *CheckoutsService
LicenseKeys *LicenseKeysService
LicenseKeyInstances *LicenseKeyInstancesService
}

// New creates and returns a new Client from a slice of Option.
Expand Down Expand Up @@ -69,6 +70,7 @@ func New(options ...Option) *Client {
client.Discounts = (*DiscountsService)(&client.common)
client.Checkouts = (*CheckoutsService)(&client.common)
client.LicenseKeys = (*LicenseKeysService)(&client.common)
client.LicenseKeyInstances = (*LicenseKeyInstancesService)(&client.common)

return client
}
Expand Down
34 changes: 34 additions & 0 deletions e2e/license_key_instance_service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package e2e

import (
"context"
"net/http"
"testing"

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

func TestLicenseKeyInstancesService_Get(t *testing.T) {
// Setup
t.Parallel()

_, response, err := client.LicenseKeyInstances.Get(context.Background(), "9959")

// Assert
assert.NotNil(t, err)

assert.Equal(t, http.StatusNotFound, response.HTTPResponse.StatusCode)
}

func TestLicenseKeyInstancesService_List(t *testing.T) {
// Setup
t.Parallel()

licenseKeys, response, err := client.LicenseKeyInstances.List(context.Background())

// Assert
assert.Nil(t, err)

assert.Equal(t, http.StatusOK, response.HTTPResponse.StatusCode)
assert.Equal(t, 0, len(licenseKeys.Data))
}
86 changes: 86 additions & 0 deletions internal/stubs/license_key_instance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package stubs

// LicenseKeyInstanceGetResponse is a dummy response to the GET /v1/license-key-instances/:id endpoint
func LicenseKeyInstanceGetResponse() []byte {
return []byte(`
{
"jsonapi": {
"version": "1.0"
},
"links": {
"self": "https://api.lemonsqueezy.com/v1/license-key-instances/1"
},
"data": {
"type": "license-key-instances",
"id": "1",
"attributes": {
"license_key_id": 1,
"identifier": "f70a79fa-6054-433e-9c1b-6075344292e4",
"name": "example.com",
"created_at": "2022-11-14T11:45:39.000000Z",
"updated_at": "2022-11-14T11:45:39.000000Z"
},
"relationships": {
"license-key": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/license-key-instances/1/license-key",
"self": "https://api.lemonsqueezy.com/v1/license-key-instances/1/relationships/license-key"
}
}
},
"links": {
"self": "https://api.lemonsqueezy.com/v1/license-key-instances/1"
}
}
}
`)
}

// LicenseKeyInstancesListResponse is a dummy response to GET /v1/license-key-instances
func LicenseKeyInstancesListResponse() []byte {
return []byte(`
{
"meta": {
"page": {
"currentPage": 1,
"from": 1,
"lastPage": 1,
"perPage": 10,
"to": 10,
"total": 10
}
},
"jsonapi": {
"version": "1.0"
},
"links": {
"first": "https://api.lemonsqueezy.com/v1/license-key-instances?page%5Bnumber%5D=1&page%5Bsize%5D=10&sort=id",
"last": "https://api.lemonsqueezy.com/v1/license-key-instances?page%5Bnumber%5D=1&page%5Bsize%5D=10&sort=id"
},
"data": [
{
"type": "license-key-instances",
"id": "1",
"attributes": {
"license_key_id": 1,
"identifier": "f70a79fa-6054-433e-9c1b-6075344292e4",
"name": "example.com",
"created_at": "2022-11-14T11:45:39.000000Z",
"updated_at": "2022-11-14T11:45:39.000000Z"
},
"relationships": {
"license-key": {
"links": {
"related": "https://api.lemonsqueezy.com/v1/license-key-instances/1/license-key",
"self": "https://api.lemonsqueezy.com/v1/license-key-instances/1/relationships/license-key"
}
}
},
"links": {
"self": "https://api.lemonsqueezy.com/v1/license-key-instances/1"
}
}
]
}
`)
}
23 changes: 23 additions & 0 deletions license_key_instance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package client

import "time"

// LicenseKeyInstanceAttributes represents a single instance (or activation) of a license key that has been issued to a customer.
type LicenseKeyInstanceAttributes struct {
LicenseKeyID int `json:"license_key_id"`
Identifier string `json:"identifier"`
Name string `json:"name"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}

// ApiResponseRelationshipsLicenseKeyInstance relationships of a license key
type ApiResponseRelationshipsLicenseKeyInstance struct {
LicenseKey ApiResponseLinks `json:"license-key"`
}

// LicenseKeyInstanceApiResponse is the api response for one subscription invoice
type LicenseKeyInstanceApiResponse = ApiResponse[LicenseKeyInstanceAttributes, ApiResponseRelationshipsLicenseKeyInstance]

// LicenseKeyInstancesApiResponse is the api response for a list of subscription invoices.
type LicenseKeyInstancesApiResponse = ApiResponseList[LicenseKeyInstanceAttributes, ApiResponseRelationshipsLicenseKeyInstance]
44 changes: 44 additions & 0 deletions license_key_instance_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package client

import (
"context"
"encoding/json"
"net/http"
)

// LicenseKeyInstancesService is the API client for the `/v1/license-key-instances` endpoint
type LicenseKeyInstancesService service

// Get retrieves the license key instance with the given ID.
//
// https://docs.lemonsqueezy.com/api/license-key-instances#retrieve-a-license-key-instance
func (service *LicenseKeyInstancesService) Get(ctx context.Context, licenseKeyID string) (*LicenseKeyInstanceApiResponse, *Response, error) {
response, err := service.client.do(ctx, http.MethodGet, "/v1/license-key-instances/"+licenseKeyID)
if err != nil {
return nil, response, err
}

licenseKeyInstance := new(LicenseKeyInstanceApiResponse)
if err = json.Unmarshal(*response.Body, licenseKeyInstance); err != nil {
return nil, response, err
}

return licenseKeyInstance, response, nil
}

// List a paginated list of license key instances.
//
// https://docs.lemonsqueezy.com/api/license-key-instances#list-all-license-key-instances
func (service *LicenseKeyInstancesService) List(ctx context.Context) (*LicenseKeyInstancesApiResponse, *Response, error) {
response, err := service.client.do(ctx, http.MethodGet, "/v1/license-key-instances")
if err != nil {
return nil, response, err
}

licenseKeyInstances := new(LicenseKeyInstancesApiResponse)
if err = json.Unmarshal(*response.Body, licenseKeyInstances); err != nil {
return nil, response, err
}

return licenseKeyInstances, response, nil
}
95 changes: 95 additions & 0 deletions license_key_instance_service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package client

import (
"context"
"net/http"
"testing"

"github.com/NdoleStudio/lemonsqueezy-go/internal/helpers"
"github.com/NdoleStudio/lemonsqueezy-go/internal/stubs"
"github.com/stretchr/testify/assert"
)

func TestLicenseKeyInstancesService_Get(t *testing.T) {
// Setup
t.Parallel()

// Arrange
server := helpers.MakeTestServer(http.StatusOK, stubs.LicenseKeyInstanceGetResponse())
client := New(WithBaseURL(server.URL))

// Act
licenseKeyInstance, response, err := client.LicenseKeyInstances.Get(context.Background(), "1")

// Assert
assert.Nil(t, err)

assert.Equal(t, http.StatusOK, response.HTTPResponse.StatusCode)
assert.Equal(t, stubs.LicenseKeyInstanceGetResponse(), *response.Body)
assert.Equal(t, "1", licenseKeyInstance.Data.ID)

// Teardown
server.Close()
}

func TestLicenseKeyInstancesService_GetWithError(t *testing.T) {
// Setup
t.Parallel()

// Arrange
server := helpers.MakeTestServer(http.StatusInternalServerError, nil)
client := New(WithBaseURL(server.URL))

// Act
_, response, err := client.LicenseKeyInstances.Get(context.Background(), "1")

// Assert
assert.NotNil(t, err)

assert.Equal(t, http.StatusInternalServerError, response.HTTPResponse.StatusCode)

// Teardown
server.Close()
}

func TestLicenseKeyInstancesService_List(t *testing.T) {
// Setup
t.Parallel()

// Arrange
server := helpers.MakeTestServer(http.StatusOK, stubs.LicenseKeyInstancesListResponse())
client := New(WithBaseURL(server.URL))

// Act
licenseKeyInstances, response, err := client.LicenseKeyInstances.List(context.Background())

// Assert
assert.Nil(t, err)

assert.Equal(t, http.StatusOK, response.HTTPResponse.StatusCode)
assert.Equal(t, stubs.LicenseKeyInstancesListResponse(), *response.Body)
assert.Equal(t, 1, len(licenseKeyInstances.Data))

// Teardown
server.Close()
}

func TestLicenseKeyInstancesService_ListWithError(t *testing.T) {
// Setup
t.Parallel()

// Arrange
server := helpers.MakeTestServer(http.StatusInternalServerError, nil)
client := New(WithBaseURL(server.URL))

// Act
_, response, err := client.LicenseKeyInstances.List(context.Background())

// Assert
assert.NotNil(t, err)

assert.Equal(t, http.StatusInternalServerError, response.HTTPResponse.StatusCode)

// Teardown
server.Close()
}

0 comments on commit 1af38c0

Please sign in to comment.