Cleanup
This commit is contained in:
25
base_test.go
25
base_test.go
@@ -1,25 +0,0 @@
|
|||||||
package airtable
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestGetBases(t *testing.T) {
|
|
||||||
client := testClient(t)
|
|
||||||
baseschema := client.GetBaseSchema("test")
|
|
||||||
baseschema.client.baseURL = mockResponse("base_schema.json").URL
|
|
||||||
|
|
||||||
result, err := baseschema.Do()
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("there should not be an err, but was: %v", err)
|
|
||||||
}
|
|
||||||
if len(result.Tables) != 2 {
|
|
||||||
t.Errorf("there should be 2 tales, but was %v", len(result.Tables))
|
|
||||||
}
|
|
||||||
|
|
||||||
baseschema.client.baseURL = mockErrorResponse(400).URL
|
|
||||||
_, err = baseschema.Do()
|
|
||||||
if err == nil {
|
|
||||||
t.Errorf("there should be an err, but was nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
// Copyright © 2020 Mike Berezin
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by an MIT license.
|
|
||||||
// Details in the LICENSE file.
|
|
||||||
|
|
||||||
package airtable
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func testClient(t *testing.T) *Client {
|
|
||||||
c := NewClient("apiKey")
|
|
||||||
c.SetRateLimit(1000)
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestClient_do(t *testing.T) {
|
|
||||||
c := testClient(t)
|
|
||||||
url := mockErrorResponse(404).URL
|
|
||||||
req, err := http.NewRequest("GET", url, nil)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
err = c.do(req, nil)
|
|
||||||
var e *HTTPClientError
|
|
||||||
if errors.Is(err, e) {
|
|
||||||
t.Errorf("should be an http error, but was not: %v", err)
|
|
||||||
}
|
|
||||||
err = c.do(nil, nil)
|
|
||||||
if err == nil {
|
|
||||||
t.Errorf("there should be an error, but was nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestClient_SetBaseURL(t *testing.T) {
|
|
||||||
testCases := []struct {
|
|
||||||
description string
|
|
||||||
url string
|
|
||||||
expectedError string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
description: "accepts a valid URL",
|
|
||||||
url: "http://localhost:3000",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "accepts a valid HTTPS URL",
|
|
||||||
url: "https://example.com",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "rejects non http/https scheme url",
|
|
||||||
url: "ftp://example.com",
|
|
||||||
expectedError: "http or https baseURL must be used",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "rejects url without scheme",
|
|
||||||
url: "example.com",
|
|
||||||
expectedError: "scheme of http or https must be specified",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
c := testClient(t)
|
|
||||||
|
|
||||||
for _, testCase := range testCases {
|
|
||||||
t.Run(testCase.description, func(t *testing.T) {
|
|
||||||
err := c.SetBaseURL(testCase.url)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
if testCase.expectedError != "" {
|
|
||||||
if !strings.Contains(err.Error(), testCase.expectedError) {
|
|
||||||
t.Fatalf("unexpected error: %s", err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
t.Fatalf("unexpected error: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
// Copyright © 2020 Mike Berezin
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by an MIT license.
|
|
||||||
// Details in the LICENSE file.
|
|
||||||
|
|
||||||
package airtable
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestHTTPClientError_Error(t *testing.T) {
|
|
||||||
e := &HTTPClientError{
|
|
||||||
StatusCode: 300,
|
|
||||||
Err: errors.New("error message"),
|
|
||||||
}
|
|
||||||
expected := "status 300, err: error message"
|
|
||||||
if got := e.Error(); got != expected {
|
|
||||||
t.Errorf("HTTPClientError.Error() = %v, want %v", got, expected)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_makeHTTPClientError(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
url string
|
|
||||||
resp *http.Response
|
|
||||||
expected string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "400",
|
|
||||||
url: "google.com",
|
|
||||||
resp: &http.Response{
|
|
||||||
StatusCode: 400,
|
|
||||||
Status: "Bad Request",
|
|
||||||
Body: io.NopCloser(bytes.NewReader([]byte("body"))),
|
|
||||||
},
|
|
||||||
expected: `status 400, err: HTTP request failure on google.com:
|
|
||||||
400 Bad Request
|
|
||||||
The request encoding is invalid; the request can't be parsed as a valid JSON.
|
|
||||||
|
|
||||||
Body: body`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
if err := makeHTTPClientError(tt.url, tt.resp); err.Error() != tt.expected {
|
|
||||||
t.Errorf("makeHTTPClientError() error:\n%v\n\nexpected:\n%v", err, tt.expected)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
// Copyright © 2020 Mike Berezin
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by an MIT license.
|
|
||||||
// Details in the LICENSE file.
|
|
||||||
|
|
||||||
package airtable
|
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestToDateTime(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
field any
|
|
||||||
want time.Time
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{"not string", any(1), time.Time{}, true},
|
|
||||||
{"string not time", any("hello"), time.Time{}, true},
|
|
||||||
{"string time", any("2022-03-24T11:12:13.000Z"), time.Date(2022, 0o3, 24, 11, 12, 13, 0, time.UTC), false},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
got, err := ToDateTime(tt.field)
|
|
||||||
if (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("ToDateTime() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(got, tt.want) {
|
|
||||||
t.Errorf("ToDateTime() = %v, want %v", got, tt.want)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFromDateTime(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
t time.Time
|
|
||||||
want any
|
|
||||||
}{
|
|
||||||
{"positive", time.Date(2022, 0o3, 24, 11, 12, 13, 1, time.UTC), any("2022-03-24T11:12:13.000Z")},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
if got := FromDateTime(tt.t); got.(string) != tt.want.(string) {
|
|
||||||
t.Errorf("FromDateTime() = %v, want %v", got, tt.want)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
package airtable
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestGetBases_Do(t *testing.T) {
|
|
||||||
client := testClient(t)
|
|
||||||
bases := client.GetBases()
|
|
||||||
bases.client.baseURL = mockResponse("get_bases.json").URL
|
|
||||||
|
|
||||||
result, err := bases.WithOffset("0").Do()
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("there should not be an err, but was: %v", err)
|
|
||||||
}
|
|
||||||
if len(result.Bases) != 2 {
|
|
||||||
t.Errorf("there should be 2 bases, but was %v", len(result.Bases))
|
|
||||||
}
|
|
||||||
|
|
||||||
bases.client.baseURL = mockErrorResponse(400).URL
|
|
||||||
_, err = bases.Do()
|
|
||||||
if err == nil {
|
|
||||||
t.Errorf("there should be an err, but was nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
// Copyright © 2020 Mike Berezin
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by an MIT license.
|
|
||||||
// Details in the LICENSE file.
|
|
||||||
|
|
||||||
package airtable
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestGetRecordsConfig_Do(t *testing.T) {
|
|
||||||
table := testTable(t)
|
|
||||||
table.client.baseURL = mockResponse("get_records_with_filter.json").URL
|
|
||||||
sortQuery1 := struct {
|
|
||||||
FieldName string
|
|
||||||
Direction string
|
|
||||||
}{"Field1", "desc"}
|
|
||||||
sortQuery2 := struct {
|
|
||||||
FieldName string
|
|
||||||
Direction string
|
|
||||||
}{"Field2", "asc"}
|
|
||||||
|
|
||||||
records, err := table.GetRecords().
|
|
||||||
FromView("view_1").
|
|
||||||
WithFilterFormula("AND({Field1}='value_1',NOT({Field2}='value_2'))").
|
|
||||||
WithSort(sortQuery1, sortQuery2).
|
|
||||||
ReturnFields("Field1", "Field2").
|
|
||||||
InStringFormat("Europe/Moscow", "ru").
|
|
||||||
MaxRecords(100).
|
|
||||||
PageSize(10).
|
|
||||||
WithOffset("hhh").
|
|
||||||
Do()
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("there should not be an err, but was: %v", err)
|
|
||||||
}
|
|
||||||
if len(records.Records) != 3 {
|
|
||||||
t.Errorf("there should be 3 records, but was %v", len(records.Records))
|
|
||||||
}
|
|
||||||
|
|
||||||
table.client.baseURL = mockErrorResponse(400).URL
|
|
||||||
_, err = table.GetRecords().Do()
|
|
||||||
if err == nil {
|
|
||||||
t.Errorf("there should be an err, but was nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
// Copyright © 2020 Mike Berezin
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by an MIT license.
|
|
||||||
// Details in the LICENSE file.
|
|
||||||
|
|
||||||
package airtable
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"net/http/httptest"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
)
|
|
||||||
|
|
||||||
func mockResponse(paths ...string) *httptest.Server {
|
|
||||||
parts := []string{".", "testdata"}
|
|
||||||
filename := filepath.Join(append(parts, paths...)...)
|
|
||||||
|
|
||||||
mockData, err := os.ReadFile(filename)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
|
||||||
_, err := rw.Write(mockData)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
func mockErrorResponse(code int) *httptest.Server {
|
|
||||||
return httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
|
||||||
http.Error(rw, "An error occurred", code)
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
// Copyright © 2020 Mike Berezin
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by an MIT license.
|
|
||||||
// Details in the LICENSE file.
|
|
||||||
|
|
||||||
package airtable
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestRecord_GetRecord(t *testing.T) {
|
|
||||||
table := testTable(t)
|
|
||||||
table.client.baseURL = mockResponse("get_record.json").URL
|
|
||||||
record, err := table.GetRecord("recnTq6CsvFM6vX2m")
|
|
||||||
if err != nil {
|
|
||||||
t.Error("must be no error")
|
|
||||||
}
|
|
||||||
expected := &Record{
|
|
||||||
client: table.client,
|
|
||||||
table: table,
|
|
||||||
ID: "recnTq6CsvFM6vX2m",
|
|
||||||
CreatedTime: "2020-04-10T11:30:57.000Z",
|
|
||||||
Fields: map[string]any{
|
|
||||||
"Field1": "Field1",
|
|
||||||
"Field2": true,
|
|
||||||
"Field3": "2020-04-06T06:00:00.000Z",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(record, expected) {
|
|
||||||
t.Errorf("expected: %#v\nbut got: %#v\n", expected, record)
|
|
||||||
}
|
|
||||||
table.client.baseURL = mockErrorResponse(404).URL
|
|
||||||
_, err = table.GetRecord("recnTq6CsvFM6vX2m")
|
|
||||||
var e *HTTPClientError
|
|
||||||
if errors.Is(err, e) {
|
|
||||||
t.Errorf("should be an http error, but was not: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRecord_DeleteRecord(t *testing.T) {
|
|
||||||
record := testRecord(t)
|
|
||||||
record.client.baseURL = mockResponse("delete_record.json").URL
|
|
||||||
res, err := record.DeleteRecord()
|
|
||||||
if err != nil {
|
|
||||||
t.Error("must be no error")
|
|
||||||
}
|
|
||||||
if !res.Deleted {
|
|
||||||
t.Errorf("expected that record will be deleted, but was: %#v", record.Deleted)
|
|
||||||
}
|
|
||||||
record.client.baseURL = mockErrorResponse(404).URL
|
|
||||||
_, err = record.DeleteRecord()
|
|
||||||
var e *HTTPClientError
|
|
||||||
if errors.Is(err, e) {
|
|
||||||
t.Errorf("should be an http error, but was not: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRecord_UpdateRecordPartial(t *testing.T) {
|
|
||||||
record := testRecord(t)
|
|
||||||
record.client.baseURL = mockResponse("get_records_with_filter.json").URL
|
|
||||||
res, err := record.UpdateRecordPartial(map[string]any{"Field_2": true})
|
|
||||||
if err != nil {
|
|
||||||
t.Error("must be no error")
|
|
||||||
}
|
|
||||||
resBool, ok := res.Fields["Field2"].(bool)
|
|
||||||
if !ok {
|
|
||||||
t.Errorf("Field2 should be bool type, but was %#v\n\nFull resp: %#v", res.Fields["Field2"], res)
|
|
||||||
}
|
|
||||||
if !resBool {
|
|
||||||
t.Errorf("expected that Field_2 will be true, but was: %#v", res.Fields["Field2"].(bool))
|
|
||||||
}
|
|
||||||
record.client.baseURL = mockErrorResponse(404).URL
|
|
||||||
_, err = record.UpdateRecordPartial(map[string]any{})
|
|
||||||
var e *HTTPClientError
|
|
||||||
if errors.Is(err, e) {
|
|
||||||
t.Errorf("should be an http error, but was not: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testRecord(t *testing.T) *Record {
|
|
||||||
table := testTable(t)
|
|
||||||
table.client.baseURL = mockResponse("get_record.json").URL
|
|
||||||
record, err := table.GetRecord("recordID")
|
|
||||||
if err != nil {
|
|
||||||
t.Error("must be no error")
|
|
||||||
}
|
|
||||||
return record
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
// Copyright © 2020 Mike Berezin
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by an MIT license.
|
|
||||||
// Details in the LICENSE file.
|
|
||||||
|
|
||||||
package airtable
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestTable_DeleteRecords(t *testing.T) {
|
|
||||||
table := testTable(t)
|
|
||||||
table.client.baseURL = mockResponse("delete_records.json").URL
|
|
||||||
records, err := table.DeleteRecords([]string{"recnTq6CsvFM6vX2m", "recr3qAQbM7juKa4o"})
|
|
||||||
if err != nil {
|
|
||||||
t.Error("must be no error")
|
|
||||||
}
|
|
||||||
for _, record := range records.Records {
|
|
||||||
if !record.Deleted {
|
|
||||||
t.Errorf("expected that record will be deleted, but was: %#v", record.Deleted)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
table.client.baseURL = mockErrorResponse(404).URL
|
|
||||||
_, err = table.DeleteRecords([]string{})
|
|
||||||
var e *HTTPClientError
|
|
||||||
if errors.Is(err, e) {
|
|
||||||
t.Errorf("should be an http error, but was not: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTable_AddRecords(t *testing.T) {
|
|
||||||
table := testTable(t)
|
|
||||||
table.client.baseURL = mockResponse("get_records_with_filter.json").URL
|
|
||||||
toSend := new(Records)
|
|
||||||
records, err := table.AddRecords(toSend)
|
|
||||||
if err != nil {
|
|
||||||
t.Error("must be no error")
|
|
||||||
}
|
|
||||||
if len(records.Records) != 3 {
|
|
||||||
t.Errorf("should be 3 records in result, but was: %v", len(records.Records))
|
|
||||||
}
|
|
||||||
table.client.baseURL = mockErrorResponse(404).URL
|
|
||||||
_, err = table.AddRecords(toSend)
|
|
||||||
var e *HTTPClientError
|
|
||||||
if errors.Is(err, e) {
|
|
||||||
t.Errorf("should be an http error, but was not: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTable_UpdateRecords(t *testing.T) {
|
|
||||||
table := testTable(t)
|
|
||||||
table.client.baseURL = mockResponse("get_records_with_filter.json").URL
|
|
||||||
toSend := new(Records)
|
|
||||||
records, err := table.UpdateRecords(toSend)
|
|
||||||
if err != nil {
|
|
||||||
t.Error("must be no error")
|
|
||||||
}
|
|
||||||
if len(records.Records) != 3 {
|
|
||||||
t.Errorf("should be 3 records in result, but was: %v", len(records.Records))
|
|
||||||
}
|
|
||||||
table.client.baseURL = mockErrorResponse(404).URL
|
|
||||||
_, err = table.UpdateRecords(toSend)
|
|
||||||
var e *HTTPClientError
|
|
||||||
if errors.Is(err, e) {
|
|
||||||
t.Errorf("should be an http error, but was not: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTable_UpdateRecordsPartial(t *testing.T) {
|
|
||||||
table := testTable(t)
|
|
||||||
table.client.baseURL = mockResponse("get_records_with_filter.json").URL
|
|
||||||
toSend := new(Records)
|
|
||||||
records, err := table.UpdateRecordsPartial(toSend)
|
|
||||||
if err != nil {
|
|
||||||
t.Error("must be no error")
|
|
||||||
}
|
|
||||||
if len(records.Records) != 3 {
|
|
||||||
t.Errorf("should be 3 records in result, but was: %v", len(records.Records))
|
|
||||||
}
|
|
||||||
table.client.baseURL = mockErrorResponse(404).URL
|
|
||||||
_, err = table.UpdateRecordsPartial(toSend)
|
|
||||||
var e *HTTPClientError
|
|
||||||
if errors.Is(err, e) {
|
|
||||||
t.Errorf("should be an http error, but was not: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testTable(t *testing.T) *Table {
|
|
||||||
client := testClient(t)
|
|
||||||
return client.GetTable("dbName", "tableName")
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user