-
Notifications
You must be signed in to change notification settings - Fork 16
/
server.go
98 lines (80 loc) · 2.52 KB
/
server.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
package mockhttp
import (
"encoding/base64"
"fmt"
"log"
"net/http"
"net/http/httptest"
"runtime/debug"
"strings"
"sync"
. "github.com/onsi/ginkgo/v2"
)
type Server struct {
expectedAuthorizationHeader string
*httptest.Server
*sync.Mutex
mockHandlers []MockedResponseBuilder
currentHandler int
logger *log.Logger
}
func StartServer(name string, startTestServer func(http.Handler) *httptest.Server) *Server {
d := &Server{Mutex: new(sync.Mutex)}
d.Server = startTestServer(d)
d.logger = log.New(GinkgoWriter, "["+name+"] ", log.LstdFlags)
return d
}
func (d *Server) ExpectedAuthorizationHeader(header string) {
d.expectedAuthorizationHeader = header
}
func (d *Server) ExpectedBasicAuth(username, password string) {
d.ExpectedAuthorizationHeader(basicAuth(username, password))
}
func (d *Server) ServeHTTP(writer http.ResponseWriter, req *http.Request) {
d.Lock()
defer d.Unlock()
defer GinkgoRecover()
if d.currentHandler >= len(d.mockHandlers) {
Fail(fmt.Sprintf("unmocked call received\n\t%s\nCompleted mocks:\n%s\nPending mocks:\n%s\n", req.Method+" "+req.URL.String(), strings.Join(d.completedMocks(), "\n"), strings.Join(d.pendingMocks(), "\n")))
}
d.logger.Printf("%s %s\n", req.Method, req.URL.String())
d.mockHandlers[d.currentHandler].Verify(req, d)
d.mockHandlers[d.currentHandler].Respond(writer, d.logger)
d.currentHandler += 1
}
func (d *Server) completedMocks() []string {
completedMocks := []string{}
for i := 0; i < d.currentHandler; i++ {
completedMocks = append(completedMocks, "\t"+d.mockHandlers[i].Url())
}
return completedMocks
}
func (d *Server) pendingMocks() []string {
pendingMocks := []string{}
for i := d.currentHandler; i < len(d.mockHandlers); i++ {
pendingMocks = append(pendingMocks, "\t"+d.mockHandlers[i].Url())
}
return pendingMocks
}
func (d *Server) VerifyAndMock(mockedResponses ...MockedResponseBuilder) {
d.Lock()
defer d.Unlock()
d.VerifyMocks()
d.currentHandler = 0
d.mockHandlers = mockedResponses
}
func (d *Server) VerifyMocks() {
if len(d.mockHandlers) != d.currentHandler {
debug.PrintStack()
Fail(fmt.Sprintf("Uninvoked mocks\nCompleted mocks:\n%s\nPending mocks:\n%s\n", strings.Join(d.completedMocks(), "\n"), strings.Join(d.pendingMocks(), "\n")))
}
}
type MockedResponseBuilder interface {
Verify(req *http.Request, d *Server)
Respond(writer http.ResponseWriter, logger *log.Logger)
Url() string
}
func basicAuth(username, password string) string {
auth := username + ":" + password
return "Basic " + base64.StdEncoding.EncodeToString([]byte(auth))
}