Skip to content

Commit

Permalink
🌿 Add integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
fern-api[bot] committed Nov 18, 2024
1 parent aba7c86 commit 70a35b0
Show file tree
Hide file tree
Showing 11 changed files with 808 additions and 1 deletion.
9 changes: 8 additions & 1 deletion .fernignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Specify files that shouldn't be modified by Fern

README.md
webhooks/client/verify_signature.go

# Hand-written integration tests.
.github/workflows/integration.yml
integration_tests

# Custom webhook helper methods.
verify_signature.go
webhooks/client/verify_signature.go
webhooks/client/verify_signature_test.go
18 changes: 18 additions & 0 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: ci

on: [push]

jobs:
integration:
env:
TEST_SQUARE_TOKEN: ${{ secrets.TEST_SQUARE_TOKEN }}
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3

- name: Set up go
uses: actions/setup-go@v4

- name: Test
run: go test ./... # TODO: Add the following flag when TEST_SQUARE_TOKEN is configured -- -tags=integration
173 changes: 173 additions & 0 deletions integration_tests/catalog_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
//go:build integration

package integration

import (
"context"
"fmt"
"os"
"testing"

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

"github.com/square/square-go-sdk"
"github.com/square/square-go-sdk/catalog"
"github.com/square/square-go-sdk/core"
)

// Catalog API integration tests.
func TestCatalogAPI(t *testing.T) {
t.Run("bulk create and iterate through paginated catalog objects", func(t *testing.T) {
squareClient := newTestSquareClient(t)

// Setup: Create 100 catalog objects with 1 CatalogItemVariation each.
catalogObjects := make([]*square.CatalogObject, 0, 100)
for i := 0; i < 100; i++ {
catalogObjects = append(catalogObjects, newTestCatalogObject())
}

// Create the catalog objects in a bulk request.
createCatalogObjectsResp, err := squareClient.Catalog.BatchUpsert(
context.Background(),
&square.BatchUpsertCatalogObjectsRequest{
IdempotencyKey: newTestUUID(),
Batches: []*square.CatalogObjectBatch{
{
Objects: catalogObjects,
},
},
},
)
require.NoError(t, err)
assert.Len(t, createCatalogObjectsResp.Objects, 100)

// List all catalog objects.
catalogObjectsResp, err := squareClient.Catalog.List(
context.Background(),
&square.CatalogListRequest{},
)
require.NoError(t, err)
assert.Len(t, catalogObjectsResp.Results, MaxCatalogPageSize)

// Check if there's more than one page of catalog objects to iterate through,
// and that the eventual error returned is `ErrNoPages`, which signals the
// end of the iteration.
numberOfPages := 0
currentPage := catalogObjectsResp
for {
numberOfPages++
currentPage, err = currentPage.GetNextPage(context.Background())
if err != nil {
assert.Equal(t, core.ErrNoPages, err)
break
}
}
assert.Greater(t, numberOfPages, 0)

// Cleanup: Delete the catalog objects we created.
var objectIDs []string
for _, catalogObject := range createCatalogObjectsResp.Objects {
objectIDs = append(objectIDs, catalogObject.Item.ID)
require.GreaterOrEqual(t, len(catalogObject.Item.ItemData.Variations), 1)
objectIDs = append(objectIDs, catalogObject.Item.ItemData.Variations[0].ItemVariation.ID)
}

deleteCatalogObjectsResp, err := squareClient.Catalog.BatchDelete(
context.Background(),
&square.BatchDeleteCatalogObjectsRequest{
ObjectIDs: objectIDs,
},
)
require.NoError(t, err)
assert.Equal(t, 200, len(deleteCatalogObjectsResp.DeletedObjectIDs))
})

t.Run("upload catalog image", func(t *testing.T) {
squareClient := newTestSquareClient(t)

// Setup: Load a test image file.
file, err := os.Open("./testdata/image.jpeg")
require.NoError(t, err)
defer func() {
require.NoError(t, file.Close())
}()

// Setup: Create a catalog object to associate the image with.
catalogObject := newTestCatalogObject()
createCatalogResp, err := squareClient.Catalog.BatchUpsert(
context.Background(),
&square.BatchUpsertCatalogObjectsRequest{
IdempotencyKey: newTestUUID(),
Batches: []*square.CatalogObjectBatch{
{
Objects: []*square.CatalogObject{catalogObject},
},
},
},
)
require.NoError(t, err)
require.GreaterOrEqual(t, len(createCatalogResp.Objects), 1)

createdCatalogObject := createCatalogResp.Objects[0]
require.NotNil(t, createdCatalogObject)

// Create a new catalog image.
imageName := fmt.Sprintf("Test Image %s", newTestUUID())
createCatalogImageResp, err := squareClient.Catalog.Images.Create(
context.Background(),
&catalog.ImagesCreateRequest{
ImageFile: file,
Request: &square.CreateCatalogImageRequest{
IdempotencyKey: newTestUUID(),
ObjectID: &createdCatalogObject.Item.ID,
Image: &square.CatalogObject{
Image: &square.CatalogObjectImage{
ID: newTestSquareTempID(),
ImageData: &square.CatalogImage{
Name: &imageName,
},
},
},
},
},
)
require.NoError(t, err)
assert.NotNil(t, createCatalogImageResp.Image)

// Cleanup: Delete the created catalog object and image.
_, err = squareClient.Catalog.BatchDelete(
context.Background(),
&square.BatchDeleteCatalogObjectsRequest{
ObjectIDs: []string{
createdCatalogObject.Item.ID,
createCatalogImageResp.Image.Image.ID,
},
},
)
require.NoError(t, err)
})
}

// Creates a CatalogObject with a single variation.
func newTestCatalogObject() *square.CatalogObject {
return &square.CatalogObject{
Item: &square.CatalogObjectItem{
ID: newTestSquareTempID(),
ItemData: &square.CatalogItem{
Name: square.String(fmt.Sprintf("Item %s", newTestUUID())),
Variations: []*square.CatalogObject{
{
ItemVariation: &square.CatalogObjectItemVariation{
ID: newTestSquareTempID(),
ItemVariationData: &square.CatalogItemVariation{
Name: square.String(fmt.Sprintf("Variation %s", newTestUUID())),
PriceMoney: newTestMoney(1000),
},
},
},
},
},
},
}
}
56 changes: 56 additions & 0 deletions integration_tests/client_utils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//go:build integration

package integration

import (
"fmt"
"os"
"testing"

"github.com/google/uuid"
"github.com/stretchr/testify/require"

square "github.com/square/square-go-sdk"
client "github.com/square/square-go-sdk/client"
option "github.com/square/square-go-sdk/option"
)

// LocationID represents the test location ID for the sandbox environment.
const LocationID string = "LSBBNEKMKQ72P"

// SourceID represents the payment source ID for the sandbox environment.
const SourceID string = "cnon:card-nonce-ok"

const MaxCatalogPageSize int = 100

func newTestSquareClient(t *testing.T) *client.Client {
token := os.Getenv("TEST_SQUARE_TOKEN")
require.NotEmpty(t, token, "The TEST_SQUARE_TOKEN environment variable is required to run this test")
return client.NewClient(
option.WithToken(token),
option.WithBaseURL("https://connect.squareupsandbox.com"),
)
}

// Generates a new UUID for use as an idempotency key.
//
// For info on Square idempotency keys, see:
// * https://developer.squareup.com/docs/build-basics/common-api-patterns/idempotency
func newTestUUID() string {
return uuid.New().String()
}

// Creates a Square temporary ID (for use in e.g. creation on CatalogObjects),
// which is simply a string prefixed with '#'.
//
// See: https://developer.squareup.com/docs/catalog-api/what-it-does#reference-other-objects-by-their-ids
func newTestSquareTempID() string {
return fmt.Sprintf("#%d", uuid.New().ID())
}

func newTestMoney(amount int64) *square.Money {
return &square.Money{
Amount: square.Int64(amount),
Currency: square.CurrencyUsd.Ptr(),
}
}
130 changes: 130 additions & 0 deletions integration_tests/orders_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
//go:build integration

package integration

import (
"context"
"fmt"
"testing"

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

"github.com/square/square-go-sdk"
)

// Orders API integration tests.
func TestOrdersAPI(t *testing.T) {
t.Run("create order and attach payment", func(t *testing.T) {
squareClient := newTestSquareClient(t)

testOrder := newTestOrder([]TestOrderItem{
{
Name: "New York Strip Steak",
Quantity: "1",
Price: 1599,
},
})

// 1. Create an order and verify that it's `OPEN`.
createOrderResp, err := squareClient.Orders.Create(
context.Background(),
&square.CreateOrderRequest{
Order: testOrder,
},
)
require.NoError(t, err)
assert.NotNil(t, createOrderResp.Order)
assert.Len(t, createOrderResp.Order.LineItems, 1)
assert.Equal(t, *createOrderResp.Order.State, square.OrderStateOpen)

// Attach a payment to the order (equal to the total amount of the order).
createPaymentResp, err := squareClient.Payments.Create(
context.Background(),
&square.CreatePaymentRequest{
LocationID: square.String(LocationID),
IdempotencyKey: newTestUUID(),
OrderID: createOrderResp.Order.ID,
SourceID: SourceID,
AmountMoney: newTestMoney(1599),
Autocomplete: square.Bool(true),
},
)
require.NoError(t, err)
assert.Equal(t, createPaymentResp.Payment.OrderID, createOrderResp.Order.ID)

// Retrieve the order and verify it's `COMPLETED`.
getOrderResp, err := squareClient.Orders.Get(
context.Background(),
*createOrderResp.Order.ID,
)
require.NoError(t, err)
assert.Equal(t, *getOrderResp.Order.State, square.OrderStateCompleted)
})

t.Run("create and use a custom attribute for an order", func(t *testing.T) {
squareClient := newTestSquareClient(t)

// Setup: Create an order with the custom attribute.
testOrder := newTestOrder([]TestOrderItem{
{
Name: "New York Strip Steak",
Quantity: "1",
Price: 1599,
},
})
createOrderResp, err := squareClient.Orders.Create(
context.Background(),
&square.CreateOrderRequest{
Order: testOrder,
},
)
require.NoError(t, err)

// 1. Create a custom attribute definition for an email address schema.
emailSchemaUri := "https://developer-production-s.squarecdn.com/schemas/v1/common.json#squareup.common.Email"
attrKey := fmt.Sprintf("custom-attr-%s", newTestUUID())
customAttrDefinition := &square.CustomAttributeDefinition{
Key: square.String(attrKey),
Name: square.String("My Custom Attribute"),
Schema: map[string]interface{}{
"$ref": square.String(emailSchemaUri),
},
}
createAttrResp, err := squareClient.OrderCustomAttributes.CreateOrderCustomAttributeDefinition(
context.Background(),
&square.CreateOrderCustomAttributeDefinitionRequest{
CustomAttributeDefinition: customAttrDefinition,
},
)
require.NoError(t, err)
assert.NotNil(t, createAttrResp.CustomAttributeDefinition)

// 2. For the given order, upsert a valid value for the custom attribute.
upsertOrderResp, err := squareClient.OrderCustomAttributes.UpsertOrderCustomAttribute(
context.Background(),
*createOrderResp.Order.ID,
attrKey,
&square.UpsertOrderCustomAttributeRequest{
CustomAttribute: &square.CustomAttribute{
Value: square.String("[email protected]"),
},
},
)
require.NoError(t, err)
assert.NotNil(t, upsertOrderResp.CustomAttribute)

// 3. For the given order, upsert an invalid value for the custom attribute.
_, err = squareClient.OrderCustomAttributes.UpsertOrderCustomAttribute(
context.Background(),
*createOrderResp.Order.ID,
attrKey,
&square.UpsertOrderCustomAttributeRequest{
CustomAttribute: &square.CustomAttribute{
Value: square.String("invalid-email"),
},
},
)
require.Error(t, err)
})
}
Loading

0 comments on commit 70a35b0

Please sign in to comment.