-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add timezone getter function in dateTime module [ATLAS-170] #125
base: master
Are you sure you want to change the base?
Changes from 16 commits
803a5fc
a8665df
345bbcb
31116f1
a33b6ed
57de989
3f6669c
438529e
066a321
4e66862
97a5116
7eda595
f669891
eb245c5
7a61e4e
2536c02
7132aa1
df647d6
5a21124
7b786b6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@razorpay/i18nify-js": patch | ||
--- | ||
|
||
feat: add timezone getter function in dateTime module |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { test } from '@playwright/test'; | ||
import { getTimeZoneByCountry } from '../index'; | ||
import { assertScriptText, injectScript } from '../../../blackbox/utils'; | ||
|
||
test.describe('getTimeZoneByCountry', () => { | ||
test.beforeEach(async ({ page }) => { | ||
await page.exposeFunction('getTimeZoneByCountry', getTimeZoneByCountry); | ||
}); | ||
|
||
test('should print the correct timezone of a country capital from countries meta data', async ({ | ||
page, | ||
}) => { | ||
await injectScript( | ||
page, | ||
`await getTimeZoneByCountry('AF').then(res => res)`, | ||
); | ||
|
||
await assertScriptText(page, 'Asia/Kabul'); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { getTimeZoneByCountry } from '../index'; | ||
import { COUNTRIES_METADATA } from '../mocks/country'; | ||
import { CountryMetaType } from '../types'; | ||
|
||
type MockResponse = { | ||
metadata_information: Record<string, CountryMetaType>; | ||
}; | ||
|
||
global.fetch = jest.fn(() => | ||
Promise.resolve({ | ||
ok: true, | ||
status: 200, | ||
json: () => Promise.resolve<MockResponse>(COUNTRIES_METADATA as any), | ||
} as Response), | ||
); | ||
|
||
describe('getTimeZoneByCountry', () => { | ||
it('fetches country metadata correctly', async () => { | ||
const timeZoneAF = await getTimeZoneByCountry('AF'); | ||
expect(timeZoneAF).toBe('Asia/Kabul'); | ||
|
||
const timeZoneIN = await getTimeZoneByCountry('IN'); | ||
expect(timeZoneIN).toBe('Asia/Kolkata'); | ||
}); | ||
|
||
it('handles API errors', async () => { | ||
global.fetch = jest.fn(() => Promise.reject('API Error')); | ||
await expect(getTimeZoneByCountry('XYZ')).rejects.toThrow( | ||
'Error in API response', | ||
); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { test } from '@playwright/test'; | ||
import { getTimezoneList } from '../index'; | ||
import { assertScriptText, injectScript } from '../../../blackbox/utils'; | ||
|
||
test.describe('getTimezoneList', () => { | ||
test.beforeEach(async ({ page }) => { | ||
await page.exposeFunction('getTimezoneList', getTimezoneList); | ||
}); | ||
|
||
test('should print the correct timezone of a country capital from countries meta data', async ({ | ||
page, | ||
}) => { | ||
await injectScript( | ||
page, | ||
`await getTimezoneList().then(res => res.AF.timezone_of_capital)`, | ||
); | ||
|
||
await assertScriptText(page, 'Asia/Kabul'); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { getTimezoneList } from '../index'; | ||
import { COUNTRIES_METADATA } from '../mocks/country'; | ||
import { CountryMetaType } from '../types'; | ||
|
||
type MockResponse = { | ||
metadata_information: Record<string, CountryMetaType>; | ||
}; | ||
|
||
global.fetch = jest.fn(() => | ||
Promise.resolve({ | ||
ok: true, | ||
status: 200, | ||
json: () => Promise.resolve<MockResponse>(COUNTRIES_METADATA as any), | ||
} as Response), | ||
); | ||
|
||
describe('getTimezoneList', () => { | ||
it('fetches country metadata correctly', async () => { | ||
const expectedTimezoneListObj = { | ||
AF: { | ||
timezone_of_capital: 'Asia/Kabul', | ||
timezones: { | ||
'Asia/Kabul': { | ||
utc_offset: 'UTC +04:30', | ||
}, | ||
}, | ||
}, | ||
IN: { | ||
timezone_of_capital: 'Asia/Kolkata', | ||
timezones: { | ||
'Asia/Kolkata': { | ||
utc_offset: 'UTC +05:30', | ||
}, | ||
}, | ||
}, | ||
}; | ||
const timeZoneList = await getTimezoneList(); | ||
expect(timeZoneList).toEqual(expectedTimezoneListObj); | ||
}); | ||
|
||
it('handles API errors', async () => { | ||
global.fetch = jest.fn(() => Promise.reject('API Error')); | ||
await expect(getTimezoneList()).rejects.toThrow('Error in API response'); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { withErrorBoundary } from '../../common/errorBoundary'; | ||
import { I18NIFY_DATA_SOURCE } from './constants'; | ||
|
||
/** | ||
* Asynchronously retrieves the timezone of the capital city for a given country code. | ||
* | ||
* @param countryCode The country code for which the timezone of the capital city is requested. | ||
* @returns A promise that resolves to the timezone of the capital city for the specified country code. | ||
* @throws Error if the country code is not found in the dynamically imported dataset or if there's an API response error. | ||
*/ | ||
const getTimeZoneByCountry = async (countryCode: string): Promise<string> => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's return timezone list too ? |
||
try { | ||
const response = await fetch( | ||
`${I18NIFY_DATA_SOURCE}/country/metadata/data.json`, | ||
); | ||
const data = await response.json(); | ||
|
||
const timezone = | ||
data.metadata_information[countryCode]?.timezone_of_capital; | ||
|
||
if (!timezone) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will this error be reported in catch block of promise ?
|
||
throw new Error(`Invalid countryCode: ${countryCode}`); | ||
} | ||
|
||
return timezone; | ||
} catch (err) { | ||
throw new Error(`Error in API response: ${(err as Error).message}`); | ||
} | ||
}; | ||
|
||
export default withErrorBoundary<typeof getTimeZoneByCountry>( | ||
getTimeZoneByCountry, | ||
); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { withErrorBoundary } from '../../common/errorBoundary'; | ||
import { I18NIFY_DATA_SOURCE } from './constants'; | ||
import { CountryDataApiResponse, CountryMetaType } from './types'; | ||
|
||
/** | ||
* Dynamically imports country data and extracts timezone information for each country. | ||
* | ||
* This function transforms the imported COUNTRY_DATA dataset to a map where each key is a country code, | ||
* associated with an object that includes the timezones (an object with timezone names as keys | ||
* and their utc_offset as values) and the timezone_of_capital (the timezone in which the capital city resides). | ||
* | ||
* @returns A Promise that resolves to a map with country codes as keys and their respective timezone information. | ||
*/ | ||
const getTimezoneList = async (): Promise<Record<string, CountryMetaType>> => { | ||
try { | ||
const response = await fetch( | ||
`${I18NIFY_DATA_SOURCE}/country/metadata/data.json`, | ||
); | ||
const data: CountryDataApiResponse = await response.json(); | ||
|
||
return Object.entries(data.metadata_information).reduce( | ||
(acc, [countryCode, countryMetadata]) => ({ | ||
...acc, | ||
[countryCode]: { | ||
timezones: countryMetadata.timezones, | ||
timezone_of_capital: countryMetadata.timezone_of_capital, | ||
}, | ||
}), | ||
{}, | ||
); | ||
} catch (err) { | ||
throw new Error(`Error in API response: ${(err as Error).message}`); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will it always have message attribute ? |
||
} | ||
}; | ||
|
||
export default withErrorBoundary<typeof getTimezoneList>(getTimezoneList); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not return
timezones
too ?