Skip to content

Commit 1be32d8

Browse files
test: added tests for streamer and monitor
1 parent 5ac30a5 commit 1be32d8

File tree

7 files changed

+677
-24
lines changed

7 files changed

+677
-24
lines changed
Lines changed: 265 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,274 @@
11
package monitorCoinbase_test
22

3-
// import (
4-
// "time"
3+
import (
4+
"fmt"
5+
"net/http"
6+
"time"
57

6-
// "github.com/go-resty/resty/v2"
7-
// . "github.com/onsi/ginkgo/v2"
8-
// . "github.com/onsi/gomega"
8+
"github.com/go-resty/resty/v2"
9+
"github.com/jarcoal/httpmock"
10+
. "github.com/onsi/ginkgo/v2"
11+
. "github.com/onsi/gomega"
912

10-
// monitorCoinbase "github.com/achannarasappa/ticker/v4/internal/monitor/coinbase"
11-
// )
13+
c "github.com/achannarasappa/ticker/v4/internal/common"
14+
monitorCoinbase "github.com/achannarasappa/ticker/v4/internal/monitor/coinbase"
15+
)
1216

13-
// var _ = Describe("Monitor Coinbase", func() {
17+
var _ = Describe("Monitor Coinbase", func() {
1418

15-
// Describe("NewMonitorCoinbase", func() {
16-
// PIt("should return a new MonitorCoinbase", func() {
17-
// monitor := monitorCoinbase.NewMonitorCoinbase(time.Second, *resty.New(), []string{"BTC-USD"}, func() {})
19+
Describe("NewMonitorCoinbase", func() {
20+
It("should return a new MonitorCoinbase", func() {
21+
monitor := monitorCoinbase.NewMonitorCoinbase(monitorCoinbase.Config{
22+
Client: *resty.New(),
23+
})
24+
Expect(monitor).NotTo(BeNil())
25+
})
1826

19-
// Expect(monitor).NotTo(BeNil())
20-
// })
21-
// })
27+
When("the underlying symbols are set", func() {
28+
It("should set the underlying symbols", func() {
29+
underlyingSymbols := []string{"BTC-USD"}
30+
monitor := monitorCoinbase.NewMonitorCoinbase(monitorCoinbase.Config{
31+
Client: *resty.New(),
32+
}, monitorCoinbase.WithSymbolsUnderlying(underlyingSymbols))
2233

23-
// Describe("GetAssetQuotes", func() {
24-
// PIt("should return the asset quotes", func() {
25-
// monitor := monitorCoinbase.NewMonitorCoinbase(time.Second, *resty.New(), []string{"BTC-USD"}, func() {})
34+
Expect(monitor).NotTo(BeNil())
35+
})
36+
})
2637

27-
// quotes := monitor.GetAssetQuotes()
28-
// Expect(quotes).NotTo(BeEmpty())
29-
// })
30-
// })
31-
// })
38+
When("the streaming URL is set", func() {
39+
It("should set the streaming URL", func() {
40+
url := "wss://websocket-feed.exchange.coinbase.com"
41+
monitor := monitorCoinbase.NewMonitorCoinbase(monitorCoinbase.Config{
42+
Client: *resty.New(),
43+
}, monitorCoinbase.WithStreamingURL(url))
44+
45+
Expect(monitor).NotTo(BeNil())
46+
})
47+
})
48+
49+
When("the refresh interval is set", func() {
50+
It("should set the refresh interval", func() {
51+
interval := 10 * time.Second
52+
monitor := monitorCoinbase.NewMonitorCoinbase(monitorCoinbase.Config{
53+
Client: *resty.New(),
54+
}, monitorCoinbase.WithRefreshInterval(interval))
55+
56+
Expect(monitor).NotTo(BeNil())
57+
})
58+
})
59+
60+
When("the onUpdate function is set", func() {
61+
It("should set the onUpdate function", func() {
62+
onUpdate := func(symbol string, pq c.QuotePrice) {}
63+
monitor := monitorCoinbase.NewMonitorCoinbase(monitorCoinbase.Config{
64+
Client: *resty.New(),
65+
})
66+
monitor.SetOnUpdate(onUpdate)
67+
68+
Expect(monitor).NotTo(BeNil())
69+
})
70+
})
71+
})
72+
73+
Describe("GetAssetQuotes", func() {
74+
BeforeEach(func() {
75+
responseFixture := `{
76+
"products": [
77+
{
78+
"base_display_symbol": "BTC",
79+
"product_type": "SPOT",
80+
"product_id": "BTC-USD",
81+
"base_name": "Bitcoin",
82+
"price": "50000.00",
83+
"price_percentage_change_24h": "2.5",
84+
"volume_24h": "1000.50",
85+
"display_name": "Bitcoin",
86+
"status": "online",
87+
"quote_currency_id": "USD",
88+
"product_venue": "CBE"
89+
}
90+
]
91+
}`
92+
responseUrl := `=~\/api\/v3\/brokerage\/market\/products.*product_ids\=BTC\-USD.*`
93+
httpmock.RegisterResponder("GET", responseUrl, func(req *http.Request) (*http.Response, error) {
94+
resp := httpmock.NewStringResponse(200, responseFixture)
95+
resp.Header.Set("Content-Type", "application/json")
96+
return resp, nil
97+
})
98+
})
99+
100+
It("should return the asset quotes", func() {
101+
monitor := monitorCoinbase.NewMonitorCoinbase(monitorCoinbase.Config{
102+
Client: *client,
103+
})
104+
105+
monitor.SetSymbols([]string{"BTC-USD"})
106+
107+
assetQuotes := monitor.GetAssetQuotes(true)
108+
Expect(assetQuotes).To(HaveLen(1))
109+
Expect(assetQuotes[0].Symbol).To(Equal("BTC"))
110+
Expect(assetQuotes[0].Name).To(Equal("Bitcoin"))
111+
Expect(assetQuotes[0].QuotePrice.Price).To(Equal(50000.00))
112+
Expect(assetQuotes[0].QuotePrice.ChangePercent).To(Equal(2.5))
113+
})
114+
115+
When("the http request fails", func() {
116+
It("should return an error", func() {
117+
// Override the previous responder with an error response
118+
responseUrl := `=~\/api\/v3\/brokerage\/market\/products.*product_ids\=BTC\-USD.*`
119+
httpmock.RegisterResponder("GET", responseUrl,
120+
httpmock.NewErrorResponder(fmt.Errorf("network error")))
121+
122+
monitor := monitorCoinbase.NewMonitorCoinbase(monitorCoinbase.Config{
123+
Client: *client,
124+
})
125+
126+
monitor.SetSymbols([]string{"BTC-USD"})
127+
128+
assetQuotes := monitor.GetAssetQuotes(true)
129+
Expect(assetQuotes).To(BeEmpty())
130+
})
131+
})
132+
133+
When("the ignoreCache flag is set to true", func() {
134+
It("should return the asset quotes from the cache", func() {
135+
monitor := monitorCoinbase.NewMonitorCoinbase(monitorCoinbase.Config{
136+
Client: *client,
137+
})
138+
139+
monitor.SetSymbols([]string{"BTC-USD"})
140+
141+
// First call to populate cache
142+
firstQuotes := monitor.GetAssetQuotes(true)
143+
144+
// Modify the HTTP mock to return different data
145+
responseFixture := `{
146+
"products": [
147+
{
148+
"base_display_symbol": "BTC",
149+
"product_type": "SPOT",
150+
"product_id": "BTC-USD",
151+
"base_name": "Bitcoin",
152+
"price": "55000.00",
153+
"price_percentage_change_24h": "5.0",
154+
"volume_24h": "2000.50",
155+
"display_name": "Bitcoin",
156+
"status": "online",
157+
"quote_currency_id": "USD",
158+
"product_venue": "CBE"
159+
}
160+
]
161+
}`
162+
responseUrl := `=~\/api\/v3\/brokerage\/market\/products.*product_ids\=BTC\-USD.*`
163+
httpmock.RegisterResponder("GET", responseUrl, func(req *http.Request) (*http.Response, error) {
164+
resp := httpmock.NewStringResponse(200, responseFixture)
165+
resp.Header.Set("Content-Type", "application/json")
166+
return resp, nil
167+
})
168+
169+
// Second call with ignoreCache=false should return cached data
170+
secondQuotes := monitor.GetAssetQuotes(false)
171+
172+
Expect(secondQuotes).To(HaveLen(1))
173+
Expect(secondQuotes[0].QuotePrice.Price).To(Equal(firstQuotes[0].QuotePrice.Price))
174+
Expect(secondQuotes[0].QuotePrice.ChangePercent).To(Equal(firstQuotes[0].QuotePrice.ChangePercent))
175+
})
176+
})
177+
})
178+
179+
Describe("Start", func() {
180+
It("should start the monitor", func() {
181+
monitor := monitorCoinbase.NewMonitorCoinbase(monitorCoinbase.Config{
182+
Client: *client,
183+
}, monitorCoinbase.WithRefreshInterval(10*time.Second))
184+
185+
err := monitor.Start()
186+
Expect(err).NotTo(HaveOccurred())
187+
})
188+
189+
When("the monitor is already started", func() {
190+
It("should return an error", func() {
191+
monitor := monitorCoinbase.NewMonitorCoinbase(monitorCoinbase.Config{
192+
Client: *client,
193+
}, monitorCoinbase.WithRefreshInterval(10*time.Second))
194+
195+
err := monitor.Start()
196+
Expect(err).NotTo(HaveOccurred())
197+
198+
err = monitor.Start()
199+
Expect(err).To(HaveOccurred())
200+
Expect(err.Error()).To(ContainSubstring("monitor already started"))
201+
})
202+
})
203+
204+
When("the initial unary request for quotes fails", func() {
205+
BeforeEach(func() {
206+
responseUrl := `=~\/api\/v3\/brokerage\/market\/products.*product_ids\=BTC\-USD.*`
207+
httpmock.RegisterResponder("GET", responseUrl,
208+
httpmock.NewErrorResponder(fmt.Errorf("network error")))
209+
})
210+
211+
It("should return an error", func() {
212+
monitor := monitorCoinbase.NewMonitorCoinbase(monitorCoinbase.Config{
213+
Client: *client,
214+
}, monitorCoinbase.WithRefreshInterval(10*time.Second))
215+
216+
monitor.SetSymbols([]string{"BTC-USD"})
217+
218+
err := monitor.Start()
219+
Expect(err).To(HaveOccurred())
220+
Expect(err.Error()).To(ContainSubstring("network error"))
221+
})
222+
})
223+
224+
When("the streamer fails to start", func() {
225+
PIt("should return an error", func() {})
226+
})
227+
228+
When("the poller fails to start", func() {
229+
PIt("should return an error", func() {})
230+
})
231+
232+
When("there is a price update", func() {
233+
234+
PIt("should call the onUpdate function", func() {})
235+
PIt("should update the asset quote cache", func() {})
236+
237+
})
238+
239+
When("there is a extended quote update", func() {
240+
241+
PIt("should call the onUpdate function", func() {})
242+
PIt("should update the asset quote cache", func() {})
243+
244+
})
245+
246+
})
247+
248+
Describe("Stop", func() {
249+
250+
It("should stop the monitor", func() {
251+
monitor := monitorCoinbase.NewMonitorCoinbase(monitorCoinbase.Config{
252+
Client: *client,
253+
}, monitorCoinbase.WithRefreshInterval(10*time.Second))
254+
255+
err := monitor.Start()
256+
Expect(err).NotTo(HaveOccurred())
257+
258+
err = monitor.Stop()
259+
Expect(err).NotTo(HaveOccurred())
260+
})
261+
262+
When("the monitor is not started", func() {
263+
It("should return an error", func() {
264+
monitor := monitorCoinbase.NewMonitorCoinbase(monitorCoinbase.Config{
265+
Client: *client,
266+
})
267+
268+
err := monitor.Stop()
269+
Expect(err).To(HaveOccurred())
270+
Expect(err.Error()).To(ContainSubstring("monitor not started"))
271+
})
272+
})
273+
})
274+
})

internal/monitor/coinbase/streamer/streamer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ func (s *Streamer) SetURL(url string) error {
153153
return fmt.Errorf("cannot set URL while streamer is connected")
154154
}
155155

156-
s.url = "wss://" + url
156+
s.url = url
157157
return nil
158158
}
159159

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package streamer_test
2+
3+
import (
4+
"testing"
5+
6+
. "github.com/onsi/ginkgo/v2"
7+
. "github.com/onsi/gomega"
8+
)
9+
10+
func TestStreamer(t *testing.T) {
11+
RegisterFailHandler(Fail)
12+
RunSpecs(t, "Streamer Suite")
13+
}

0 commit comments

Comments
 (0)