From 842fa2e5793629ea7a44bbea7ad930d9b4e795df Mon Sep 17 00:00:00 2001 From: tatsuya Date: Mon, 7 Nov 2022 18:20:33 +0900 Subject: [PATCH 1/8] update argument --- src/main.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.ts b/src/main.ts index bbc66f5..7d9309c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -37,7 +37,7 @@ global.exportCsv = exportCsv * 指定した銘柄の財務数字や指標を取得します。 * * @param {"6501"} ticker 銘柄コード - * @param {"2017Q4"} period 会計期間 (例: 四半期 '2017Q4', 日付 '2020-09-06') + * @param {"2017Q4"} intent 会計期間 (例: 四半期 '2017Q4', 日付 '2020-09-06')、企業情報を取得する場合は`COMPANY'を指定してください * @param {"net_sales"} propertyName 項目名 * @param {TRUE} isRawValue (オプション) 数値をRAWデータで表示するかどうか (デフォルト値: FALSE) * @param {TRUE} isWithUnits (オプション) 単位を末尾に付加するかどうか (デフォルト値: FALSE) @@ -45,6 +45,6 @@ global.exportCsv = exportCsv * @return 指定した銘柄の財務数字または指標 * @customfunction */ -global.BCODE = (ticker, period, propertyName, isRawValue = false, isWithUnits = false): number | string => { - return bcode(ticker, period, propertyName, isRawValue, isWithUnits) +global.BCODE = (ticker, intent, propertyName, isRawValue = false, isWithUnits = false): number | string => { + return bcode(ticker, intent, propertyName, isRawValue, isWithUnits) } From 72899fd81569fc467b2f92d58ef5f5ed39011b12 Mon Sep 17 00:00:00 2001 From: tatsuya Date: Mon, 7 Nov 2022 19:27:17 +0900 Subject: [PATCH 2/8] add company entity --- src/entities/v3/company.ts | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/entities/v3/company.ts diff --git a/src/entities/v3/company.ts b/src/entities/v3/company.ts new file mode 100644 index 0000000..d58671b --- /dev/null +++ b/src/entities/v3/company.ts @@ -0,0 +1,37 @@ +import { HasColumnDescription } from '~/entities/v3/interface' + +export class Company implements HasColumnDescription { + constructor(readonly data: object, readonly columnDescription: object) { + // noop + } + + propertyNames(): string[] { + return Object.keys(this.data) + } + + labelOf(propertyName: string): string | null { + const desc = this.columnDescriptionOf(propertyName) + if (desc) { + return desc['name_jp'] + } else { + return null + } + } + + unitOf(propertyName: string): string | null { + const desc = this.columnDescriptionOf(propertyName) + if (desc) { + return desc['unit'] + } else { + return null + } + } + + private columnDescriptionOf(propertyName: string): string | null { + return this.columnDescription[propertyName] + } + + static fromResponse(response: object): Company { + return new Company(response['data'], response['column_description']) + } +} From e551dcf07ecb2b85c2a564a9f20952bf965b5fc6 Mon Sep 17 00:00:00 2001 From: tatsuya Date: Mon, 7 Nov 2022 19:27:50 +0900 Subject: [PATCH 3/8] update client --- src/api/company-service.ts | 11 +++++---- src/api/v3/caching-client.ts | 3 ++- src/api/v3/client.ts | 5 ++-- src/services/company-cache.ts | 46 ++++++++++++++++++++++++++++++++--- 4 files changed, 53 insertions(+), 12 deletions(-) diff --git a/src/api/company-service.ts b/src/api/company-service.ts index 76e3a9e..8898859 100644 --- a/src/api/company-service.ts +++ b/src/api/company-service.ts @@ -1,4 +1,5 @@ import { BuffettCodeApiClientV3 } from '~/api/v3/client' +import { Company } from '~/entities/v3/company' import { DateParam } from '~/fiscal-periods/date-param' import { LqWithOffset } from '~/fiscal-periods/lq-with-offset' import { LyWithOffset } from '~/fiscal-periods/ly-with-offset' @@ -6,7 +7,7 @@ import { YearQuarter } from '~/fiscal-periods/year-quarter' import { YearQuarterParam } from '~/fiscal-periods/year-quarter-param' export class CompanyService { - public company: object + public company: Company constructor(public ticker: string, client: BuffettCodeApiClientV3, private today: Date = new Date()) { this.company = client.company(ticker) @@ -14,12 +15,12 @@ export class CompanyService { public convertYearQuarterParamToYearQuarter(period: YearQuarterParam): YearQuarter { if (period.year instanceof LyWithOffset) { - period.year = this.company['latest_fiscal_year'] + period.year.offset + period.year = this.company.data['latest_fiscal_year'] + period.year.offset } if (period.quarter instanceof LqWithOffset) { period.year = (period.year as number) + Math.ceil(period.quarter.offset / 4) - period.quarter = this.company['latest_fiscal_quarter'] + (period.quarter.offset % 4) + period.quarter = this.company.data['latest_fiscal_quarter'] + (period.quarter.offset % 4) if (period.quarter <= 0) { period.year -= 1 @@ -38,7 +39,7 @@ export class CompanyService { period = _period } - const fixedTierRange = this.company['fixed_tier_range'] + const fixedTierRange = this.company.data['fixed_tier_range'] const fixedTierOldestPeriod = new YearQuarter( fixedTierRange['oldest_fiscal_year'], fixedTierRange['oldest_fiscal_quarter'] @@ -51,7 +52,7 @@ export class CompanyService { return false } - const fixedTierRange = this.company['fixed_tier_range'] + const fixedTierRange = this.company.data['fixed_tier_range'] const fixedTierOldestDate = new Date(fixedTierRange['oldest_date']) return date.toDate().valueOf() < fixedTierOldestDate.valueOf() diff --git a/src/api/v3/caching-client.ts b/src/api/v3/caching-client.ts index 0d38fa4..a7d5c60 100644 --- a/src/api/v3/caching-client.ts +++ b/src/api/v3/caching-client.ts @@ -1,4 +1,5 @@ import { BuffettCodeApiClientV3 } from '~/api/v3/client' +import { Company } from '~/entities/v3/company' import { Daily } from '~/entities/v3/daily' import { Quarter } from '~/entities/v3/quarter' import { DateParam } from '~/fiscal-periods/date-param' @@ -12,7 +13,7 @@ export class CachingBuffettCodeApiClientV3 extends BuffettCodeApiClientV3 { super(token) } - company(ticker: string): object { + company(ticker: string): Company { const cached = CompanyCache.get(ticker) if (cached) { return cached diff --git a/src/api/v3/client.ts b/src/api/v3/client.ts index c4450c0..a2fcae3 100644 --- a/src/api/v3/client.ts +++ b/src/api/v3/client.ts @@ -1,5 +1,6 @@ import { HttpError } from '~/api/http-error' import { UrlBuilder } from '~/api/url-builder' +import { Company } from '~/entities/v3/company' import { Daily } from '~/entities/v3/daily' import { Quarter } from '~/entities/v3/quarter' import { DateParam } from '~/fiscal-periods/date-param' @@ -45,14 +46,14 @@ export class BuffettCodeApiClientV3 { } } - public company(ticker: string): object { + public company(ticker: string): Company { const endpoint = BuffettCodeApiClientV3.baseUrl + '/company' const builder = new UrlBuilder(endpoint, { ticker: ticker }) const url = builder.toString() const options = this.defaultOptions() const res = BuffettCodeApiClientV3.request(url, options) - return res['data'] + return Company.fromResponse(res) } public quarter(ticker: string, period: YearQuarterParam): Quarter { diff --git a/src/services/company-cache.ts b/src/services/company-cache.ts index b0dcbaf..b09551d 100644 --- a/src/services/company-cache.ts +++ b/src/services/company-cache.ts @@ -1,3 +1,5 @@ +import { Company } from '~/entities/v3/company' + export class CompanyCache { static readonly prefix = 'company' @@ -9,9 +11,14 @@ export class CompanyCache { return `${this.prefix}-${ticker}` } - static get(ticker): object | null { + static columnDescriptionKey(): string { + return `${this.prefix}-column-description` + } + + static getData(ticker: string): object | null { const cache = CacheService.getUserCache() - const cached = cache.get(this.key(ticker)) + const key = this.key(ticker) + const cached = cache.get(key) if (!cached) { return null } @@ -19,8 +26,39 @@ export class CompanyCache { return JSON.parse(cached) } - static put(ticker: string, company: object, expirationInSeconds = 21600): void { + static getColumnDescription(): object | null { const cache = CacheService.getUserCache() - cache.put(this.key(ticker), JSON.stringify(company), expirationInSeconds) + const cached = cache.get(this.columnDescriptionKey()) + if (!cached) { + return null + } + + return JSON.parse(cached) + } + + static get(ticker: string): Company | null { + const cachedData = this.getData(ticker) + const cachedColumnDescription = this.getColumnDescription() + if (!cachedData || !cachedColumnDescription) { + return null + } + + return new Company(cachedData, cachedColumnDescription) + } + + static putData(ticker: string, company: object, expirationInSeconds = 21600): void { + const cache = CacheService.getUserCache() + const key = this.key(ticker) + cache.put(key, JSON.stringify(company), expirationInSeconds) + } + + static putColumnDescription(columnDescription: object, expirationInSeconds = 21600): void { + const cache = CacheService.getUserCache() + cache.put(this.columnDescriptionKey(), JSON.stringify(columnDescription), expirationInSeconds) + } + + static put(ticker: string, company: Company, expirationInSeconds = 21600): void { + this.putData(ticker, company.data, expirationInSeconds) + this.putColumnDescription(company.columnDescription, expirationInSeconds) } } From 14c5d901d675ec785d3956eff33e974f636e1f4a Mon Sep 17 00:00:00 2001 From: tatsuya Date: Mon, 7 Nov 2022 19:28:14 +0900 Subject: [PATCH 4/8] add company intent --- src/custom-functions/v3/bcode-company.ts | 17 ++++++++++++++++ src/custom-functions/v3/bcode.ts | 25 +++++++++++++++++------- 2 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 src/custom-functions/v3/bcode-company.ts diff --git a/src/custom-functions/v3/bcode-company.ts b/src/custom-functions/v3/bcode-company.ts new file mode 100644 index 0000000..585b272 --- /dev/null +++ b/src/custom-functions/v3/bcode-company.ts @@ -0,0 +1,17 @@ +import { BuffettCodeApiClientV3 } from '~/api/v3/client' +import { PropertyNotFoundError } from '~/custom-functions/error' +import { BcodeResult } from '~/custom-functions/v3/bcode-result' + +export function bcodeCompany(client: BuffettCodeApiClientV3, ticker: string, propertyName: string): BcodeResult { + const company = client.company(ticker) + + const property = company.columnDescription[propertyName] + if (property == undefined) { + throw new PropertyNotFoundError(`propetyName '${propertyName}' is not found.`) + } + + const value = company.data[propertyName] + const unit = company.unitOf(propertyName) + + return new BcodeResult(propertyName, value, unit) +} diff --git a/src/custom-functions/v3/bcode.ts b/src/custom-functions/v3/bcode.ts index 43ff088..ded5cea 100644 --- a/src/custom-functions/v3/bcode.ts +++ b/src/custom-functions/v3/bcode.ts @@ -1,3 +1,4 @@ +import { bcodeCompany } from './bcode-company' import { CachingBuffettCodeApiClientV3 } from '~/api/v3/caching-client' import { bcodeDaily } from '~/custom-functions/v3/bcode-daily' import { bcodeQuarter } from '~/custom-functions/v3/bcode-quarter' @@ -8,7 +9,7 @@ import { Setting } from '~/setting' export function bcode( ticker: string, - period: string | Date, + intent: string | Date, propertyName: string, isRawValue = false, isWithUnits = false @@ -17,7 +18,7 @@ export function bcode( throw new Error('<>') } - if (!period) { + if (!intent) { throw new Error('<>') } @@ -25,18 +26,28 @@ export function bcode( throw new Error('<>') } - if (period instanceof Date) { - period = period.toISOString().substring(0, 10) - } - const setting = Setting.load() if (!setting.token) { throw new Error('<>') } + if (intent === 'COMPANY') { + try { + const client = new CachingBuffettCodeApiClientV3(setting.token) + const result = bcodeCompany(client, ticker, propertyName) + return result.format(isRawValue, isWithUnits) + } catch (e) { + ErrorHandler.handle(e) + } + } + + if (intent instanceof Date) { + intent = intent.toISOString().substring(0, 10) + } + try { const client = new CachingBuffettCodeApiClientV3(setting.token) - const parsedPeriod = PeriodParser.parse(period) + const parsedPeriod = PeriodParser.parse(intent) let result: BcodeResult if (PeriodParser.isDateParam(parsedPeriod)) { result = bcodeDaily( From 6f9eca5d351924e0b09de95f72621455c07e20ed Mon Sep 17 00:00:00 2001 From: tatsuya Date: Fri, 11 Nov 2022 11:24:54 +0900 Subject: [PATCH 5/8] fix test --- package.json | 3 +- src/__mocks__/api/v3/client.ts | 3 +- src/api/v3/client.test.ts | 3 +- src/custom-functions/v3/bcode-company.test.ts | 16 ++++++++ src/entities/v3/company.test.ts | 18 +++++++++ src/services/company-cache.test.ts | 39 ++++++++++++++----- 6 files changed, 70 insertions(+), 12 deletions(-) create mode 100644 src/custom-functions/v3/bcode-company.test.ts create mode 100644 src/entities/v3/company.test.ts diff --git a/package.json b/package.json index 19d7364..c7cd414 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,8 @@ "build": "cpx 'appsscript.json' 'dist' -v && cpx 'src/ui/*.html' 'dist' -v && webpack", "watch": "webpack -w", "lint": "eslint 'src/**/*.ts'", - "test": "npm run lint && jest", + "jest": "jest", + "test": "npm run lint && npm run jest", "switch:local": "cp .clasp.local.json .clasp.json", "switch:dev": "cp .clasp.dev.json .clasp.json", "switch:prod": "cp .clasp.prod.json .clasp.json", diff --git a/src/__mocks__/api/v3/client.ts b/src/__mocks__/api/v3/client.ts index 521a6ee..a7d0fa9 100644 --- a/src/__mocks__/api/v3/client.ts +++ b/src/__mocks__/api/v3/client.ts @@ -3,6 +3,7 @@ import { default as company } from '~/__mocks__/fixtures/v3/company.js' import { default as daily } from '~/__mocks__/fixtures/v3/daily.js' import { default as quarter } from '~/__mocks__/fixtures/v3/quarter.js' import { HttpError } from '~/api/http-error' +import { Company } from '~/entities/v3/company' import { Daily } from '~/entities/v3/daily' import { Quarter } from '~/entities/v3/quarter' @@ -23,7 +24,7 @@ export class BuffettCodeApiClientV3 { throw new HttpError('/v3/company', res) } - return this.mockCompany()['data'] + return Company.fromResponse(this.mockCompany()) } quarter(ticker: string): Quarter { diff --git a/src/api/v3/client.test.ts b/src/api/v3/client.test.ts index 20ab39f..9dc14b6 100644 --- a/src/api/v3/client.test.ts +++ b/src/api/v3/client.test.ts @@ -4,6 +4,7 @@ import * as quarter from '~/__mocks__/fixtures/v3/quarter' import { HttpError } from '~/api/http-error' import { useMockedUrlFetchApp } from '~/api/test-helper' import { BuffettCodeApiClientV3 } from '~/api/v3/client' +import { Company } from '~/entities/v3/company' import { Daily } from '~/entities/v3/daily' import { Quarter } from '~/entities/v3/quarter' import { DateParam } from '~/fiscal-periods/date-param' @@ -66,7 +67,7 @@ describe('BuffettCodeApiClientV3', () => { const client = new BuffettCodeApiClientV3('foo') const ticker = '2371' - expect(client.company(ticker)).toEqual(company['data']) + expect(client.company(ticker)).toEqual(Company.fromResponse(company)) 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/company?ticker=${ticker}`) diff --git a/src/custom-functions/v3/bcode-company.test.ts b/src/custom-functions/v3/bcode-company.test.ts new file mode 100644 index 0000000..32e32fa --- /dev/null +++ b/src/custom-functions/v3/bcode-company.test.ts @@ -0,0 +1,16 @@ +import { CachingBuffettCodeApiClientV3 } from '~/api/v3/caching-client' +import { bcodeCompany } from '~/custom-functions/v3/bcode-company' +import { BcodeResult } from '~/custom-functions/v3/bcode-result' + +jest.mock('~/api/v3/client', () => jest.requireActual('~/__mocks__/api/v3/client')) +jest.mock('~/services/company-cache', () => jest.requireActual('~/__mocks__/services/company-cache')) + +test('bcodeCompany', () => { + const ticker = '2371' + const propertyName = 'company_name' + + const client = new CachingBuffettCodeApiClientV3('token') + const result = bcodeCompany(client, ticker, propertyName) + + expect(result).toEqual(new BcodeResult(propertyName, 'カカクコム', 'なし')) +}) diff --git a/src/entities/v3/company.test.ts b/src/entities/v3/company.test.ts new file mode 100644 index 0000000..9e5cc96 --- /dev/null +++ b/src/entities/v3/company.test.ts @@ -0,0 +1,18 @@ +import * as response from '~/__mocks__/fixtures/v3/company' +import { Company } from '~/entities/v3/company' + +const company = Company.fromResponse(response) + +test('propertyName', () => { + expect(company.propertyNames()).toEqual(Object.keys(response['column_description'])) +}) + +test('labelOf', () => { + expect(company.labelOf('company_name')).toEqual('会社名') + expect(company.labelOf('priority_market')).toEqual('優先市場') +}) + +test('unitOf', () => { + expect(company.unitOf('company_name')).toEqual('なし') + expect(company.unitOf('priority_market')).toEqual('なし') +}) diff --git a/src/services/company-cache.test.ts b/src/services/company-cache.test.ts index 32de284..d115f5e 100644 --- a/src/services/company-cache.test.ts +++ b/src/services/company-cache.test.ts @@ -2,29 +2,50 @@ import * as companyFixture from '~/__mocks__/fixtures/v3/company' import { getMock, putMock } from '~/services/cache-test-helper' import { CompanyCache } from '~/services/company-cache' -const company = companyFixture['data'] - test('key', () => { expect(CompanyCache.key('2371')).toBe('company-2371') }) +test('columnDescriptionKey', () => { + expect(CompanyCache.columnDescriptionKey()).toBe('company-column-description') +}) + beforeEach(() => { jest.clearAllMocks() }) -test('get', () => { - getMock.mockReturnValueOnce(JSON.stringify(company)) - expect(CompanyCache.get('2371')).toEqual(company) - expect(CompanyCache.get('2371')).toBeNull() +test('getData', () => { + getMock.mockReturnValueOnce(JSON.stringify(companyFixture['data'])) + expect(CompanyCache.getData('2371')).toEqual(companyFixture['data']) + expect(CompanyCache.getData('2371')).toBeNull() expect(getMock).toBeCalledTimes(2) expect(getMock).nthCalledWith(1, 'company-2371') expect(getMock).nthCalledWith(2, 'company-2371') }) -test('put', () => { - CompanyCache.put('2371', company) +test('getColumnDescription', () => { + getMock.mockReturnValueOnce(JSON.stringify(companyFixture['column_description'])) + expect(CompanyCache.getColumnDescription()).toEqual(companyFixture['column_description']) + + expect(getMock).toBeCalledTimes(1) + expect(getMock).nthCalledWith(1, 'company-column-description') +}) + +test('putData', () => { + CompanyCache.putData('2371', companyFixture['data']) + + expect(putMock).toBeCalledTimes(1) + expect(putMock).toBeCalledWith('company-2371', JSON.stringify(companyFixture['data']), 21600) +}) + +test('putColumnDescription', () => { + CompanyCache.putColumnDescription(companyFixture['column_description']) expect(putMock).toBeCalledTimes(1) - expect(putMock).toBeCalledWith('company-2371', JSON.stringify(company), 21600) + expect(putMock).toBeCalledWith( + 'company-column-description', + JSON.stringify(companyFixture['column_description']), + 21600 + ) }) From 56cb8787ee3232d4f21665c7ed64f95b613f90bc Mon Sep 17 00:00:00 2001 From: tatsuya Date: Fri, 11 Nov 2022 11:55:00 +0900 Subject: [PATCH 6/8] Update src/main.ts Co-authored-by: Akiomi Kamakura --- src/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.ts b/src/main.ts index 7d9309c..53f1e5e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -37,7 +37,7 @@ global.exportCsv = exportCsv * 指定した銘柄の財務数字や指標を取得します。 * * @param {"6501"} ticker 銘柄コード - * @param {"2017Q4"} intent 会計期間 (例: 四半期 '2017Q4', 日付 '2020-09-06')、企業情報を取得する場合は`COMPANY'を指定してください + * @param {"2017Q4"} intent 会計期間または識別子 (例: 四半期 '2017Q4', 日付 '2020-09-06', 企業情報 'COMPANY') * @param {"net_sales"} propertyName 項目名 * @param {TRUE} isRawValue (オプション) 数値をRAWデータで表示するかどうか (デフォルト値: FALSE) * @param {TRUE} isWithUnits (オプション) 単位を末尾に付加するかどうか (デフォルト値: FALSE) From 7270ccade3f6db821a955371967ee387396804bc Mon Sep 17 00:00:00 2001 From: tatsuya Date: Fri, 11 Nov 2022 12:10:24 +0900 Subject: [PATCH 7/8] fix v3 bcode --- src/custom-functions/v3/bcode.ts | 4 ++-- src/setting.ts | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/custom-functions/v3/bcode.ts b/src/custom-functions/v3/bcode.ts index ded5cea..41edc97 100644 --- a/src/custom-functions/v3/bcode.ts +++ b/src/custom-functions/v3/bcode.ts @@ -19,7 +19,7 @@ export function bcode( } if (!intent) { - throw new Error('<>') + throw new Error('<>') } if (!propertyName) { @@ -31,7 +31,7 @@ export function bcode( throw new Error('<>') } - if (intent === 'COMPANY') { + if (typeof intent === 'string' && intent.toUpperCase() === Setting.companyIntent) { try { const client = new CachingBuffettCodeApiClientV3(setting.token) const result = bcodeCompany(client, ticker, propertyName) diff --git a/src/setting.ts b/src/setting.ts index 91d45fb..a25dea6 100644 --- a/src/setting.ts +++ b/src/setting.ts @@ -12,6 +12,8 @@ export class Setting { static readonly defaultOndemandApiEnabled = false static readonly defaultOndemandApiCallMode = Setting.ondemandApiCallModes.DEFAULT + static readonly companyIntent = 'COMPANY' + private constructor( private _token: string, private _ondemandApiEnabled: boolean, From 020c0f884c588105c18abd611d437718e9e0b686 Mon Sep 17 00:00:00 2001 From: tatsuya Date: Fri, 11 Nov 2022 12:22:46 +0900 Subject: [PATCH 8/8] fix test --- src/__mocks__/api/v3/client.ts | 2 +- src/services/company-cache.test.ts | 58 ++++++++++++++---------------- src/services/company-cache.ts | 8 ++--- 3 files changed, 32 insertions(+), 36 deletions(-) diff --git a/src/__mocks__/api/v3/client.ts b/src/__mocks__/api/v3/client.ts index a7d0fa9..f3dd955 100644 --- a/src/__mocks__/api/v3/client.ts +++ b/src/__mocks__/api/v3/client.ts @@ -18,7 +18,7 @@ export class BuffettCodeApiClientV3 { this.mockQuarter.mockReturnValue(quarter) } - company(ticker: string): object { + company(ticker: string): Company { if (ticker !== '2371') { const res = new HTTPResnpose() throw new HttpError('/v3/company', res) diff --git a/src/services/company-cache.test.ts b/src/services/company-cache.test.ts index d115f5e..f54928f 100644 --- a/src/services/company-cache.test.ts +++ b/src/services/company-cache.test.ts @@ -1,7 +1,10 @@ import * as companyFixture from '~/__mocks__/fixtures/v3/company' +import { Company } from '~/entities/v3/company' import { getMock, putMock } from '~/services/cache-test-helper' import { CompanyCache } from '~/services/company-cache' +const company = Company.fromResponse(companyFixture) + test('key', () => { expect(CompanyCache.key('2371')).toBe('company-2371') }) @@ -14,38 +17,31 @@ beforeEach(() => { jest.clearAllMocks() }) -test('getData', () => { - getMock.mockReturnValueOnce(JSON.stringify(companyFixture['data'])) - expect(CompanyCache.getData('2371')).toEqual(companyFixture['data']) - expect(CompanyCache.getData('2371')).toBeNull() - - expect(getMock).toBeCalledTimes(2) - expect(getMock).nthCalledWith(1, 'company-2371') - expect(getMock).nthCalledWith(2, 'company-2371') -}) - -test('getColumnDescription', () => { - getMock.mockReturnValueOnce(JSON.stringify(companyFixture['column_description'])) - expect(CompanyCache.getColumnDescription()).toEqual(companyFixture['column_description']) - - expect(getMock).toBeCalledTimes(1) - expect(getMock).nthCalledWith(1, 'company-column-description') -}) - -test('putData', () => { - CompanyCache.putData('2371', companyFixture['data']) - - expect(putMock).toBeCalledTimes(1) - expect(putMock).toBeCalledWith('company-2371', JSON.stringify(companyFixture['data']), 21600) +describe('get', () => { + test('returns data if cache exists', () => { + getMock.mockReturnValueOnce(JSON.stringify(company.data)) + getMock.mockReturnValueOnce(JSON.stringify(company.columnDescription)) + expect(CompanyCache.get('2371')).toEqual(company) + + expect(getMock).toBeCalledTimes(2) + expect(getMock).nthCalledWith(1, 'company-2371') + expect(getMock).nthCalledWith(2, 'company-column-description') + }) + + test('returns null if cache does not exist', () => { + getMock.mockReturnValue(null) + expect(CompanyCache.get('2371')).toBeNull() + + expect(getMock).toBeCalledTimes(2) + expect(getMock).nthCalledWith(1, 'company-2371') + expect(getMock).nthCalledWith(2, 'company-column-description') + }) }) -test('putColumnDescription', () => { - CompanyCache.putColumnDescription(companyFixture['column_description']) +test('put', () => { + CompanyCache.put('2371', company) - expect(putMock).toBeCalledTimes(1) - expect(putMock).toBeCalledWith( - 'company-column-description', - JSON.stringify(companyFixture['column_description']), - 21600 - ) + expect(putMock).toBeCalledTimes(2) + expect(putMock).toBeCalledWith('company-2371', JSON.stringify(company.data), 21600) + expect(putMock).toBeCalledWith('company-column-description', JSON.stringify(company.columnDescription), 21600) }) diff --git a/src/services/company-cache.ts b/src/services/company-cache.ts index b09551d..bd91958 100644 --- a/src/services/company-cache.ts +++ b/src/services/company-cache.ts @@ -15,7 +15,7 @@ export class CompanyCache { return `${this.prefix}-column-description` } - static getData(ticker: string): object | null { + private static getData(ticker: string): object | null { const cache = CacheService.getUserCache() const key = this.key(ticker) const cached = cache.get(key) @@ -26,7 +26,7 @@ export class CompanyCache { return JSON.parse(cached) } - static getColumnDescription(): object | null { + private static getColumnDescription(): object | null { const cache = CacheService.getUserCache() const cached = cache.get(this.columnDescriptionKey()) if (!cached) { @@ -46,13 +46,13 @@ export class CompanyCache { return new Company(cachedData, cachedColumnDescription) } - static putData(ticker: string, company: object, expirationInSeconds = 21600): void { + private static putData(ticker: string, company: object, expirationInSeconds = 21600): void { const cache = CacheService.getUserCache() const key = this.key(ticker) cache.put(key, JSON.stringify(company), expirationInSeconds) } - static putColumnDescription(columnDescription: object, expirationInSeconds = 21600): void { + private static putColumnDescription(columnDescription: object, expirationInSeconds = 21600): void { const cache = CacheService.getUserCache() cache.put(this.columnDescriptionKey(), JSON.stringify(columnDescription), expirationInSeconds) }