diff --git a/src/api/v3/client.test.ts b/src/api/v3/client.test.ts index 1c8e860..8f65f96 100644 --- a/src/api/v3/client.test.ts +++ b/src/api/v3/client.test.ts @@ -5,7 +5,10 @@ import { HttpError } from '~/api/http-error' import { useMockedUrlFetchApp } from '~/api/test-helper' import { BuffettCodeApiClientV3 } from '~/api/v3/client' import { DateParam } from '~/fiscal-periods/date-param' +import { DateRange } from '~/fiscal-periods/date-range' +import { YearQuarter } from '~/fiscal-periods/year-quarter' import { YearQuarterParam } from '~/fiscal-periods/year-quarter-param' +import { YearQuarterRange } from '~/fiscal-periods/year-quarter-range' describe('BuffettCodeApiClientV3', () => { test('HttpError#isInvalidTestingRequest', () => { @@ -110,6 +113,27 @@ describe('BuffettCodeApiClientV3', () => { }) }) + test('bulkQuarter', () => { + const mockFetch = useMockedUrlFetchApp(200, JSON.stringify(quarter)) + + const client = new BuffettCodeApiClientV3('foo') + const ticker = '2371' + const range = new YearQuarterRange( + new YearQuarter(2018, 1), + new YearQuarter(2018, 4) + ) + expect(client.bulkQuarter(ticker, range)).toEqual(quarter['data']) + expect(mockFetch.mock.calls.length).toBe(1) + expect(mockFetch.mock.calls[0].length).toBe(2) + expect(mockFetch.mock.calls[0][0]).toBe( + 'https://api.buffett-code.com/api/v3/bulk/quarter?ticker=2371&from=2018Q1&to=2018Q4' + ) + expect(mockFetch.mock.calls[0][1]).toEqual({ + headers: { 'x-api-key': 'foo' }, + muteHttpExceptions: true + }) + }) + test('ondemandQuarter', () => { const mockFetch = useMockedUrlFetchApp(200, JSON.stringify(quarter)) @@ -146,6 +170,24 @@ describe('BuffettCodeApiClientV3', () => { }) }) + test('bulkDaily', () => { + const mockFetch = useMockedUrlFetchApp(200, JSON.stringify(daily)) + + const client = new BuffettCodeApiClientV3('foo') + const ticker = '2371' + const range = new DateRange(new Date('2021-08-11'), new Date('2021-08-17')) + expect(client.bulkDaily(ticker, range)).toEqual(daily['data']) + expect(mockFetch.mock.calls.length).toBe(1) + expect(mockFetch.mock.calls[0].length).toBe(2) + expect(mockFetch.mock.calls[0][0]).toBe( + 'https://api.buffett-code.com/api/v3/bulk/daily?ticker=2371&from=2021-08-11&to=2021-08-17' + ) + expect(mockFetch.mock.calls[0][1]).toEqual({ + headers: { 'x-api-key': 'foo' }, + muteHttpExceptions: true + }) + }) + test('ondemandDaily', () => { const mockFetch = useMockedUrlFetchApp(200, JSON.stringify(daily)) diff --git a/src/api/v3/client.ts b/src/api/v3/client.ts index 03530e6..765a587 100644 --- a/src/api/v3/client.ts +++ b/src/api/v3/client.ts @@ -1,7 +1,9 @@ import { HttpError } from '~/api/http-error' import { UrlBuilder } from '~/api/url-builder' import { DateParam } from '~/fiscal-periods/date-param' +import { DateRange } from '~/fiscal-periods/date-range' import { YearQuarterParam } from '~/fiscal-periods/year-quarter-param' +import { YearQuarterRange } from '~/fiscal-periods/year-quarter-range' export class BuffettCodeApiClientV3 { static readonly baseUrl = 'https://api.buffett-code.com/api/v3' @@ -69,6 +71,20 @@ export class BuffettCodeApiClientV3 { return res['data'] } + public bulkQuarter(ticker: string, range: YearQuarterRange): object[] { + const endpoint = BuffettCodeApiClientV3.baseUrl + '/bulk/quarter' + const builder = new UrlBuilder(endpoint, { + ticker, + from: range.from.toString(), + to: range.to.toString() + }) + const url = builder.toString() + const options = this.defaultOptions() + + const res = BuffettCodeApiClientV3.request(url, options) + return res['data'] + } + public ondemandQuarter(ticker: string, period: YearQuarterParam): object { const endpoint = BuffettCodeApiClientV3.baseUrl + '/ondemand/quarter' const builder = new UrlBuilder(endpoint, { @@ -96,6 +112,20 @@ export class BuffettCodeApiClientV3 { return res['data'] } + public bulkDaily(ticker: string, range: DateRange): object[] { + const endpoint = BuffettCodeApiClientV3.baseUrl + '/bulk/daily' + const builder = new UrlBuilder(endpoint, { + ticker, + from: new DateParam(range.from).toString(), + to: new DateParam(range.to).toString() + }) + const url = builder.toString() + const options = this.defaultOptions() + + const res = BuffettCodeApiClientV3.request(url, options) + return res['data'] + } + public ondemandDaily(ticker: string, date: DateParam): object { const endpoint = BuffettCodeApiClientV3.baseUrl + '/ondemand/daily' const builder = new UrlBuilder(endpoint, { diff --git a/src/fiscal-periods/date-range.test.ts b/src/fiscal-periods/date-range.test.ts new file mode 100644 index 0000000..591a361 --- /dev/null +++ b/src/fiscal-periods/date-range.test.ts @@ -0,0 +1,19 @@ +import { DateRange } from '~/fiscal-periods/date-range' + +test('diff', () => { + expect( + new DateRange(new Date(2020, 9, 6), new Date(2021, 9, 6)).diff() + ).toEqual(365) + expect( + new DateRange(new Date(2020, 9, 6), new Date(2020, 9, 7)).diff() + ).toEqual(1) + expect( + new DateRange(new Date(2020, 9, 6), new Date(2020, 9, 6)).diff() + ).toEqual(0) + expect( + new DateRange(new Date(2020, 9, 6), new Date(2020, 9, 5)).diff() + ).toEqual(-1) + expect( + new DateRange(new Date(2020, 9, 6), new Date(2019, 9, 6)).diff() + ).toEqual(-366) +}) diff --git a/src/fiscal-periods/date-range.ts b/src/fiscal-periods/date-range.ts new file mode 100644 index 0000000..b0ecbae --- /dev/null +++ b/src/fiscal-periods/date-range.ts @@ -0,0 +1,11 @@ +export class DateRange { + constructor(readonly from: Date, readonly to: Date) { + // + } + + diff(): number { + return Math.round( + (this.to.getTime() - this.from.getTime()) / (1000 * 60 * 60 * 24) + ) + } +}