github.com/polygon-io/client-go@v1.16.4/rest/reference_test.go (about) 1 package polygon_test 2 3 import ( 4 "context" 5 "encoding/json" 6 "testing" 7 "time" 8 9 "github.com/jarcoal/httpmock" 10 polygon "github.com/polygon-io/client-go/rest" 11 "github.com/polygon-io/client-go/rest/models" 12 "github.com/stretchr/testify/assert" 13 ) 14 15 func TestListTickers(t *testing.T) { 16 c := polygon.New("API_KEY") 17 18 httpmock.ActivateNonDefault(c.HTTP.GetClient()) 19 defer httpmock.DeactivateAndReset() 20 21 ticker1 := `{ 22 "ticker": "A", 23 "name": "Agilent Technologies Inc.", 24 "market": "stocks", 25 "locale": "us", 26 "primary_exchange": "XNYS", 27 "type": "CS", 28 "active": true, 29 "currency_name": "usd", 30 "cik": "0001090872", 31 "composite_figi": "BBG000BWQYZ5", 32 "share_class_figi": "BBG001SCTQY4", 33 "last_updated_utc": "2021-04-25T00:00:00.000Z" 34 }` 35 36 expectedResponse := `{ 37 "status": "OK", 38 "count": 1, 39 "next_url": "https://api.polygon.io/v3/reference/tickers?cursor=YWN0aXZlPXRydWUmZGF0ZT0yMDIxLTA0LTI1JmxpbWl0PTEmb3JkZXI9YXNjJnBhZ2VfbWFya2VyPUElN0M5YWRjMjY0ZTgyM2E1ZjBiOGUyNDc5YmZiOGE1YmYwNDVkYzU0YjgwMDcyMWE2YmI1ZjBjMjQwMjU4MjFmNGZiJnNvcnQ9dGlja2Vy", 40 "request_id": "e70013d92930de90e089dc8fa098888e", 41 "results": [ 42 ` + indent(true, ticker1, "\t\t") + ` 43 ] 44 }` 45 46 registerResponder("https://api.polygon.io/v3/reference/tickers?active=true&cik=5&cusip=10&date=2021-07-22&exchange=XNAS&limit=2&market=stocks&order=asc&sort=ticker&type=CS", expectedResponse) 47 registerResponder("https://api.polygon.io/v3/reference/tickers?cursor=YWN0aXZlPXRydWUmZGF0ZT0yMDIxLTA0LTI1JmxpbWl0PTEmb3JkZXI9YXNjJnBhZ2VfbWFya2VyPUElN0M5YWRjMjY0ZTgyM2E1ZjBiOGUyNDc5YmZiOGE1YmYwNDVkYzU0YjgwMDcyMWE2YmI1ZjBjMjQwMjU4MjFmNGZiJnNvcnQ9dGlja2Vy", "{}") 48 iter := c.ListTickers(context.Background(), models.ListTickersParams{}. 49 WithType("CS").WithMarket(models.AssetStocks). 50 WithExchange("XNAS").WithCUSIP(10).WithCIK(5). 51 WithDate(models.Date(time.Date(2021, 7, 22, 0, 0, 0, 0, time.UTC))).WithActive(true). 52 WithSort(models.TickerSymbol).WithOrder(models.Asc).WithLimit(2)) 53 54 // iter creation 55 assert.Nil(t, iter.Err()) 56 assert.NotNil(t, iter.Item()) 57 58 // first item 59 assert.True(t, iter.Next()) 60 assert.Nil(t, iter.Err()) 61 var expect models.Ticker 62 err := json.Unmarshal([]byte(ticker1), &expect) 63 assert.Nil(t, err) 64 assert.Equal(t, expect, iter.Item()) 65 66 // end of list 67 assert.False(t, iter.Next()) 68 assert.Nil(t, iter.Err()) 69 } 70 71 func TestGetTickerDetails(t *testing.T) { 72 c := polygon.New("API_KEY") 73 74 httpmock.ActivateNonDefault(c.HTTP.GetClient()) 75 defer httpmock.DeactivateAndReset() 76 77 expectedResponse := `{ 78 "status": "OK", 79 "request_id": "31d59dda-80e5-4721-8496-d0d32a654afe", 80 "results": { 81 "ticker": "AAPL", 82 "name": "Apple Inc.", 83 "market": "stocks", 84 "locale": "us", 85 "primary_exchange": "XNAS", 86 "type": "CS", 87 "active": true, 88 "currency_name": "usd", 89 "cik": "0000320193", 90 "composite_figi": "BBG000B9XRY4", 91 "share_class_figi": "BBG001S5N8V8", 92 "last_updated_utc": "2021-04-25T00:00:00.000Z", 93 "market_cap": 2771126040150, 94 "phone_number": "(408) 996-1010", 95 "address": { 96 "address1": "One Apple Park Way", 97 "city": "Cupertino", 98 "state": "CA" 99 }, 100 "description": "Apple designs a wide variety of consumer electronic devices, including smartphones (iPhone), tablets (iPad), PCs (Mac), smartwatches (Apple Watch), AirPods, and TV boxes (Apple TV), among others. The iPhone makes up the majority of Apple's total revenue. In addition, Apple offers its customers a variety of services such as Apple Music, iCloud, Apple Care, Apple TV+, Apple Arcade, Apple Card, and Apple Pay, among others. Apple's products run internally developed software and semiconductors, and the firm is well known for its integration of hardware, software and services. Apple's products are distributed online as well as through company-owned stores and third-party retailers. The company generates roughly 40% of its revenue from the Americas, with the remainder earned internationally.", 101 "sic_code": "3571", 102 "sic_description": "ELECTRONIC COMPUTERS", 103 "homepage_url": "https://www.apple.com", 104 "total_employees": 154000, 105 "list_date": "1980-12-12", 106 "branding": { 107 "logo_url": "https://api.polygon.io/v1/reference/company-branding/d3d3LmFwcGxlLmNvbQ/images/2022-01-10_logo.svg", 108 "icon_url": "https://api.polygon.io/v1/reference/company-branding/d3d3LmFwcGxlLmNvbQ/images/2022-01-10_icon.png" 109 }, 110 "share_class_shares_outstanding": 16406400000, 111 "weighted_shares_outstanding": 16334371000 112 } 113 }` 114 115 registerResponder("https://api.polygon.io/v3/reference/tickers/A?date=2021-07-22", expectedResponse) 116 res, err := c.GetTickerDetails(context.Background(), models.GetTickerDetailsParams{ 117 Ticker: "A", 118 }.WithDate(models.Date(time.Date(2021, 7, 22, 0, 0, 0, 0, time.UTC)))) 119 assert.Nil(t, err) 120 121 var expect models.GetTickerDetailsResponse 122 err = json.Unmarshal([]byte(expectedResponse), &expect) 123 assert.Nil(t, err) 124 assert.Equal(t, &expect, res) 125 } 126 127 func TestListTickerNews(t *testing.T) { 128 c := polygon.New("API_KEY") 129 130 httpmock.ActivateNonDefault(c.HTTP.GetClient()) 131 defer httpmock.DeactivateAndReset() 132 133 news1 := `{ 134 "id": "nJsSJJdwViHZcw5367rZi7_qkXLfMzacXBfpv-vD9UA", 135 "publisher": { 136 "name": "Benzinga", 137 "homepage_url": "https://www.benzinga.com/", 138 "logo_url": "https://s3.polygon.io/public/public/assets/news/logos/benzinga.svg", 139 "favicon_url": "https://s3.polygon.io/public/public/assets/news/favicons/benzinga.ico" 140 }, 141 "title": "Cathie Wood Adds More Coinbase, Skillz, Trims Square", 142 "author": "Rachit Vats", 143 "published_utc": "2021-04-26T02:33:17.000Z", 144 "article_url": "https://www.benzinga.com/markets/cryptocurrency/21/04/20784086/cathie-wood-adds-more-coinbase-skillz-trims-square", 145 "tickers": [ 146 "DOCU", 147 "DDD", 148 "NIU", 149 "ARKF", 150 "NVDA", 151 "SKLZ", 152 "PCAR", 153 "MASS", 154 "PSTI", 155 "SPFR", 156 "TREE", 157 "PHR", 158 "IRDM", 159 "BEAM", 160 "ARKW", 161 "ARKK", 162 "ARKG", 163 "PSTG", 164 "SQ", 165 "IONS", 166 "SYRS" 167 ], 168 "amp_url": "https://amp.benzinga.com/amp/content/20784086", 169 "image_url": "https://cdn2.benzinga.com/files/imagecache/og_image_social_share_1200x630/images/story/2012/andre-francois-mckenzie-auhr4gcqcce-unsplash.jpg?width=720", 170 "description": "Cathie Wood-led Ark Investment Management on Friday snapped up another 221,167 shares...", 171 "keywords": [ 172 "Sector ETFs", 173 "Penny Stocks", 174 "Cryptocurrency", 175 "Small Cap", 176 "Markets", 177 "Trading Ideas", 178 "ETFs" 179 ] 180 }` 181 182 expectedResponse := `{ 183 "status": "OK", 184 "count": 1, 185 "next_url": "https://api.polygon.io/v2/reference/news?cursor=eyJsaW1pdCI6MSwic29ydCI6InB1Ymxpc2hlZF91dGMiLCJvcmRlciI6ImFzY2VuZGluZyIsInRpY2tlciI6e30sInB1Ymxpc2hlZF91dGMiOnsiZ3RlIjoiMjAyMS0wNC0yNiJ9LCJzZWFyY2hfYWZ0ZXIiOlsxNjE5NDA0Mzk3MDAwLG51bGxdfQ", 186 "request_id": "831afdb0b8078549fed053476984947a", 187 "results": [ 188 ` + indent(true, news1, "\t\t") + ` 189 ] 190 }` 191 192 registerResponder("https://api.polygon.io/v2/reference/news?limit=2&order=asc&published_utc.lt=1626912000000&sort=published_utc&ticker.lte=AAPL", expectedResponse) 193 registerResponder("https://api.polygon.io/v2/reference/news?cursor=eyJsaW1pdCI6MSwic29ydCI6InB1Ymxpc2hlZF91dGMiLCJvcmRlciI6ImFzY2VuZGluZyIsInRpY2tlciI6e30sInB1Ymxpc2hlZF91dGMiOnsiZ3RlIjoiMjAyMS0wNC0yNiJ9LCJzZWFyY2hfYWZ0ZXIiOlsxNjE5NDA0Mzk3MDAwLG51bGxdfQ", "{}") 194 iter := c.ListTickerNews(context.Background(), models.ListTickerNewsParams{}. 195 WithTicker(models.LTE, "AAPL").WithPublishedUTC(models.LT, models.Millis(time.Date(2021, 7, 22, 0, 0, 0, 0, time.UTC))). 196 WithSort(models.PublishedUTC).WithOrder(models.Asc).WithLimit(2)) 197 198 // iter creation 199 assert.Nil(t, iter.Err()) 200 assert.NotNil(t, iter.Item()) 201 202 // first item 203 assert.True(t, iter.Next()) 204 assert.Nil(t, iter.Err()) 205 var expect models.TickerNews 206 err := json.Unmarshal([]byte(news1), &expect) 207 assert.Nil(t, err) 208 assert.Equal(t, expect, iter.Item()) 209 210 // end of list 211 assert.False(t, iter.Next()) 212 assert.Nil(t, iter.Err()) 213 } 214 215 func TestGetTickerTypes(t *testing.T) { 216 c := polygon.New("API_KEY") 217 218 httpmock.ActivateNonDefault(c.HTTP.GetClient()) 219 defer httpmock.DeactivateAndReset() 220 221 expectedResponse := `{ 222 "status": "OK", 223 "request_id": "31d59dda-80e5-4721-8496-d0d32a654afe", 224 "count": 1, 225 "results": [ 226 { 227 "asset_class": "stocks", 228 "code": "CS", 229 "description": "Common Stock", 230 "locale": "us" 231 } 232 ] 233 }` 234 235 registerResponder("https://api.polygon.io/v3/reference/tickers/types?asset_class=stocks&locale=us", expectedResponse) 236 res, err := c.GetTickerTypes(context.Background(), models.GetTickerTypesParams{}.WithAssetClass("stocks").WithLocale(models.US)) 237 assert.Nil(t, err) 238 239 var expect models.GetTickerTypesResponse 240 err = json.Unmarshal([]byte(expectedResponse), &expect) 241 assert.Nil(t, err) 242 assert.Equal(t, &expect, res) 243 } 244 245 func TestGetMarketHolidays(t *testing.T) { 246 c := polygon.New("API_KEY") 247 248 httpmock.ActivateNonDefault(c.HTTP.GetClient()) 249 defer httpmock.DeactivateAndReset() 250 251 expectedResponse := `[ 252 { 253 "exchange": "NYSE", 254 "name": "Thanksgiving", 255 "date": "2020-11-26", 256 "status": "closed" 257 }, 258 { 259 "exchange": "NASDAQ", 260 "name": "Thanksgiving", 261 "date": "2020-11-26", 262 "status": "closed" 263 }, 264 { 265 "exchange": "OTC", 266 "name": "Thanksgiving", 267 "date": "2020-11-26", 268 "status": "closed" 269 }, 270 { 271 "exchange": "NASDAQ", 272 "name": "Thanksgiving", 273 "date": "2020-11-27", 274 "status": "early-close", 275 "open": "2020-11-27T14:30:00.000Z", 276 "close": "2020-11-27T18:00:00.000Z" 277 }, 278 { 279 "exchange": "NYSE", 280 "name": "Thanksgiving", 281 "date": "2020-11-27", 282 "status": "early-close", 283 "open": "2020-11-27T14:30:00.000Z", 284 "close": "2020-11-27T18:00:00.000Z" 285 } 286 ]` 287 288 registerResponder("https://api.polygon.io/v1/marketstatus/upcoming", expectedResponse) 289 res, err := c.GetMarketHolidays(context.Background()) 290 assert.Nil(t, err) 291 292 var expect models.GetMarketHolidaysResponse 293 err = json.Unmarshal([]byte(expectedResponse), &expect) 294 assert.Nil(t, err) 295 assert.Equal(t, &expect, res) 296 } 297 298 func TestGetMarketStatus(t *testing.T) { 299 c := polygon.New("API_KEY") 300 301 httpmock.ActivateNonDefault(c.HTTP.GetClient()) 302 defer httpmock.DeactivateAndReset() 303 304 expectedResponse := `{ 305 "afterHours": true, 306 "currencies": { 307 "crypto": "open", 308 "fx": "open" 309 }, 310 "earlyHours": false, 311 "exchanges": { 312 "nasdaq": "extended-hours", 313 "nyse": "extended-hours", 314 "otc": "closed" 315 }, 316 "market": "extended-hours", 317 "serverTime": "2022-05-17T10:26:06-04:00" 318 }` 319 320 registerResponder("https://api.polygon.io/v1/marketstatus/now", expectedResponse) 321 res, err := c.GetMarketStatus(context.Background()) 322 assert.Nil(t, err) 323 324 var expect models.GetMarketStatusResponse 325 err = json.Unmarshal([]byte(expectedResponse), &expect) 326 assert.Nil(t, err) 327 assert.Equal(t, &expect, res) 328 } 329 330 func TestListSplits(t *testing.T) { 331 c := polygon.New("API_KEY") 332 333 httpmock.ActivateNonDefault(c.HTTP.GetClient()) 334 defer httpmock.DeactivateAndReset() 335 336 split := `{ 337 "execution_date": "2020-08-31", 338 "split_from": 1.0, 339 "split_to": 4, 340 "ticker": "AAPL" 341 }` 342 343 expectedResponse := `{ 344 "status": "OK", 345 "request_id": "2b539ae65c1478dee109b7397bd591b2", 346 "results": [ 347 ` + indent(true, split, "\t\t") + ` 348 ] 349 }` 350 351 registerResponder("https://api.polygon.io/v3/reference/splits?execution_date=2021-07-22&limit=2&order=asc&reverse_split=false&sort=ticker&ticker=AAPL", expectedResponse) 352 iter := c.ListSplits(context.Background(), models.ListSplitsParams{}. 353 WithTicker(models.EQ, "AAPL").WithExecutionDate(models.EQ, models.Date(time.Date(2021, 7, 22, 0, 0, 0, 0, time.UTC))).WithReverseSplit(false). 354 WithSort(models.TickerSymbol).WithOrder(models.Asc).WithLimit(2)) 355 356 // iter creation 357 assert.Nil(t, iter.Err()) 358 assert.NotNil(t, iter.Item()) 359 360 // first item 361 assert.True(t, iter.Next()) 362 assert.Nil(t, iter.Err()) 363 var expect models.Split 364 err := json.Unmarshal([]byte(split), &expect) 365 assert.Nil(t, err) 366 assert.Equal(t, expect, iter.Item()) 367 368 // end of list 369 assert.False(t, iter.Next()) 370 assert.Nil(t, iter.Err()) 371 } 372 373 func TestListDividends(t *testing.T) { 374 c := polygon.New("API_KEY") 375 376 httpmock.ActivateNonDefault(c.HTTP.GetClient()) 377 defer httpmock.DeactivateAndReset() 378 379 dividend := `{ 380 "cash_amount": 0.59375, 381 "declaration_date": "2020-09-09", 382 "dividend_type": "CD", 383 "ex_dividend_date": "2025-06-12", 384 "frequency": 4, 385 "pay_date": "2025-06-30", 386 "record_date": "2025-06-15", 387 "ticker": "CSSEN" 388 }` 389 390 expectedResponse := `{ 391 "status": "OK", 392 "request_id": "eca6d9a0d8dc1cd1b29d2d3112fe938e", 393 "next_url": "https://api.polygon.io/v3/reference/dividends?cursor=YXA9MjUmYXM9JmxpbWl0PTEwJm9yZGVyPWRlc2Mmc29ydD1leF9kaXZpZGVuZF9kYXRlJnRpY2tlcj1DU1NFTg", 394 "results": [ 395 ` + indent(true, dividend, "\t\t") + ` 396 ] 397 }` 398 399 registerResponder("https://api.polygon.io/v3/reference/dividends?dividend_type=CD&ticker=CSSEN", expectedResponse) 400 registerResponder("https://api.polygon.io/v3/reference/dividends?cursor=YXA9MjUmYXM9JmxpbWl0PTEwJm9yZGVyPWRlc2Mmc29ydD1leF9kaXZpZGVuZF9kYXRlJnRpY2tlcj1DU1NFTg", "{}") 401 iter := c.ListDividends(context.Background(), models.ListDividendsParams{}.WithTicker(models.EQ, "CSSEN").WithDividendType(models.DividendCD)) 402 403 // iter creation 404 assert.Nil(t, iter.Err()) 405 assert.NotNil(t, iter.Item()) 406 407 // first item 408 assert.True(t, iter.Next()) 409 assert.Nil(t, iter.Err()) 410 var expect models.Dividend 411 err := json.Unmarshal([]byte(dividend), &expect) 412 assert.Nil(t, err) 413 assert.Equal(t, expect, iter.Item()) 414 415 // end of list 416 assert.False(t, iter.Next()) 417 assert.Nil(t, iter.Err()) 418 } 419 420 func TestListConditions(t *testing.T) { 421 c := polygon.New("API_KEY") 422 423 httpmock.ActivateNonDefault(c.HTTP.GetClient()) 424 defer httpmock.DeactivateAndReset() 425 426 condition := `{ 427 "asset_class": "stocks", 428 "data_types": [ 429 "trade" 430 ], 431 "id": 1, 432 "legacy": false, 433 "name": "Acquisition", 434 "sip_mapping": { 435 "UTP": "A" 436 }, 437 "type": "sale_condition", 438 "update_rules": { 439 "consolidated": { 440 "updates_high_low": true, 441 "updates_open_close": true, 442 "updates_volume": true 443 }, 444 "market_center": { 445 "updates_high_low": true, 446 "updates_open_close": true, 447 "updates_volume": true 448 } 449 } 450 }` 451 452 expectedResponse := `{ 453 "status": "OK", 454 "request_id": "4599a4e2ba5e19e2e732f711e97b0d84", 455 "count": 1, 456 "next_url": "https://api.polygon.io/v3/reference/conditions?cursor=YXA9MiZhcz0mYXNzZXRfY2xhc3M9c3RvY2tzJmRhdGFfdHlwZT10cmFkZSZsaW1pdD0yJnNvcnQ9YXNzZXRfY2xhc3M", 457 "results": [ 458 ` + indent(true, condition, "\t\t") + ` 459 ] 460 }` 461 462 registerResponder("https://api.polygon.io/v3/reference/conditions?asset_class=stocks&data_type=trade&limit=1", expectedResponse) 463 registerResponder("https://api.polygon.io/v3/reference/conditions?cursor=YXA9MiZhcz0mYXNzZXRfY2xhc3M9c3RvY2tzJmRhdGFfdHlwZT10cmFkZSZsaW1pdD0yJnNvcnQ9YXNzZXRfY2xhc3M", "{}") 464 iter := c.ListConditions(context.Background(), models.ListConditionsParams{}.WithAssetClass(models.AssetStocks).WithDataType(models.DataTrade).WithLimit(1)) 465 466 // iter creation 467 assert.Nil(t, iter.Err()) 468 assert.NotNil(t, iter.Item()) 469 470 // first item 471 assert.True(t, iter.Next()) 472 assert.Nil(t, iter.Err()) 473 var expect models.Condition 474 err := json.Unmarshal([]byte(condition), &expect) 475 assert.Nil(t, err) 476 assert.Equal(t, expect, iter.Item()) 477 478 // end of list 479 assert.False(t, iter.Next()) 480 assert.Nil(t, iter.Err()) 481 } 482 483 func TestGetExchanges(t *testing.T) { 484 c := polygon.New("API_KEY") 485 486 httpmock.ActivateNonDefault(c.HTTP.GetClient()) 487 defer httpmock.DeactivateAndReset() 488 489 expectedResponse := `{ 490 "status": "OK", 491 "request_id": "c784b78622b5a68c932af78a68b5907c", 492 "count": 1, 493 "results": [ 494 { 495 "acronym": "AMEX", 496 "asset_class": "stocks", 497 "id": 1, 498 "locale": "us", 499 "mic": "XASE", 500 "name": "NYSE American, LLC", 501 "operating_mic": "XNYS", 502 "participant_id": "A", 503 "type": "exchange", 504 "url": "https://www.nyse.com/markets/nyse-american" 505 } 506 ] 507 }` 508 509 registerResponder("https://api.polygon.io/v3/reference/exchanges?asset_class=stocks&locale=us", expectedResponse) 510 res, err := c.GetExchanges(context.Background(), models.GetExchangesParams{}.WithAssetClass(models.AssetStocks).WithLocale(models.US)) 511 assert.Nil(t, err) 512 513 var expect models.GetExchangesResponse 514 err = json.Unmarshal([]byte(expectedResponse), &expect) 515 assert.Nil(t, err) 516 assert.Equal(t, &expect, res) 517 } 518 519 func TestGetOptionsContract(t *testing.T) { 520 c := polygon.New("API_KEY") 521 522 httpmock.ActivateNonDefault(c.HTTP.GetClient()) 523 defer httpmock.DeactivateAndReset() 524 525 expectedResponse := `{ 526 "results": { 527 "cfi": "OCASPS", 528 "contract_type": "call", 529 "exercise_style": "american", 530 "expiration_date": "2024-01-19", 531 "primary_exchange": "BATO", 532 "shares_per_contract": 100, 533 "strike_price": 2.5, 534 "ticker": "O:EVRI240119C00002500", 535 "underlying_ticker": "EVRI" 536 }, 537 "status": "OK", 538 "request_id": "52fccf652441fc4d4fd35e2d0d2dd1f2" 539 }` 540 541 registerResponder("https://api.polygon.io/v3/reference/options/contracts/O:EVRI240119C00002500", expectedResponse) 542 res, err := c.GetOptionsContract(context.Background(), models.GetOptionsContractParams{ 543 Ticker: "O:EVRI240119C00002500", 544 }.WithAsOf(models.Date(time.Date(2022, 5, 16, 0, 0, 0, 0, time.Local)))) 545 assert.Nil(t, err) 546 547 var expect models.GetOptionsContractResponse 548 err = json.Unmarshal([]byte(expectedResponse), &expect) 549 assert.Nil(t, err) 550 assert.Equal(t, &expect, res) 551 } 552 553 func TestListOptionsContracts(t *testing.T) { 554 c := polygon.New("API_KEY") 555 556 httpmock.ActivateNonDefault(c.HTTP.GetClient()) 557 defer httpmock.DeactivateAndReset() 558 559 contract1 := `{ 560 "cfi": "OCASPS", 561 "contract_type": "call", 562 "exercise_style": "american", 563 "expiration_date": "2022-05-20", 564 "primary_exchange": "BATO", 565 "shares_per_contract": 100, 566 "strike_price": 65, 567 "ticker": "O:A220520C00065000", 568 "underlying_ticker": "A" 569 }` 570 571 contract2 := `{ 572 "cfi": "OCASPS", 573 "contract_type": "call", 574 "exercise_style": "american", 575 "expiration_date": "2022-05-20", 576 "primary_exchange": "BATO", 577 "shares_per_contract": 100, 578 "strike_price": 70, 579 "ticker": "O:A220520C00070000", 580 "underlying_ticker": "A" 581 }` 582 583 expectedResponse := `{ 584 "status": "OK", 585 "request_id": "975d5e1aacc6c147c94934b016b8d1a7", 586 "next_url": "https://api.polygon.io/v3/reference/options/contracts?cursor=YXA9JTdCJTIySUQlMjIlM0ElMjIyNzI2MTY3OTUxMjgzOTI1NTI5JTIyJTJDJTIyU3RhcnREYXRlVXRjJTIyJTNBJTdCJTIyVGltZSUyMiUzQSUyMjIwMjEtMDktMjFUMDAlM0EwMCUzQTAwWiUyMiUyQyUyMlZhbGlkJTIyJTNBdHJ1ZSU3RCUyQyUyMkVuZERhdGVVdGMlMjIlM0ElN0IlMjJUaW1lJTIyJTNBJTIyMDAwMS0wMS0wMVQwMCUzQTAwJTNBMDBaJTIyJTJDJTIyVmFsaWQlMjIlM0FmYWxzZSU3RCUyQyUyMnVuZGVybHlpbmdfdGlja2VyJTIyJTNBJTIyQSUyMiUyQyUyMnRpY2tlciUyMiUzQSUyMk8lM0FBMjIwNTIwQzAwMTEwMDAwJTIyJTJDJTIyZXhwaXJhdGlvbl9kYXRlJTIyJTNBJTIyMjAyMi0wNS0yMFQwMCUzQTAwJTNBMDBaJTIyJTJDJTIyc3RyaWtlX3ByaWNlJTIyJTNBMTEwJTJDJTIyY2ZpJTIyJTNBJTIyT0NBU1BTJTIyJTJDJTIyY29udHJhY3RfdHlwZSUyMiUzQSUyMmNhbGwlMjIlMkMlMjJleGVyY2lzZV9zdHlsZSUyMiUzQSUyMmFtZXJpY2FuJTIyJTJDJTIycHJpbWFyeV9leGNoYW5nZSUyMiUzQSU3QiUyMlN0cmluZyUyMiUzQSUyMkJBVE8lMjIlMkMlMjJWYWxpZCUyMiUzQXRydWUlN0QlMkMlMjJzaGFyZXNfcGVyX2NvbnRyYWN0JTIyJTNBMTAwJTJDJTIyYWRkaXRpb25hbF91bmRlcmx5aW5ncyUyMiUzQSUyMm51bGwlMjIlN0QmYXM9JmNvbnRyYWN0X3R5cGU9Y2FsbCZsaW1pdD0xMCZzb3J0PXRpY2tlcg", 587 "results": [ 588 ` + indent(true, contract1, "\t\t") + `, 589 ` + indent(true, contract2, "\t\t") + ` 590 ] 591 }` 592 593 registerResponder("https://api.polygon.io/v3/reference/options/contracts?contract_type=call", expectedResponse) 594 registerResponder("https://api.polygon.io/v3/reference/options/contracts?cursor=YXA9JTdCJTIySUQlMjIlM0ElMjIyNzI2MTY3OTUxMjgzOTI1NTI5JTIyJTJDJTIyU3RhcnREYXRlVXRjJTIyJTNBJTdCJTIyVGltZSUyMiUzQSUyMjIwMjEtMDktMjFUMDAlM0EwMCUzQTAwWiUyMiUyQyUyMlZhbGlkJTIyJTNBdHJ1ZSU3RCUyQyUyMkVuZERhdGVVdGMlMjIlM0ElN0IlMjJUaW1lJTIyJTNBJTIyMDAwMS0wMS0wMVQwMCUzQTAwJTNBMDBaJTIyJTJDJTIyVmFsaWQlMjIlM0FmYWxzZSU3RCUyQyUyMnVuZGVybHlpbmdfdGlja2VyJTIyJTNBJTIyQSUyMiUyQyUyMnRpY2tlciUyMiUzQSUyMk8lM0FBMjIwNTIwQzAwMTEwMDAwJTIyJTJDJTIyZXhwaXJhdGlvbl9kYXRlJTIyJTNBJTIyMjAyMi0wNS0yMFQwMCUzQTAwJTNBMDBaJTIyJTJDJTIyc3RyaWtlX3ByaWNlJTIyJTNBMTEwJTJDJTIyY2ZpJTIyJTNBJTIyT0NBU1BTJTIyJTJDJTIyY29udHJhY3RfdHlwZSUyMiUzQSUyMmNhbGwlMjIlMkMlMjJleGVyY2lzZV9zdHlsZSUyMiUzQSUyMmFtZXJpY2FuJTIyJTJDJTIycHJpbWFyeV9leGNoYW5nZSUyMiUzQSU3QiUyMlN0cmluZyUyMiUzQSUyMkJBVE8lMjIlMkMlMjJWYWxpZCUyMiUzQXRydWUlN0QlMkMlMjJzaGFyZXNfcGVyX2NvbnRyYWN0JTIyJTNBMTAwJTJDJTIyYWRkaXRpb25hbF91bmRlcmx5aW5ncyUyMiUzQSUyMm51bGwlMjIlN0QmYXM9JmNvbnRyYWN0X3R5cGU9Y2FsbCZsaW1pdD0xMCZzb3J0PXRpY2tlcg", "{}") 595 iter := c.ListOptionsContracts(context.Background(), models.ListOptionsContractsParams{}.WithContractType("call")) 596 597 // iter creation 598 assert.Nil(t, iter.Err()) 599 assert.NotNil(t, iter.Item()) 600 601 // first item 602 assert.True(t, iter.Next()) 603 assert.Nil(t, iter.Err()) 604 var expect1 models.OptionsContract 605 err := json.Unmarshal([]byte(contract1), &expect1) 606 assert.Nil(t, err) 607 assert.Equal(t, expect1, iter.Item()) 608 609 // second item 610 assert.True(t, iter.Next()) 611 assert.Nil(t, iter.Err()) 612 var expect2 models.OptionsContract 613 err = json.Unmarshal([]byte(contract2), &expect2) 614 assert.Nil(t, err) 615 assert.Equal(t, expect2, iter.Item()) 616 617 // end of list 618 assert.False(t, iter.Next()) 619 assert.Nil(t, iter.Err()) 620 }