-
Notifications
You must be signed in to change notification settings - Fork 3
/
testsuite.go
100 lines (85 loc) · 2.7 KB
/
testsuite.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package apitest
import (
"fmt"
"net/url"
"testing"
"github.com/jingweno/go-sawyer/hypermedia"
)
// IApiTest defines an interface of API test definition.
//
// Responsibility of api test is to provide some meta data about API endpoint and
// collection of test cases that describe concrete usage of that endpoint.
type IApiTest interface {
Method() string
Description() string
Path() string
TestCases() []ApiTestCase
}
// ISetuppable defines interface for tests that have setup logic
//
// If you need to run some preparation logic - this is the right place to do
type ISetuppable interface {
SetUp() error
}
// ITeardownable defines interface for tests that have teardown logic
//
// Good place to put some cleanup logic if you need to
type ITeardownable interface {
TearDown() error
}
// AssertResponseFunc defines function that asserts that expected object equals to
// given response body
type AssertResponseFunc func(t *testing.T, expected interface{}, responseBody []byte) bool
// ApiTestCase provides use case of some API endpoint: input and expected output.
//
// Test case knows nothing about API endpoint itself. Path of an API endpoint and
// its description must be provided by ApiTest.
//
// Ideally each different error that API endpoint can return should
// be described by a test case.
type ApiTestCase struct {
Description string
Headers ParamMap
QueryParams ParamMap
PathParams ParamMap
RequestBody interface{}
ExpectedHttpCode int
ExpectedHeaders map[string]string
ExpectedData interface{}
// AssertResponse is a custom assertion logic that can be used
// instead of ExpectedData. If provided, it is fully responsible
// for processing of API response payload and assertion with
// expected data.
AssertResponse AssertResponseFunc
}
type ParamMap map[string]Param
// Param defines a parameter that is used in headers or URL query
// of the API request
type Param struct {
Value interface{}
Required bool
Description string
}
// Url generates full URL to API endpoint for given test case.
// urlpath must provide full URL to the endpoint with no query parameters.
func (testCase *ApiTestCase) Url(urlpath string) (string, error) {
// TODO: what if url template contains something, but it's not provided by test case?
sawyerHyperlink := hypermedia.Hyperlink(urlpath)
params := hypermedia.M{}
for name, p := range testCase.PathParams {
params[name] = p.Value
}
u, err := sawyerHyperlink.Expand(params)
if err != nil {
return "", err
}
if testCase.QueryParams != nil {
query := url.Values{}
for key, param := range testCase.QueryParams {
valueStr := fmt.Sprintf("%v", param.Value)
query.Set(key, valueStr)
}
u.RawQuery = query.Encode()
}
return u.String(), nil
}