Merge pull request #8 from StevanFreeborn/stevanfreeborn/tests/add-integration-tests
tests: add integration tests
This commit is contained in:
@@ -11,3 +11,4 @@ go.work.sum
|
||||
*.html
|
||||
cover.out
|
||||
coverage.txt
|
||||
.env
|
||||
@@ -0,0 +1,211 @@
|
||||
//go:build integration
|
||||
|
||||
package onspring_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/StevanFreeborn/onspring-api-sdk-go"
|
||||
)
|
||||
|
||||
func TestAppsIntegration(t *testing.T) {
|
||||
loadEnvFile(t)
|
||||
client := createClient(t)
|
||||
ctx := context.Background()
|
||||
|
||||
t.Run("Get", func(t *testing.T) {
|
||||
t.Run("should return an app", func(t *testing.T) {
|
||||
appId := requireEnvInt(t, "TEST_APP_ID")
|
||||
|
||||
app, err := client.Apps.Get(ctx, appId)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if app.Id != appId {
|
||||
t.Errorf("Expected app id %d, got %d", appId, app.Id)
|
||||
}
|
||||
|
||||
if app.Name == "" {
|
||||
t.Error("Expected app name to not be empty")
|
||||
}
|
||||
|
||||
if app.Href == "" {
|
||||
t.Error("Expected app href to not be empty")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a 401 error when an invalid api key is used", func(t *testing.T) {
|
||||
invalidClient := createInvalidClient(t)
|
||||
appId := requireEnvInt(t, "TEST_APP_ID")
|
||||
|
||||
_, err := invalidClient.Apps.Get(ctx, appId)
|
||||
|
||||
assertAPIError(t, err, http.StatusUnauthorized)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 error when api key does not have access to the app", func(t *testing.T) {
|
||||
appIdNoAccess := requireEnvInt(t, "TEST_APP_ID_NO_ACCESS")
|
||||
|
||||
_, err := client.Apps.Get(ctx, appIdNoAccess)
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
|
||||
t.Run("should return a 404 error when an app id cannot be found", func(t *testing.T) {
|
||||
_, err := client.Apps.Get(ctx, 0)
|
||||
|
||||
assertAPIError(t, err, http.StatusNotFound)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("List", func(t *testing.T) {
|
||||
t.Run("should return a paged list of apps", func(t *testing.T) {
|
||||
page, err := client.Apps.List(ctx)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if page.PageNumber == 0 {
|
||||
t.Error("Expected page number to not be zero")
|
||||
}
|
||||
|
||||
if page.PageSize == 0 {
|
||||
t.Error("Expected page size to not be zero")
|
||||
}
|
||||
|
||||
if page.TotalPages == 0 {
|
||||
t.Error("Expected total pages to not be zero")
|
||||
}
|
||||
|
||||
if page.TotalRecords == 0 {
|
||||
t.Error("Expected total records to not be zero")
|
||||
}
|
||||
|
||||
if len(page.Items) == 0 {
|
||||
t.Error("Expected items to not be empty")
|
||||
}
|
||||
|
||||
for _, app := range page.Items {
|
||||
if app.Id == 0 {
|
||||
t.Error("Expected app id to not be zero")
|
||||
}
|
||||
|
||||
if app.Name == "" {
|
||||
t.Error("Expected app name to not be empty")
|
||||
}
|
||||
|
||||
if app.Href == "" {
|
||||
t.Error("Expected app href to not be empty")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a paged list of apps with correct page size and number when passed paging request", func(t *testing.T) {
|
||||
page, err := client.Apps.List(ctx, onspring.ForPageNumber(1), onspring.WithPageSize(1))
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if page.PageNumber != 1 {
|
||||
t.Errorf("Expected page number 1, got %d", page.PageNumber)
|
||||
}
|
||||
|
||||
if page.PageSize != 1 {
|
||||
t.Errorf("Expected page size 1, got %d", page.PageSize)
|
||||
}
|
||||
|
||||
if len(page.Items) != 1 {
|
||||
t.Errorf("Expected 1 item, got %d", len(page.Items))
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a 400 response when an invalid page size is used", func(t *testing.T) {
|
||||
_, err := client.Apps.List(ctx, onspring.WithPageSize(1001))
|
||||
|
||||
assertAPIError(t, err, http.StatusBadRequest)
|
||||
})
|
||||
|
||||
t.Run("should return a 401 response when an invalid api key is used", func(t *testing.T) {
|
||||
invalidClient := createInvalidClient(t)
|
||||
|
||||
_, err := invalidClient.Apps.List(ctx)
|
||||
|
||||
assertAPIError(t, err, http.StatusUnauthorized)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("ListAll", func(t *testing.T) {
|
||||
t.Run("should iterate all apps", func(t *testing.T) {
|
||||
var apps []onspring.App
|
||||
|
||||
for app, err := range client.Apps.ListAll(ctx, onspring.WithPageSize(1)) {
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
apps = append(apps, app)
|
||||
}
|
||||
|
||||
if len(apps) == 0 {
|
||||
t.Error("Expected to iterate at least one app")
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("GetMany", func(t *testing.T) {
|
||||
t.Run("should return a collection of apps", func(t *testing.T) {
|
||||
appIds := requireEnvIntSlice(t, "TEST_APP_IDS")
|
||||
|
||||
batch, err := client.Apps.GetMany(ctx, appIds)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if batch.Count != len(appIds) {
|
||||
t.Errorf("Expected count %d, got %d", len(appIds), batch.Count)
|
||||
}
|
||||
|
||||
if len(batch.Items) != len(appIds) {
|
||||
t.Errorf("Expected %d items, got %d", len(appIds), len(batch.Items))
|
||||
}
|
||||
|
||||
for _, app := range batch.Items {
|
||||
if app.Id == 0 {
|
||||
t.Error("Expected app id to not be zero")
|
||||
}
|
||||
|
||||
if app.Name == "" {
|
||||
t.Error("Expected app name to not be empty")
|
||||
}
|
||||
|
||||
if app.Href == "" {
|
||||
t.Error("Expected app href to not be empty")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a 401 error when an invalid api key is used", func(t *testing.T) {
|
||||
invalidClient := createInvalidClient(t)
|
||||
appIds := requireEnvIntSlice(t, "TEST_APP_IDS")
|
||||
|
||||
_, err := invalidClient.Apps.GetMany(ctx, appIds)
|
||||
|
||||
assertAPIError(t, err, http.StatusUnauthorized)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 error when api key does not have access to the apps", func(t *testing.T) {
|
||||
appIdsNoAccess := requireEnvIntSlice(t, "TEST_APP_IDS_NO_ACCESS")
|
||||
|
||||
_, err := client.Apps.GetMany(ctx, appIdsNoAccess)
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -21,7 +21,7 @@ const (
|
||||
// defaultTimeout is the default HTTP client timeout duration.
|
||||
defaultTimeout = 120 * time.Second
|
||||
// defaultAPIKeyHeader is the HTTP header name used for API key authentication.
|
||||
defaultAPIKeyHeader = "x-api-key"
|
||||
defaultAPIKeyHeader = "x-apikey"
|
||||
// defaultAPIVersionHeader is the HTTP header name used to specify the API version.
|
||||
defaultAPIVersionHeader = "x-api-version"
|
||||
// defaultAPIVersion is the default Onspring API version to use.
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
API_BASE_URL=https://api.onspring.com
|
||||
SANDBOX_API_KEY=your-sandbox-api-key
|
||||
|
||||
TEST_APP_ID=1
|
||||
TEST_APP_ID_NO_ACCESS=2
|
||||
TEST_APP_IDS=1,2,3
|
||||
TEST_APP_IDS_NO_ACCESS=4,5,6
|
||||
|
||||
TEST_SURVEY_ID=1
|
||||
TEST_SURVEY_RECORD_ID=1
|
||||
TEST_SURVEY_AUTO_NUMBER_FIELD=1
|
||||
|
||||
TEST_FIELD_ID=1
|
||||
TEST_FIELD_ID_NO_ACCESS=2
|
||||
TEST_FIELD_IDS=1,2,3
|
||||
TEST_FIELD_IDS_NO_ACCESS=4,5,6
|
||||
TEST_TEXT_FIELD=1
|
||||
|
||||
TEST_RECORD=1
|
||||
TEST_ATTACHMENT_FIELD=1
|
||||
TEST_ATTACHMENT_FIELD_NO_ACCESS_FIELD=2
|
||||
TEST_ATTACHMENT_FIELD_NO_ACCESS_APP=3
|
||||
TEST_ATTACHMENT=1
|
||||
TEST_IMAGE_FIELD=1
|
||||
TEST_IMAGE=1
|
||||
|
||||
TEST_LIST_FIELD=1
|
||||
TEST_LIST_FIELD_NO_ACCESS=2
|
||||
TEST_LIST_ID=1
|
||||
TEST_LIST_ID_NO_ACCESS=2
|
||||
TEST_LIST_ITEM_ID_NO_ACCESS=some-guid
|
||||
|
||||
TEST_REPORT=1
|
||||
TEST_REPORT_NO_ACCESS=2
|
||||
TEST_REPORT_WITH_CHART_DATA=3
|
||||
@@ -31,8 +31,8 @@ type Field struct {
|
||||
|
||||
// FormulaField represents a formula field type in Onspring
|
||||
type FormulaField struct {
|
||||
OutputType string `json:"outputType"`
|
||||
Values []string `json:"values"`
|
||||
OutputType string `json:"outputType"`
|
||||
Values []ListValue `json:"values"`
|
||||
}
|
||||
|
||||
// ReferenceField represents a reference field type in Onspring
|
||||
@@ -41,11 +41,20 @@ type ReferenceField struct {
|
||||
ReferenceAppId string `json:"referenceAppId"`
|
||||
}
|
||||
|
||||
// ListValue represents a value option within a list field in Onspring.
|
||||
type ListValue struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
SortOrder int `json:"sortOrder"`
|
||||
NumericValue float64 `json:"numericValue"`
|
||||
Color string `json:"color"`
|
||||
}
|
||||
|
||||
// ListField represents a list field type in Onspring
|
||||
type ListField struct {
|
||||
Multiplicity string `json:"multiplicity"`
|
||||
Values []string `json:"values"`
|
||||
ListId int `json:"listId"`
|
||||
Multiplicity string `json:"multiplicity"`
|
||||
Values []ListValue `json:"values"`
|
||||
ListId int `json:"listId"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface for Field.
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
//go:build integration
|
||||
|
||||
package onspring_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/StevanFreeborn/onspring-api-sdk-go"
|
||||
)
|
||||
|
||||
func TestFieldsIntegration(t *testing.T) {
|
||||
loadEnvFile(t)
|
||||
client := createClient(t)
|
||||
ctx := context.Background()
|
||||
|
||||
t.Run("Get", func(t *testing.T) {
|
||||
t.Run("should return a field", func(t *testing.T) {
|
||||
fieldId := requireEnvInt(t, "TEST_FIELD_ID")
|
||||
|
||||
field, err := client.Fields.Get(ctx, fieldId)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if field.Id != fieldId {
|
||||
t.Errorf("Expected field id %d, got %d", fieldId, field.Id)
|
||||
}
|
||||
|
||||
if field.Name == "" {
|
||||
t.Error("Expected field name to not be empty")
|
||||
}
|
||||
|
||||
if field.AppId == 0 {
|
||||
t.Error("Expected field appId to not be zero")
|
||||
}
|
||||
|
||||
if field.Type == "" {
|
||||
t.Error("Expected field type to not be empty")
|
||||
}
|
||||
|
||||
if field.Status == "" {
|
||||
t.Error("Expected field status to not be empty")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a 401 error when an invalid api key is used", func(t *testing.T) {
|
||||
invalidClient := createInvalidClient(t)
|
||||
fieldId := requireEnvInt(t, "TEST_FIELD_ID")
|
||||
|
||||
_, err := invalidClient.Fields.Get(ctx, fieldId)
|
||||
|
||||
assertAPIError(t, err, http.StatusUnauthorized)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 error when api key does not have access to the field", func(t *testing.T) {
|
||||
fieldIdNoAccess := requireEnvInt(t, "TEST_FIELD_ID_NO_ACCESS")
|
||||
|
||||
_, err := client.Fields.Get(ctx, fieldIdNoAccess)
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
|
||||
t.Run("should return a 404 error when the field does not exist", func(t *testing.T) {
|
||||
_, err := client.Fields.Get(ctx, 0)
|
||||
|
||||
assertAPIError(t, err, http.StatusNotFound)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("List", func(t *testing.T) {
|
||||
t.Run("should return a paged list of fields", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
|
||||
page, err := client.Fields.List(ctx, surveyId)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if page.PageNumber == 0 {
|
||||
t.Error("Expected page number to not be zero")
|
||||
}
|
||||
|
||||
if page.TotalRecords == 0 {
|
||||
t.Error("Expected total records to not be zero")
|
||||
}
|
||||
|
||||
if len(page.Items) == 0 {
|
||||
t.Error("Expected items to not be empty")
|
||||
}
|
||||
|
||||
for _, field := range page.Items {
|
||||
if field.Id == 0 {
|
||||
t.Error("Expected field id to not be zero")
|
||||
}
|
||||
|
||||
if field.Name == "" {
|
||||
t.Error("Expected field name to not be empty")
|
||||
}
|
||||
|
||||
if field.AppId == 0 {
|
||||
t.Error("Expected field appId to not be zero")
|
||||
}
|
||||
|
||||
if field.Type == "" {
|
||||
t.Error("Expected field type to not be empty")
|
||||
}
|
||||
|
||||
if field.Status == "" {
|
||||
t.Error("Expected field status to not be empty")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a paged list of fields with correct page size and number when passed paging request", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
|
||||
page, err := client.Fields.List(ctx, surveyId, onspring.ForPageNumber(1), onspring.WithPageSize(1))
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if page.PageNumber != 1 {
|
||||
t.Errorf("Expected page number 1, got %d", page.PageNumber)
|
||||
}
|
||||
|
||||
if page.PageSize != 1 {
|
||||
t.Errorf("Expected page size 1, got %d", page.PageSize)
|
||||
}
|
||||
|
||||
if len(page.Items) != 1 {
|
||||
t.Errorf("Expected 1 item, got %d", len(page.Items))
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a 400 response when an invalid page size is used", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
|
||||
_, err := client.Fields.List(ctx, surveyId, onspring.WithPageSize(1001))
|
||||
|
||||
assertAPIError(t, err, http.StatusBadRequest)
|
||||
})
|
||||
|
||||
t.Run("should return a 401 response when an invalid api key is used", func(t *testing.T) {
|
||||
invalidClient := createInvalidClient(t)
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
|
||||
_, err := invalidClient.Fields.List(ctx, surveyId)
|
||||
|
||||
assertAPIError(t, err, http.StatusUnauthorized)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 response when api key does not have access to the app", func(t *testing.T) {
|
||||
appIdNoAccess := requireEnvInt(t, "TEST_APP_ID_NO_ACCESS")
|
||||
|
||||
_, err := client.Fields.List(ctx, appIdNoAccess)
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("ListAll", func(t *testing.T) {
|
||||
t.Run("should iterate all fields for an app", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
|
||||
var fields []onspring.Field
|
||||
|
||||
for field, err := range client.Fields.ListAll(ctx, surveyId, onspring.WithPageSize(1)) {
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
fields = append(fields, field)
|
||||
}
|
||||
|
||||
if len(fields) == 0 {
|
||||
t.Error("Expected to iterate at least one field")
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("GetMany", func(t *testing.T) {
|
||||
t.Run("should return a collection of fields", func(t *testing.T) {
|
||||
fieldIds := requireEnvIntSlice(t, "TEST_FIELD_IDS")
|
||||
|
||||
batch, err := client.Fields.GetMany(ctx, fieldIds)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if batch.Count != len(fieldIds) {
|
||||
t.Errorf("Expected count %d, got %d", len(fieldIds), batch.Count)
|
||||
}
|
||||
|
||||
if len(batch.Items) != len(fieldIds) {
|
||||
t.Errorf("Expected %d items, got %d", len(fieldIds), len(batch.Items))
|
||||
}
|
||||
|
||||
for _, field := range batch.Items {
|
||||
if field.Id == 0 {
|
||||
t.Error("Expected field id to not be zero")
|
||||
}
|
||||
|
||||
if field.Name == "" {
|
||||
t.Error("Expected field name to not be empty")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a 401 response when an invalid api key is used", func(t *testing.T) {
|
||||
invalidClient := createInvalidClient(t)
|
||||
fieldIds := requireEnvIntSlice(t, "TEST_FIELD_IDS")
|
||||
|
||||
_, err := invalidClient.Fields.GetMany(ctx, fieldIds)
|
||||
|
||||
assertAPIError(t, err, http.StatusUnauthorized)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 response when the api key does not have access to any of the requested fields", func(t *testing.T) {
|
||||
fieldIdsNoAccess := requireEnvIntSlice(t, "TEST_FIELD_IDS_NO_ACCESS")
|
||||
|
||||
_, err := client.Fields.GetMany(ctx, fieldIdsNoAccess)
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
})
|
||||
}
|
||||
+17
-5
@@ -138,7 +138,10 @@ func TestFields(t *testing.T) {
|
||||
"isRequired": true,
|
||||
"isUnique": false,
|
||||
"outputType": "Number",
|
||||
"values": ["1", "2", "3"]
|
||||
"values": [
|
||||
{"id": "a1", "name": "Value1", "sortOrder": 1, "numericValue": 1, "color": "#fff"},
|
||||
{"id": "b2", "name": "Value2", "sortOrder": 2, "numericValue": 2, "color": "#000"}
|
||||
]
|
||||
}`
|
||||
|
||||
var field onspring.Field
|
||||
@@ -161,7 +164,10 @@ func TestFields(t *testing.T) {
|
||||
|
||||
expectedFormulaField := onspring.FormulaField{
|
||||
OutputType: "Number",
|
||||
Values: []string{"1", "2", "3"},
|
||||
Values: []onspring.ListValue{
|
||||
{Id: "a1", Name: "Value1", SortOrder: 1, NumericValue: 1, Color: "#fff"},
|
||||
{Id: "b2", Name: "Value2", SortOrder: 2, NumericValue: 2, Color: "#000"},
|
||||
},
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(formulaField, expectedFormulaField) {
|
||||
@@ -220,7 +226,10 @@ func TestFields(t *testing.T) {
|
||||
"isRequired": false,
|
||||
"isUnique": false,
|
||||
"multiplicity": "MultiSelect",
|
||||
"values": ["OptionA", "OptionB"],
|
||||
"values": [
|
||||
{"id": "aaa", "name": "OptionA", "sortOrder": 1, "numericValue": 0, "color": "#ffffff"},
|
||||
{"id": "bbb", "name": "OptionB", "sortOrder": 2, "numericValue": 0, "color": "#000000"}
|
||||
],
|
||||
"listId": 456
|
||||
}`
|
||||
|
||||
@@ -244,8 +253,11 @@ func TestFields(t *testing.T) {
|
||||
|
||||
expectedListField := onspring.ListField{
|
||||
Multiplicity: "MultiSelect",
|
||||
Values: []string{"OptionA", "OptionB"},
|
||||
ListId: 456,
|
||||
Values: []onspring.ListValue{
|
||||
{Id: "aaa", Name: "OptionA", SortOrder: 1, NumericValue: 0, Color: "#ffffff"},
|
||||
{Id: "bbb", Name: "OptionB", SortOrder: 2, NumericValue: 0, Color: "#000000"},
|
||||
},
|
||||
ListId: 456,
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(listField, expectedListField) {
|
||||
|
||||
@@ -0,0 +1,590 @@
|
||||
//go:build integration
|
||||
|
||||
package onspring_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/StevanFreeborn/onspring-api-sdk-go"
|
||||
)
|
||||
|
||||
func TestFilesIntegration(t *testing.T) {
|
||||
loadEnvFile(t)
|
||||
client := createClient(t)
|
||||
ctx := context.Background()
|
||||
|
||||
t.Run("GetInfo", func(t *testing.T) {
|
||||
t.Run("should return information about a file in an attachment field", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fieldId := requireEnvInt(t, "TEST_ATTACHMENT_FIELD")
|
||||
fileId := requireEnvInt(t, "TEST_ATTACHMENT")
|
||||
|
||||
info, err := client.Files.GetInfo(ctx, recordId, fieldId, fileId)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if info.Name == "" {
|
||||
t.Error("Expected name to not be empty")
|
||||
}
|
||||
|
||||
if info.ContentType == "" {
|
||||
t.Error("Expected content type to not be empty")
|
||||
}
|
||||
|
||||
if info.CreatedDate == "" {
|
||||
t.Error("Expected created date to not be empty")
|
||||
}
|
||||
|
||||
if info.ModifiedDate == "" {
|
||||
t.Error("Expected modified date to not be empty")
|
||||
}
|
||||
|
||||
if info.Owner == "" {
|
||||
t.Error("Expected owner to not be empty")
|
||||
}
|
||||
|
||||
if info.Type == "" {
|
||||
t.Error("Expected type to not be empty")
|
||||
}
|
||||
|
||||
if info.FileHref == "" {
|
||||
t.Error("Expected file href to not be empty")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return information about a file in an image field", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fieldId := requireEnvInt(t, "TEST_IMAGE_FIELD")
|
||||
fileId := requireEnvInt(t, "TEST_IMAGE")
|
||||
|
||||
info, err := client.Files.GetInfo(ctx, recordId, fieldId, fileId)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if info.Name == "" {
|
||||
t.Error("Expected name to not be empty")
|
||||
}
|
||||
|
||||
if info.ContentType == "" {
|
||||
t.Error("Expected content type to not be empty")
|
||||
}
|
||||
|
||||
if info.Type == "" {
|
||||
t.Error("Expected type to not be empty")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a 400 response when fieldId is not for a file field", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
textFieldId := requireEnvInt(t, "TEST_TEXT_FIELD")
|
||||
fileId := requireEnvInt(t, "TEST_ATTACHMENT")
|
||||
|
||||
_, err := client.Files.GetInfo(ctx, recordId, textFieldId, fileId)
|
||||
|
||||
assertAPIError(t, err, http.StatusBadRequest)
|
||||
})
|
||||
|
||||
t.Run("should return a 401 response when the api key is invalid", func(t *testing.T) {
|
||||
invalidClient := createInvalidClient(t)
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fieldId := requireEnvInt(t, "TEST_ATTACHMENT_FIELD")
|
||||
fileId := requireEnvInt(t, "TEST_ATTACHMENT")
|
||||
|
||||
_, err := invalidClient.Files.GetInfo(ctx, recordId, fieldId, fileId)
|
||||
|
||||
assertAPIError(t, err, http.StatusUnauthorized)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 response when the api key does not have access to the file field", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fieldIdNoAccess := requireEnvInt(t, "TEST_ATTACHMENT_FIELD_NO_ACCESS_FIELD")
|
||||
fileId := requireEnvInt(t, "TEST_ATTACHMENT")
|
||||
|
||||
_, err := client.Files.GetInfo(ctx, recordId, fieldIdNoAccess, fileId)
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 response when the api key does not have access to the app", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fieldIdNoApp := requireEnvInt(t, "TEST_ATTACHMENT_FIELD_NO_ACCESS_APP")
|
||||
fileId := requireEnvInt(t, "TEST_ATTACHMENT")
|
||||
|
||||
_, err := client.Files.GetInfo(ctx, recordId, fieldIdNoApp, fileId)
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
|
||||
t.Run("should return a 404 response when the file field cannot be found", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fileId := requireEnvInt(t, "TEST_ATTACHMENT")
|
||||
|
||||
_, err := client.Files.GetInfo(ctx, recordId, 0, fileId)
|
||||
|
||||
assertAPIError(t, err, http.StatusNotFound)
|
||||
})
|
||||
|
||||
t.Run("should return a 404 response when the file record cannot be found", func(t *testing.T) {
|
||||
fieldId := requireEnvInt(t, "TEST_ATTACHMENT_FIELD")
|
||||
fileId := requireEnvInt(t, "TEST_ATTACHMENT")
|
||||
|
||||
_, err := client.Files.GetInfo(ctx, 0, fieldId, fileId)
|
||||
|
||||
assertAPIError(t, err, http.StatusNotFound)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("GetContent", func(t *testing.T) {
|
||||
t.Run("should return a file in an attachment field", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fieldId := requireEnvInt(t, "TEST_ATTACHMENT_FIELD")
|
||||
fileId := requireEnvInt(t, "TEST_ATTACHMENT")
|
||||
|
||||
content, err := client.Files.GetContent(ctx, recordId, fieldId, fileId)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if len(content.Data) == 0 {
|
||||
t.Error("Expected data to not be empty")
|
||||
}
|
||||
|
||||
if content.ContentType == "" {
|
||||
t.Error("Expected content type to not be empty")
|
||||
}
|
||||
|
||||
if content.FileName == "" {
|
||||
t.Error("Expected file name to not be empty")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a file in an image field", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fieldId := requireEnvInt(t, "TEST_IMAGE_FIELD")
|
||||
fileId := requireEnvInt(t, "TEST_IMAGE")
|
||||
|
||||
content, err := client.Files.GetContent(ctx, recordId, fieldId, fileId)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if len(content.Data) == 0 {
|
||||
t.Error("Expected data to not be empty")
|
||||
}
|
||||
|
||||
if content.ContentType == "" {
|
||||
t.Error("Expected content type to not be empty")
|
||||
}
|
||||
|
||||
if content.FileName == "" {
|
||||
t.Error("Expected file name to not be empty")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a 400 response when fieldId is not for a file field", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
textFieldId := requireEnvInt(t, "TEST_TEXT_FIELD")
|
||||
fileId := requireEnvInt(t, "TEST_ATTACHMENT")
|
||||
|
||||
_, err := client.Files.GetContent(ctx, recordId, textFieldId, fileId)
|
||||
|
||||
assertAPIError(t, err, http.StatusBadRequest)
|
||||
})
|
||||
|
||||
t.Run("should return a 401 response when the api key is invalid", func(t *testing.T) {
|
||||
invalidClient := createInvalidClient(t)
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fieldId := requireEnvInt(t, "TEST_ATTACHMENT_FIELD")
|
||||
fileId := requireEnvInt(t, "TEST_ATTACHMENT")
|
||||
|
||||
_, err := invalidClient.Files.GetContent(ctx, recordId, fieldId, fileId)
|
||||
|
||||
assertAPIError(t, err, http.StatusUnauthorized)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 response when the api key does not have access to the file field", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fieldIdNoAccess := requireEnvInt(t, "TEST_ATTACHMENT_FIELD_NO_ACCESS_FIELD")
|
||||
fileId := requireEnvInt(t, "TEST_ATTACHMENT")
|
||||
|
||||
_, err := client.Files.GetContent(ctx, recordId, fieldIdNoAccess, fileId)
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 response when the api key does not have access to the app", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fieldIdNoApp := requireEnvInt(t, "TEST_ATTACHMENT_FIELD_NO_ACCESS_APP")
|
||||
fileId := requireEnvInt(t, "TEST_ATTACHMENT")
|
||||
|
||||
_, err := client.Files.GetContent(ctx, recordId, fieldIdNoApp, fileId)
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
|
||||
t.Run("should return a 404 response when the file field cannot be found", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fileId := requireEnvInt(t, "TEST_ATTACHMENT")
|
||||
|
||||
_, err := client.Files.GetContent(ctx, recordId, 0, fileId)
|
||||
|
||||
assertAPIError(t, err, http.StatusNotFound)
|
||||
})
|
||||
|
||||
t.Run("should return a 404 response when the file record cannot be found", func(t *testing.T) {
|
||||
fieldId := requireEnvInt(t, "TEST_ATTACHMENT_FIELD")
|
||||
fileId := requireEnvInt(t, "TEST_ATTACHMENT")
|
||||
|
||||
_, err := client.Files.GetContent(ctx, 0, fieldId, fileId)
|
||||
|
||||
assertAPIError(t, err, http.StatusNotFound)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Save", func(t *testing.T) {
|
||||
t.Run("should save a file into an attachment field", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fieldId := requireEnvInt(t, "TEST_ATTACHMENT_FIELD")
|
||||
|
||||
file, err := os.Open("testdata/test-attachment.txt")
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to open test attachment: %v", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
_ = file.Close()
|
||||
}()
|
||||
|
||||
response, err := client.Files.Save(ctx, onspring.SaveFileRequest{
|
||||
RecordId: recordId,
|
||||
FieldId: fieldId,
|
||||
FileName: "test-attachment.txt",
|
||||
FileContents: file,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if response.Id == 0 {
|
||||
t.Error("Expected file id to not be zero")
|
||||
}
|
||||
|
||||
t.Cleanup(func() {
|
||||
_ = client.Files.Delete(context.Background(), recordId, fieldId, response.Id)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("should save a file into an image field", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fieldId := requireEnvInt(t, "TEST_IMAGE_FIELD")
|
||||
|
||||
file, err := os.Open("testdata/test-image.jpeg")
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to open test image: %v", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
_ = file.Close()
|
||||
}()
|
||||
|
||||
response, err := client.Files.Save(ctx, onspring.SaveFileRequest{
|
||||
RecordId: recordId,
|
||||
FieldId: fieldId,
|
||||
FileName: "test-image.jpeg",
|
||||
FileContents: file,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if response.Id == 0 {
|
||||
t.Error("Expected file id to not be zero")
|
||||
}
|
||||
|
||||
t.Cleanup(func() {
|
||||
_ = client.Files.Delete(context.Background(), recordId, fieldId, response.Id)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("should return a 400 response when fieldId is not for a file field", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
textFieldId := requireEnvInt(t, "TEST_TEXT_FIELD")
|
||||
|
||||
file, err := os.Open("testdata/test-attachment.txt")
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to open test attachment: %v", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
_ = file.Close()
|
||||
}()
|
||||
|
||||
_, err = client.Files.Save(ctx, onspring.SaveFileRequest{
|
||||
RecordId: recordId,
|
||||
FieldId: textFieldId,
|
||||
FileName: "test-attachment.txt",
|
||||
FileContents: file,
|
||||
})
|
||||
|
||||
assertAPIError(t, err, http.StatusBadRequest)
|
||||
})
|
||||
|
||||
t.Run("should return a 401 response when the api key is invalid", func(t *testing.T) {
|
||||
invalidClient := createInvalidClient(t)
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fieldId := requireEnvInt(t, "TEST_ATTACHMENT_FIELD")
|
||||
|
||||
file, err := os.Open("testdata/test-attachment.txt")
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to open test attachment: %v", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
_ = file.Close()
|
||||
}()
|
||||
|
||||
_, err = invalidClient.Files.Save(ctx, onspring.SaveFileRequest{
|
||||
RecordId: recordId,
|
||||
FieldId: fieldId,
|
||||
FileName: "test-attachment.txt",
|
||||
FileContents: file,
|
||||
})
|
||||
|
||||
assertAPIError(t, err, http.StatusUnauthorized)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 response when the api key does not have access to the field", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fieldIdNoAccess := requireEnvInt(t, "TEST_ATTACHMENT_FIELD_NO_ACCESS_FIELD")
|
||||
|
||||
file, err := os.Open("testdata/test-attachment.txt")
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to open test attachment: %v", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
_ = file.Close()
|
||||
}()
|
||||
|
||||
_, err = client.Files.Save(ctx, onspring.SaveFileRequest{
|
||||
RecordId: recordId,
|
||||
FieldId: fieldIdNoAccess,
|
||||
FileName: "test-attachment.txt",
|
||||
FileContents: file,
|
||||
})
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 response when the api key does not have access to the app", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fieldIdNoApp := requireEnvInt(t, "TEST_ATTACHMENT_FIELD_NO_ACCESS_APP")
|
||||
|
||||
file, err := os.Open("testdata/test-attachment.txt")
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to open test attachment: %v", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
_ = file.Close()
|
||||
}()
|
||||
|
||||
_, err = client.Files.Save(ctx, onspring.SaveFileRequest{
|
||||
RecordId: recordId,
|
||||
FieldId: fieldIdNoApp,
|
||||
FileName: "test-attachment.txt",
|
||||
FileContents: file,
|
||||
})
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
|
||||
t.Run("should return a 404 response when the file field cannot be found", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
|
||||
file, err := os.Open("testdata/test-attachment.txt")
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to open test attachment: %v", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
_ = file.Close()
|
||||
}()
|
||||
|
||||
_, err = client.Files.Save(ctx, onspring.SaveFileRequest{
|
||||
RecordId: recordId,
|
||||
FieldId: 0,
|
||||
FileName: "test-attachment.txt",
|
||||
FileContents: file,
|
||||
})
|
||||
|
||||
assertAPIError(t, err, http.StatusNotFound)
|
||||
})
|
||||
|
||||
t.Run("should return a 404 response when the file record cannot be found", func(t *testing.T) {
|
||||
fieldId := requireEnvInt(t, "TEST_ATTACHMENT_FIELD")
|
||||
|
||||
file, err := os.Open("testdata/test-attachment.txt")
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to open test attachment: %v", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
_ = file.Close()
|
||||
}()
|
||||
|
||||
_, err = client.Files.Save(ctx, onspring.SaveFileRequest{
|
||||
RecordId: 0,
|
||||
FieldId: fieldId,
|
||||
FileName: "test-attachment.txt",
|
||||
FileContents: file,
|
||||
})
|
||||
|
||||
assertAPIError(t, err, http.StatusNotFound)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Delete", func(t *testing.T) {
|
||||
t.Run("should delete a file from an attachment field", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fieldId := requireEnvInt(t, "TEST_ATTACHMENT_FIELD")
|
||||
|
||||
file, err := os.Open("testdata/test-attachment.txt")
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to open test attachment: %v", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
_ = file.Close()
|
||||
}()
|
||||
|
||||
saveResponse, err := client.Files.Save(ctx, onspring.SaveFileRequest{
|
||||
RecordId: recordId,
|
||||
FieldId: fieldId,
|
||||
FileName: "test-attachment-to-delete.txt",
|
||||
FileContents: file,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to save file: %v", err)
|
||||
}
|
||||
|
||||
err = client.Files.Delete(ctx, recordId, fieldId, saveResponse.Id)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error, got %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should delete a file from an image field", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fieldId := requireEnvInt(t, "TEST_IMAGE_FIELD")
|
||||
|
||||
file, err := os.Open("testdata/test-image.jpeg")
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to open test image: %v", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
_ = file.Close()
|
||||
}()
|
||||
|
||||
saveResponse, err := client.Files.Save(ctx, onspring.SaveFileRequest{
|
||||
RecordId: recordId,
|
||||
FieldId: fieldId,
|
||||
FileName: "test-image-to-delete.jpeg",
|
||||
FileContents: file,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to save file: %v", err)
|
||||
}
|
||||
|
||||
err = client.Files.Delete(ctx, recordId, fieldId, saveResponse.Id)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error, got %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a 400 response when fieldId is not for a file field", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
textFieldId := requireEnvInt(t, "TEST_TEXT_FIELD")
|
||||
fileId := requireEnvInt(t, "TEST_ATTACHMENT")
|
||||
|
||||
err := client.Files.Delete(ctx, recordId, textFieldId, fileId)
|
||||
|
||||
assertAPIError(t, err, http.StatusBadRequest)
|
||||
})
|
||||
|
||||
t.Run("should return a 401 response when the api key is invalid", func(t *testing.T) {
|
||||
invalidClient := createInvalidClient(t)
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fieldId := requireEnvInt(t, "TEST_ATTACHMENT_FIELD")
|
||||
fileId := requireEnvInt(t, "TEST_ATTACHMENT")
|
||||
|
||||
err := invalidClient.Files.Delete(ctx, recordId, fieldId, fileId)
|
||||
|
||||
assertAPIError(t, err, http.StatusUnauthorized)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 response when the api key does not have access to the field", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fieldIdNoAccess := requireEnvInt(t, "TEST_ATTACHMENT_FIELD_NO_ACCESS_FIELD")
|
||||
fileId := requireEnvInt(t, "TEST_ATTACHMENT")
|
||||
|
||||
err := client.Files.Delete(ctx, recordId, fieldIdNoAccess, fileId)
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 response when the api key does not have access to the app", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fieldIdNoApp := requireEnvInt(t, "TEST_ATTACHMENT_FIELD_NO_ACCESS_APP")
|
||||
fileId := requireEnvInt(t, "TEST_ATTACHMENT")
|
||||
|
||||
err := client.Files.Delete(ctx, recordId, fieldIdNoApp, fileId)
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
|
||||
t.Run("should return a 404 response when the file field cannot be found", func(t *testing.T) {
|
||||
recordId := requireEnvInt(t, "TEST_RECORD")
|
||||
fileId := requireEnvInt(t, "TEST_ATTACHMENT")
|
||||
|
||||
err := client.Files.Delete(ctx, recordId, 0, fileId)
|
||||
|
||||
assertAPIError(t, err, http.StatusNotFound)
|
||||
})
|
||||
|
||||
t.Run("should return a 404 response when the file record cannot be found", func(t *testing.T) {
|
||||
fieldId := requireEnvInt(t, "TEST_ATTACHMENT_FIELD")
|
||||
fileId := requireEnvInt(t, "TEST_ATTACHMENT")
|
||||
|
||||
err := client.Files.Delete(ctx, 0, fieldId, fileId)
|
||||
|
||||
assertAPIError(t, err, http.StatusNotFound)
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
//go:build integration
|
||||
|
||||
package onspring_test
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/StevanFreeborn/onspring-api-sdk-go"
|
||||
)
|
||||
|
||||
func loadEnvFile(t *testing.T) {
|
||||
t.Helper()
|
||||
|
||||
file, err := os.Open(".env")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to open .env file: %v", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
_ = file.Close()
|
||||
}()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
|
||||
for scanner.Scan() {
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
|
||||
if line == "" || strings.HasPrefix(line, "#") {
|
||||
continue
|
||||
}
|
||||
|
||||
key, value, found := strings.Cut(line, "=")
|
||||
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
|
||||
key = strings.TrimSpace(key)
|
||||
value = strings.TrimSpace(value)
|
||||
|
||||
t.Setenv(key, value)
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
t.Fatalf("Failed to read .env file: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func requireEnv(t *testing.T, key string) string {
|
||||
t.Helper()
|
||||
|
||||
value := os.Getenv(key)
|
||||
|
||||
if value == "" {
|
||||
t.Fatalf("Required environment variable %s is not set", key)
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func requireEnvInt(t *testing.T, key string) int {
|
||||
t.Helper()
|
||||
|
||||
value := requireEnv(t, key)
|
||||
intValue, err := strconv.Atoi(value)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Environment variable %s is not a valid integer: %v", key, err)
|
||||
}
|
||||
|
||||
return intValue
|
||||
}
|
||||
|
||||
func requireEnvIntSlice(t *testing.T, key string) []int {
|
||||
t.Helper()
|
||||
|
||||
value := requireEnv(t, key)
|
||||
parts := strings.Split(value, ",")
|
||||
result := make([]int, len(parts))
|
||||
|
||||
for i, part := range parts {
|
||||
intValue, err := strconv.Atoi(strings.TrimSpace(part))
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Environment variable %s contains invalid integer '%s': %v", key, part, err)
|
||||
}
|
||||
|
||||
result[i] = intValue
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func createClient(t *testing.T) *onspring.Client {
|
||||
t.Helper()
|
||||
|
||||
return onspring.NewClient(
|
||||
requireEnv(t, "SANDBOX_API_KEY"),
|
||||
onspring.WithBaseURL(requireEnv(t, "API_BASE_URL")),
|
||||
)
|
||||
}
|
||||
|
||||
func createInvalidClient(t *testing.T) *onspring.Client {
|
||||
t.Helper()
|
||||
|
||||
return onspring.NewClient(
|
||||
"invalid-api-key",
|
||||
onspring.WithBaseURL(requireEnv(t, "API_BASE_URL")),
|
||||
)
|
||||
}
|
||||
|
||||
func assertAPIError(t *testing.T, err error, expectedStatus int) {
|
||||
t.Helper()
|
||||
|
||||
if err == nil {
|
||||
t.Fatalf("Expected error, got nil")
|
||||
}
|
||||
|
||||
var apiErr *onspring.OnspringAPIError
|
||||
|
||||
if !errors.As(err, &apiErr) {
|
||||
t.Fatalf("Expected OnspringAPIError, got %T: %v", err, err)
|
||||
}
|
||||
|
||||
if apiErr.StatusCode != expectedStatus {
|
||||
t.Errorf("Expected status code %d, got %d", expectedStatus, apiErr.StatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
func addTestRecord(t *testing.T, client *onspring.Client, appId, textFieldId int) int {
|
||||
t.Helper()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
response, err := client.Records.Save(ctx, onspring.SaveRecordRequest{
|
||||
AppId: appId,
|
||||
Fields: map[string]any{
|
||||
fmt.Sprintf("%d", textFieldId): "test",
|
||||
},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create test record: %v", err)
|
||||
}
|
||||
|
||||
t.Cleanup(func() {
|
||||
_ = client.Records.Delete(context.Background(), appId, response.Id)
|
||||
})
|
||||
|
||||
return response.Id
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
//go:build integration
|
||||
|
||||
package onspring_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/StevanFreeborn/onspring-api-sdk-go"
|
||||
)
|
||||
|
||||
func TestListsIntegration(t *testing.T) {
|
||||
loadEnvFile(t)
|
||||
client := createClient(t)
|
||||
ctx := context.Background()
|
||||
|
||||
t.Run("Save", func(t *testing.T) {
|
||||
t.Run("should add a list item", func(t *testing.T) {
|
||||
listId := requireEnvInt(t, "TEST_LIST_ID")
|
||||
|
||||
item := onspring.SaveListItemRequest{
|
||||
Name: "Integration Test Item",
|
||||
}
|
||||
|
||||
response, err := client.Lists.Save(ctx, listId, item)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if response.Id == "" {
|
||||
t.Error("Expected list item id to not be empty")
|
||||
}
|
||||
|
||||
t.Cleanup(func() {
|
||||
_ = client.Lists.Delete(context.Background(), listId, response.Id)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("should update a list item", func(t *testing.T) {
|
||||
listId := requireEnvInt(t, "TEST_LIST_ID")
|
||||
|
||||
item := onspring.SaveListItemRequest{
|
||||
Name: "Integration Test Item",
|
||||
}
|
||||
|
||||
addResponse, err := client.Lists.Save(ctx, listId, item)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to add list item: %v", err)
|
||||
}
|
||||
|
||||
t.Cleanup(func() {
|
||||
_ = client.Lists.Delete(context.Background(), listId, addResponse.Id)
|
||||
})
|
||||
|
||||
updateItem := onspring.SaveListItemRequest{
|
||||
Id: addResponse.Id,
|
||||
Name: "Updated Integration Test Item",
|
||||
}
|
||||
|
||||
updateResponse, err := client.Lists.Save(ctx, listId, updateItem)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if updateResponse.Id == "" {
|
||||
t.Error("Expected list item id to not be empty")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a 401 error when an invalid api key is used", func(t *testing.T) {
|
||||
invalidClient := createInvalidClient(t)
|
||||
listId := requireEnvInt(t, "TEST_LIST_ID")
|
||||
|
||||
item := onspring.SaveListItemRequest{
|
||||
Name: "Integration Test Item",
|
||||
}
|
||||
|
||||
_, err := invalidClient.Lists.Save(ctx, listId, item)
|
||||
|
||||
assertAPIError(t, err, http.StatusUnauthorized)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 error when api key does not have access to the list", func(t *testing.T) {
|
||||
listIdNoAccess := requireEnvInt(t, "TEST_LIST_ID_NO_ACCESS")
|
||||
|
||||
item := onspring.SaveListItemRequest{
|
||||
Name: "Integration Test Item",
|
||||
}
|
||||
|
||||
_, err := client.Lists.Save(ctx, listIdNoAccess, item)
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
|
||||
t.Run("should return a 404 error when the list does not exist", func(t *testing.T) {
|
||||
item := onspring.SaveListItemRequest{
|
||||
Name: "Integration Test Item",
|
||||
}
|
||||
|
||||
_, err := client.Lists.Save(ctx, 0, item)
|
||||
|
||||
assertAPIError(t, err, http.StatusNotFound)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Delete", func(t *testing.T) {
|
||||
t.Run("should delete a list item", func(t *testing.T) {
|
||||
listId := requireEnvInt(t, "TEST_LIST_ID")
|
||||
|
||||
item := onspring.SaveListItemRequest{
|
||||
Name: "Integration Test Item To Delete",
|
||||
}
|
||||
|
||||
response, err := client.Lists.Save(ctx, listId, item)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to add list item: %v", err)
|
||||
}
|
||||
|
||||
err = client.Lists.Delete(ctx, listId, response.Id)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error, got %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a 401 error when an invalid api key is used", func(t *testing.T) {
|
||||
invalidClient := createInvalidClient(t)
|
||||
listId := requireEnvInt(t, "TEST_LIST_ID")
|
||||
|
||||
err := invalidClient.Lists.Delete(ctx, listId, "some-item-id")
|
||||
|
||||
assertAPIError(t, err, http.StatusUnauthorized)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 error when api key does not have access to the list", func(t *testing.T) {
|
||||
listIdNoAccess := requireEnvInt(t, "TEST_LIST_ID_NO_ACCESS")
|
||||
listItemIdNoAccess := requireEnv(t, "TEST_LIST_ITEM_ID_NO_ACCESS")
|
||||
|
||||
err := client.Lists.Delete(ctx, listIdNoAccess, listItemIdNoAccess)
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
|
||||
t.Run("should return a 404 error when the list does not exist", func(t *testing.T) {
|
||||
err := client.Lists.Delete(ctx, 0, "a57e3d33-9195-4039-9ac0-c180013b043e")
|
||||
|
||||
assertAPIError(t, err, http.StatusNotFound)
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
//go:build integration
|
||||
|
||||
package onspring_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPingIntegration(t *testing.T) {
|
||||
loadEnvFile(t)
|
||||
|
||||
t.Run("Get should be able to connect to the API", func(t *testing.T) {
|
||||
client := createClient(t)
|
||||
|
||||
err := client.Ping.Get(context.Background())
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error, got %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,649 @@
|
||||
//go:build integration
|
||||
|
||||
package onspring_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/StevanFreeborn/onspring-api-sdk-go"
|
||||
)
|
||||
|
||||
func TestRecordsIntegration(t *testing.T) {
|
||||
loadEnvFile(t)
|
||||
client := createClient(t)
|
||||
ctx := context.Background()
|
||||
|
||||
t.Run("Get", func(t *testing.T) {
|
||||
t.Run("should get a record", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
recordId := requireEnvInt(t, "TEST_SURVEY_RECORD_ID")
|
||||
|
||||
record, err := client.Records.Get(ctx, surveyId, recordId)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if record.AppId != surveyId {
|
||||
t.Errorf("Expected appId %d, got %d", surveyId, record.AppId)
|
||||
}
|
||||
|
||||
if record.RecordId != recordId {
|
||||
t.Errorf("Expected recordId %d, got %d", recordId, record.RecordId)
|
||||
}
|
||||
|
||||
if len(record.FieldData) == 0 {
|
||||
t.Error("Expected field data to not be empty")
|
||||
}
|
||||
|
||||
for _, field := range record.FieldData {
|
||||
if field.FieldId == 0 {
|
||||
t.Error("Expected field id to not be zero")
|
||||
}
|
||||
|
||||
if field.Type == "" {
|
||||
t.Error("Expected field type to not be empty")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should get a record when fieldIds and data format are passed as parameters", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
recordId := requireEnvInt(t, "TEST_SURVEY_RECORD_ID")
|
||||
textFieldId := requireEnvInt(t, "TEST_TEXT_FIELD")
|
||||
|
||||
record, err := client.Records.Get(
|
||||
ctx,
|
||||
surveyId,
|
||||
recordId,
|
||||
onspring.WithFieldIds([]int{textFieldId}),
|
||||
onspring.WithRecordDataFormat("Formatted"),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if record.AppId != surveyId {
|
||||
t.Errorf("Expected appId %d, got %d", surveyId, record.AppId)
|
||||
}
|
||||
|
||||
if record.RecordId != recordId {
|
||||
t.Errorf("Expected recordId %d, got %d", recordId, record.RecordId)
|
||||
}
|
||||
|
||||
if len(record.FieldData) == 0 {
|
||||
t.Error("Expected field data to not be empty")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a 401 error when an invalid API key is used", func(t *testing.T) {
|
||||
invalidClient := createInvalidClient(t)
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
recordId := requireEnvInt(t, "TEST_SURVEY_RECORD_ID")
|
||||
|
||||
_, err := invalidClient.Records.Get(ctx, surveyId, recordId)
|
||||
|
||||
assertAPIError(t, err, http.StatusUnauthorized)
|
||||
})
|
||||
|
||||
t.Run("should return a 404 error when an invalid record id is used", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
|
||||
_, err := client.Records.Get(ctx, surveyId, 0)
|
||||
|
||||
assertAPIError(t, err, http.StatusNotFound)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("List", func(t *testing.T) {
|
||||
t.Run("should get records", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
|
||||
page, err := client.Records.List(ctx, surveyId)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if page.PageNumber == 0 {
|
||||
t.Error("Expected page number to not be zero")
|
||||
}
|
||||
|
||||
if page.TotalRecords == 0 {
|
||||
t.Error("Expected total records to not be zero")
|
||||
}
|
||||
|
||||
if len(page.Items) == 0 {
|
||||
t.Error("Expected items to not be empty")
|
||||
}
|
||||
|
||||
for _, record := range page.Items {
|
||||
if record.AppId != surveyId {
|
||||
t.Errorf("Expected appId %d, got %d", surveyId, record.AppId)
|
||||
}
|
||||
|
||||
if record.RecordId == 0 {
|
||||
t.Error("Expected recordId to not be zero")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should get records when fieldIds, paging information, and data format are passed as parameters", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
textFieldId := requireEnvInt(t, "TEST_TEXT_FIELD")
|
||||
|
||||
page, err := client.Records.List(
|
||||
ctx,
|
||||
surveyId,
|
||||
onspring.WithFieldIds([]int{textFieldId}),
|
||||
onspring.WithRecordDataFormat("Formatted"),
|
||||
onspring.WithPaging(onspring.ForPageNumber(1), onspring.WithPageSize(1)),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if page.PageNumber != 1 {
|
||||
t.Errorf("Expected page number 1, got %d", page.PageNumber)
|
||||
}
|
||||
|
||||
if page.PageSize != 1 {
|
||||
t.Errorf("Expected page size 1, got %d", page.PageSize)
|
||||
}
|
||||
|
||||
if len(page.Items) != 1 {
|
||||
t.Errorf("Expected 1 item, got %d", len(page.Items))
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a 401 error when an invalid API key is passed", func(t *testing.T) {
|
||||
invalidClient := createInvalidClient(t)
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
|
||||
_, err := invalidClient.Records.List(ctx, surveyId)
|
||||
|
||||
assertAPIError(t, err, http.StatusUnauthorized)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 error when the api key does not have access to the app", func(t *testing.T) {
|
||||
appIdNoAccess := requireEnvInt(t, "TEST_APP_ID_NO_ACCESS")
|
||||
|
||||
_, err := client.Records.List(ctx, appIdNoAccess)
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("ListAll", func(t *testing.T) {
|
||||
t.Run("should iterate all records for an app", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
|
||||
var records []onspring.Record
|
||||
|
||||
for record, err := range client.Records.ListAll(ctx, surveyId, onspring.WithPaging(onspring.WithPageSize(1))) {
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
records = append(records, record)
|
||||
}
|
||||
|
||||
if len(records) == 0 {
|
||||
t.Error("Expected to iterate at least one record")
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("GetMany", func(t *testing.T) {
|
||||
t.Run("should get records", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
recordId := requireEnvInt(t, "TEST_SURVEY_RECORD_ID")
|
||||
|
||||
batch, err := client.Records.GetMany(ctx, onspring.GetManyRecordsRequest{
|
||||
AppId: surveyId,
|
||||
RecordIds: []int{recordId},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if batch.Count == 0 {
|
||||
t.Error("Expected count to not be zero")
|
||||
}
|
||||
|
||||
if len(batch.Items) == 0 {
|
||||
t.Error("Expected items to not be empty")
|
||||
}
|
||||
|
||||
for _, record := range batch.Items {
|
||||
if record.AppId != surveyId {
|
||||
t.Errorf("Expected appId %d, got %d", surveyId, record.AppId)
|
||||
}
|
||||
|
||||
if record.RecordId == 0 {
|
||||
t.Error("Expected recordId to not be zero")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should get records when field ids and data format are passed as parameters", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
recordId := requireEnvInt(t, "TEST_SURVEY_RECORD_ID")
|
||||
textFieldId := requireEnvInt(t, "TEST_TEXT_FIELD")
|
||||
|
||||
batch, err := client.Records.GetMany(ctx, onspring.GetManyRecordsRequest{
|
||||
AppId: surveyId,
|
||||
RecordIds: []int{recordId},
|
||||
FieldIds: []int{textFieldId},
|
||||
DataFormat: "Formatted",
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if batch.Count == 0 {
|
||||
t.Error("Expected count to not be zero")
|
||||
}
|
||||
|
||||
if len(batch.Items) == 0 {
|
||||
t.Error("Expected items to not be empty")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a 400 error if too many record ids are passed", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
|
||||
ids := make([]int, 101)
|
||||
for i := range ids {
|
||||
ids[i] = i + 1
|
||||
}
|
||||
|
||||
_, err := client.Records.GetMany(ctx, onspring.GetManyRecordsRequest{
|
||||
AppId: surveyId,
|
||||
RecordIds: ids,
|
||||
})
|
||||
|
||||
assertAPIError(t, err, http.StatusBadRequest)
|
||||
})
|
||||
|
||||
t.Run("should return a 401 error if the api key is invalid", func(t *testing.T) {
|
||||
invalidClient := createInvalidClient(t)
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
recordId := requireEnvInt(t, "TEST_SURVEY_RECORD_ID")
|
||||
|
||||
_, err := invalidClient.Records.GetMany(ctx, onspring.GetManyRecordsRequest{
|
||||
AppId: surveyId,
|
||||
RecordIds: []int{recordId},
|
||||
})
|
||||
|
||||
assertAPIError(t, err, http.StatusUnauthorized)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 error if the user does not have access to the app", func(t *testing.T) {
|
||||
appIdNoAccess := requireEnvInt(t, "TEST_APP_ID_NO_ACCESS")
|
||||
recordId := requireEnvInt(t, "TEST_SURVEY_RECORD_ID")
|
||||
|
||||
_, err := client.Records.GetMany(ctx, onspring.GetManyRecordsRequest{
|
||||
AppId: appIdNoAccess,
|
||||
RecordIds: []int{recordId},
|
||||
})
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Query", func(t *testing.T) {
|
||||
t.Run("should return records", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
autoNumberField := requireEnvInt(t, "TEST_SURVEY_AUTO_NUMBER_FIELD")
|
||||
filter := fmt.Sprintf("%d gt 0", autoNumberField)
|
||||
|
||||
page, err := client.Records.Query(ctx, onspring.QueryRecordsRequest{
|
||||
AppId: surveyId,
|
||||
Filter: filter,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if page.PageNumber == 0 {
|
||||
t.Error("Expected page number to not be zero")
|
||||
}
|
||||
|
||||
if page.TotalRecords == 0 {
|
||||
t.Error("Expected total records to not be zero")
|
||||
}
|
||||
|
||||
if len(page.Items) == 0 {
|
||||
t.Error("Expected items to not be empty")
|
||||
}
|
||||
|
||||
for _, record := range page.Items {
|
||||
if record.AppId != surveyId {
|
||||
t.Errorf("Expected appId %d, got %d", surveyId, record.AppId)
|
||||
}
|
||||
|
||||
if record.RecordId == 0 {
|
||||
t.Error("Expected recordId to not be zero")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return records when data format, paging information, and fields are passed as parameters", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
autoNumberField := requireEnvInt(t, "TEST_SURVEY_AUTO_NUMBER_FIELD")
|
||||
textFieldId := requireEnvInt(t, "TEST_TEXT_FIELD")
|
||||
filter := fmt.Sprintf("%d gt 0", autoNumberField)
|
||||
|
||||
page, err := client.Records.Query(
|
||||
ctx,
|
||||
onspring.QueryRecordsRequest{
|
||||
AppId: surveyId,
|
||||
Filter: filter,
|
||||
FieldIds: []int{textFieldId},
|
||||
DataFormat: "Formatted",
|
||||
},
|
||||
onspring.ForPageNumber(1),
|
||||
onspring.WithPageSize(1),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if page.PageNumber != 1 {
|
||||
t.Errorf("Expected page number 1, got %d", page.PageNumber)
|
||||
}
|
||||
|
||||
if page.PageSize != 1 {
|
||||
t.Errorf("Expected page size 1, got %d", page.PageSize)
|
||||
}
|
||||
|
||||
if len(page.Items) != 1 {
|
||||
t.Errorf("Expected 1 item, got %d", len(page.Items))
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a 400 error if page size is invalid", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
autoNumberField := requireEnvInt(t, "TEST_SURVEY_AUTO_NUMBER_FIELD")
|
||||
filter := fmt.Sprintf("%d gt 0", autoNumberField)
|
||||
|
||||
_, err := client.Records.Query(
|
||||
ctx,
|
||||
onspring.QueryRecordsRequest{
|
||||
AppId: surveyId,
|
||||
Filter: filter,
|
||||
},
|
||||
onspring.WithPageSize(1001),
|
||||
)
|
||||
|
||||
assertAPIError(t, err, http.StatusBadRequest)
|
||||
})
|
||||
|
||||
t.Run("should return a 401 error if the API key is invalid", func(t *testing.T) {
|
||||
invalidClient := createInvalidClient(t)
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
autoNumberField := requireEnvInt(t, "TEST_SURVEY_AUTO_NUMBER_FIELD")
|
||||
filter := fmt.Sprintf("%d gt 0", autoNumberField)
|
||||
|
||||
_, err := invalidClient.Records.Query(ctx, onspring.QueryRecordsRequest{
|
||||
AppId: surveyId,
|
||||
Filter: filter,
|
||||
})
|
||||
|
||||
assertAPIError(t, err, http.StatusUnauthorized)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 error if the API key does not have access to the app", func(t *testing.T) {
|
||||
appIdNoAccess := requireEnvInt(t, "TEST_APP_ID_NO_ACCESS")
|
||||
autoNumberField := requireEnvInt(t, "TEST_SURVEY_AUTO_NUMBER_FIELD")
|
||||
filter := fmt.Sprintf("%d gt 0", autoNumberField)
|
||||
|
||||
_, err := client.Records.Query(ctx, onspring.QueryRecordsRequest{
|
||||
AppId: appIdNoAccess,
|
||||
Filter: filter,
|
||||
})
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("QueryAll", func(t *testing.T) {
|
||||
t.Run("should iterate all records matching a query", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
autoNumberField := requireEnvInt(t, "TEST_SURVEY_AUTO_NUMBER_FIELD")
|
||||
filter := fmt.Sprintf("%d gt 0", autoNumberField)
|
||||
|
||||
var records []onspring.Record
|
||||
|
||||
for record, err := range client.Records.QueryAll(
|
||||
ctx,
|
||||
onspring.QueryRecordsRequest{
|
||||
AppId: surveyId,
|
||||
Filter: filter,
|
||||
},
|
||||
onspring.WithPageSize(1),
|
||||
) {
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
records = append(records, record)
|
||||
}
|
||||
|
||||
if len(records) == 0 {
|
||||
t.Error("Expected to iterate at least one record")
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Save", func(t *testing.T) {
|
||||
t.Run("should add a record when no record id is passed", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
textFieldId := requireEnvInt(t, "TEST_TEXT_FIELD")
|
||||
|
||||
response, err := client.Records.Save(ctx, onspring.SaveRecordRequest{
|
||||
AppId: surveyId,
|
||||
Fields: map[string]any{
|
||||
fmt.Sprintf("%d", textFieldId): "integration test record",
|
||||
},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if response.Id == 0 {
|
||||
t.Error("Expected record id to not be zero")
|
||||
}
|
||||
|
||||
if response.Warnings == nil {
|
||||
t.Error("Expected warnings to not be nil")
|
||||
}
|
||||
|
||||
t.Cleanup(func() {
|
||||
_ = client.Records.Delete(context.Background(), surveyId, response.Id)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("should update a record when a record id is passed", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
textFieldId := requireEnvInt(t, "TEST_TEXT_FIELD")
|
||||
recordId := addTestRecord(t, client, surveyId, textFieldId)
|
||||
|
||||
response, err := client.Records.Save(ctx, onspring.SaveRecordRequest{
|
||||
AppId: surveyId,
|
||||
RecordId: &recordId,
|
||||
Fields: map[string]any{
|
||||
fmt.Sprintf("%d", textFieldId): "updated integration test record",
|
||||
},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if response.Id == 0 {
|
||||
t.Error("Expected record id to not be zero")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a 400 error when field data is empty", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
|
||||
_, err := client.Records.Save(ctx, onspring.SaveRecordRequest{
|
||||
AppId: surveyId,
|
||||
Fields: map[string]any{},
|
||||
})
|
||||
|
||||
assertAPIError(t, err, http.StatusBadRequest)
|
||||
})
|
||||
|
||||
t.Run("should return a 401 error when the api key is invalid", func(t *testing.T) {
|
||||
invalidClient := createInvalidClient(t)
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
textFieldId := requireEnvInt(t, "TEST_TEXT_FIELD")
|
||||
|
||||
_, err := invalidClient.Records.Save(ctx, onspring.SaveRecordRequest{
|
||||
AppId: surveyId,
|
||||
Fields: map[string]any{
|
||||
fmt.Sprintf("%d", textFieldId): "test",
|
||||
},
|
||||
})
|
||||
|
||||
assertAPIError(t, err, http.StatusUnauthorized)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 error when the api key does not have access to the app", func(t *testing.T) {
|
||||
appIdNoAccess := requireEnvInt(t, "TEST_APP_ID_NO_ACCESS")
|
||||
textFieldId := requireEnvInt(t, "TEST_TEXT_FIELD")
|
||||
|
||||
_, err := client.Records.Save(ctx, onspring.SaveRecordRequest{
|
||||
AppId: appIdNoAccess,
|
||||
Fields: map[string]any{
|
||||
fmt.Sprintf("%d", textFieldId): "test",
|
||||
},
|
||||
})
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
|
||||
t.Run("should return a 404 error when the record id is not found", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
textFieldId := requireEnvInt(t, "TEST_TEXT_FIELD")
|
||||
recordId := 0
|
||||
|
||||
_, err := client.Records.Save(ctx, onspring.SaveRecordRequest{
|
||||
AppId: surveyId,
|
||||
RecordId: &recordId,
|
||||
Fields: map[string]any{
|
||||
fmt.Sprintf("%d", textFieldId): "test",
|
||||
},
|
||||
})
|
||||
|
||||
assertAPIError(t, err, http.StatusNotFound)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Delete", func(t *testing.T) {
|
||||
t.Run("should delete a record", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
textFieldId := requireEnvInt(t, "TEST_TEXT_FIELD")
|
||||
recordId := addTestRecord(t, client, surveyId, textFieldId)
|
||||
|
||||
err := client.Records.Delete(ctx, surveyId, recordId)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error, got %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a 401 error when the API key is invalid", func(t *testing.T) {
|
||||
invalidClient := createInvalidClient(t)
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
recordId := requireEnvInt(t, "TEST_SURVEY_RECORD_ID")
|
||||
|
||||
err := invalidClient.Records.Delete(ctx, surveyId, recordId)
|
||||
|
||||
assertAPIError(t, err, http.StatusUnauthorized)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 error when the API key does not have access to the app", func(t *testing.T) {
|
||||
appIdNoAccess := requireEnvInt(t, "TEST_APP_ID_NO_ACCESS")
|
||||
recordId := requireEnvInt(t, "TEST_SURVEY_RECORD_ID")
|
||||
|
||||
err := client.Records.Delete(ctx, appIdNoAccess, recordId)
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
|
||||
t.Run("should return a 404 error when the record does not exist", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
|
||||
err := client.Records.Delete(ctx, surveyId, 0)
|
||||
|
||||
assertAPIError(t, err, http.StatusNotFound)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("DeleteMany", func(t *testing.T) {
|
||||
t.Run("should delete records", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
textFieldId := requireEnvInt(t, "TEST_TEXT_FIELD")
|
||||
recordId1 := addTestRecord(t, client, surveyId, textFieldId)
|
||||
recordId2 := addTestRecord(t, client, surveyId, textFieldId)
|
||||
|
||||
err := client.Records.DeleteMany(ctx, onspring.DeleteManyRecordsRequest{
|
||||
AppId: surveyId,
|
||||
RecordIds: []int{recordId1, recordId2},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error, got %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a 400 error when no record ids are provided", func(t *testing.T) {
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
|
||||
err := client.Records.DeleteMany(ctx, onspring.DeleteManyRecordsRequest{
|
||||
AppId: surveyId,
|
||||
RecordIds: []int{},
|
||||
})
|
||||
|
||||
assertAPIError(t, err, http.StatusBadRequest)
|
||||
})
|
||||
|
||||
t.Run("should return a 401 error when an invalid API key is used", func(t *testing.T) {
|
||||
invalidClient := createInvalidClient(t)
|
||||
surveyId := requireEnvInt(t, "TEST_SURVEY_ID")
|
||||
|
||||
err := invalidClient.Records.DeleteMany(ctx, onspring.DeleteManyRecordsRequest{
|
||||
AppId: surveyId,
|
||||
RecordIds: []int{1},
|
||||
})
|
||||
|
||||
assertAPIError(t, err, http.StatusUnauthorized)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 error when the API key does not have access to the app", func(t *testing.T) {
|
||||
appIdNoAccess := requireEnvInt(t, "TEST_APP_ID_NO_ACCESS")
|
||||
|
||||
err := client.Records.DeleteMany(ctx, onspring.DeleteManyRecordsRequest{
|
||||
AppId: appIdNoAccess,
|
||||
RecordIds: []int{1},
|
||||
})
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
//go:build integration
|
||||
|
||||
package onspring_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/StevanFreeborn/onspring-api-sdk-go"
|
||||
)
|
||||
|
||||
func TestReportsIntegration(t *testing.T) {
|
||||
loadEnvFile(t)
|
||||
client := createClient(t)
|
||||
ctx := context.Background()
|
||||
|
||||
t.Run("Get", func(t *testing.T) {
|
||||
t.Run("should return a report", func(t *testing.T) {
|
||||
reportId := requireEnvInt(t, "TEST_REPORT")
|
||||
|
||||
report, err := client.Reports.Get(ctx, reportId)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if report.Columns == nil {
|
||||
t.Error("Expected columns to not be nil")
|
||||
}
|
||||
|
||||
if report.Rows == nil {
|
||||
t.Error("Expected rows to not be nil")
|
||||
}
|
||||
|
||||
for _, row := range report.Rows {
|
||||
if row.Cells == nil {
|
||||
t.Error("Expected cells to not be nil")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return report data for a report with chart data when report data is requested", func(t *testing.T) {
|
||||
reportId := requireEnvInt(t, "TEST_REPORT_WITH_CHART_DATA")
|
||||
|
||||
report, err := client.Reports.Get(ctx, reportId)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if report.Columns == nil {
|
||||
t.Error("Expected columns to not be nil")
|
||||
}
|
||||
|
||||
if report.Rows == nil {
|
||||
t.Error("Expected rows to not be nil")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return chart data for a report with a chart when chart data is requested", func(t *testing.T) {
|
||||
reportId := requireEnvInt(t, "TEST_REPORT_WITH_CHART_DATA")
|
||||
|
||||
report, err := client.Reports.Get(
|
||||
ctx,
|
||||
reportId,
|
||||
onspring.WithDataFormat("Raw"),
|
||||
onspring.WithDataType("ChartData"),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if report.Columns == nil {
|
||||
t.Error("Expected columns to not be nil")
|
||||
}
|
||||
|
||||
if report.Rows == nil {
|
||||
t.Error("Expected rows to not be nil")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a 400 error if chart data is requested for a report without chart data", func(t *testing.T) {
|
||||
reportId := requireEnvInt(t, "TEST_REPORT")
|
||||
|
||||
_, err := client.Reports.Get(
|
||||
ctx,
|
||||
reportId,
|
||||
onspring.WithDataFormat("Raw"),
|
||||
onspring.WithDataType("ChartData"),
|
||||
)
|
||||
|
||||
assertAPIError(t, err, http.StatusBadRequest)
|
||||
})
|
||||
|
||||
t.Run("should return a 401 error if the api key is invalid", func(t *testing.T) {
|
||||
invalidClient := createInvalidClient(t)
|
||||
reportId := requireEnvInt(t, "TEST_REPORT")
|
||||
|
||||
_, err := invalidClient.Reports.Get(ctx, reportId)
|
||||
|
||||
assertAPIError(t, err, http.StatusUnauthorized)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 error if the api key does not have access to the report", func(t *testing.T) {
|
||||
reportIdNoAccess := requireEnvInt(t, "TEST_REPORT_NO_ACCESS")
|
||||
|
||||
_, err := client.Reports.Get(ctx, reportIdNoAccess)
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
|
||||
t.Run("should return a 404 error if the report does not exist", func(t *testing.T) {
|
||||
_, err := client.Reports.Get(ctx, 0)
|
||||
|
||||
assertAPIError(t, err, http.StatusNotFound)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("List", func(t *testing.T) {
|
||||
t.Run("should return a list of reports", func(t *testing.T) {
|
||||
appId := requireEnvInt(t, "TEST_APP_ID")
|
||||
|
||||
page, err := client.Reports.List(ctx, appId)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
if page.PageNumber == 0 {
|
||||
t.Error("Expected page number to not be zero")
|
||||
}
|
||||
|
||||
if page.TotalRecords == 0 {
|
||||
t.Error("Expected total records to not be zero")
|
||||
}
|
||||
|
||||
if len(page.Items) == 0 {
|
||||
t.Error("Expected items to not be empty")
|
||||
}
|
||||
|
||||
for _, report := range page.Items {
|
||||
if report.Id == 0 {
|
||||
t.Error("Expected report id to not be zero")
|
||||
}
|
||||
|
||||
if report.AppId == 0 {
|
||||
t.Error("Expected report appId to not be zero")
|
||||
}
|
||||
|
||||
if report.Name == "" {
|
||||
t.Error("Expected report name to not be empty")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("should return a 400 error if page size is invalid", func(t *testing.T) {
|
||||
appId := requireEnvInt(t, "TEST_APP_ID")
|
||||
|
||||
_, err := client.Reports.List(ctx, appId, onspring.WithPageSize(1001))
|
||||
|
||||
assertAPIError(t, err, http.StatusBadRequest)
|
||||
})
|
||||
|
||||
t.Run("should return a 401 error if the api key is invalid", func(t *testing.T) {
|
||||
invalidClient := createInvalidClient(t)
|
||||
appId := requireEnvInt(t, "TEST_APP_ID")
|
||||
|
||||
_, err := invalidClient.Reports.List(ctx, appId)
|
||||
|
||||
assertAPIError(t, err, http.StatusUnauthorized)
|
||||
})
|
||||
|
||||
t.Run("should return a 403 error if the api key does not have access to the app", func(t *testing.T) {
|
||||
appIdNoAccess := requireEnvInt(t, "TEST_APP_ID_NO_ACCESS")
|
||||
|
||||
_, err := client.Reports.List(ctx, appIdNoAccess)
|
||||
|
||||
assertAPIError(t, err, http.StatusForbidden)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("ListAll", func(t *testing.T) {
|
||||
t.Run("should iterate all reports for an app", func(t *testing.T) {
|
||||
appId := requireEnvInt(t, "TEST_APP_ID")
|
||||
|
||||
var reports []onspring.Report
|
||||
|
||||
for report, err := range client.Reports.ListAll(ctx, appId, onspring.WithPageSize(1)) {
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, got %v", err)
|
||||
}
|
||||
|
||||
reports = append(reports, report)
|
||||
}
|
||||
|
||||
if len(reports) == 0 {
|
||||
t.Error("Expected to iterate at least one report")
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
This is a test attachment.
|
||||
Vendored
BIN
Binary file not shown.
|
After Width: | Height: | Size: 96 KiB |
Reference in New Issue
Block a user