feat: 🎸 Multilang support for useTimetable (#14)

* feat: 🎸 Multilang support for useTimetable

BREAKING CHANGE: 🧨 useTimetable now requires lang
This commit is contained in:
Johan Öbrink 2021-04-26 10:47:49 +02:00 committed by GitHub
parent fe1729c872
commit be6c9d1302
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 44 additions and 46 deletions

View File

@ -24,14 +24,16 @@
"redux": "^4.0.5"
},
"peerDependencies": {
"@skolplattformen/embedded-api": "^4.0.0",
"@skolplattformen/curriculum": "^1.3.0",
"@skolplattformen/embedded-api": "^5.1.0",
"react": "^16.11.0"
},
"devDependencies": {
"@babel/preset-env": "^7.13.15",
"@babel/preset-react": "^7.13.13",
"@babel/preset-typescript": "^7.13.0",
"@skolplattformen/embedded-api": "^4.0.0",
"@skolplattformen/curriculum": "^1.3.0",
"@skolplattformen/embedded-api": "^5.1.0",
"@testing-library/jest-dom": "^5.11.10",
"@testing-library/react": "^11.2.6",
"@testing-library/react-hooks": "^5.1.1",

View File

@ -45,6 +45,7 @@ describe('hooks with fake data', () => {
expect(result.current.data).toEqual({
firstName: 'Namn',
lastName: 'Namnsson',
isAuthenticated: true,
})
})
})
@ -61,6 +62,7 @@ describe('hooks with fake data', () => {
expect(result.current.data).toEqual({
firstName: 'Namn',
lastName: 'Namnsson',
isAuthenticated: true,
})
})
})

View File

@ -15,6 +15,7 @@ import {
User,
} from '@skolplattformen/embedded-api'
import { DateTime } from 'luxon'
import { Language } from '@skolplattformen/curriculum/dist/translations'
import {
ApiCall,
EntityHookResult,
@ -179,12 +180,14 @@ export const useSchedule = (child: Child, from: string, to: string) => hook<Sche
(api) => () => api.getSchedule(child, DateTime.fromISO(from), DateTime.fromISO(to)),
)
export const useTimetable = (child: Skola24Child, week: number, year: number) => hook<TimetableEntry[]>(
export const useTimetable = (
child: Skola24Child, week: number, year: number, lang: Language,
) => hook<TimetableEntry[]>(
'TIMETABLE',
`timetable_${child.personGuid}_${week}_${year}`,
`timetable_${child.personGuid}_${week}_${year}_${lang}`,
[],
(s) => s.timetable,
(api) => () => api.getTimetable(child, week, year),
(api) => () => api.getTimetable(child, week, year, lang),
)
export const useUser = () => hook<User>(

View File

@ -9,13 +9,14 @@ import reporter from './__mocks__/reporter'
const pause = (ms = 0) => new Promise((r) => setTimeout(r, ms))
describe('useTimetable(child, week, year)', () => {
describe('useTimetable(child, week, year, lang)', () => {
let api
let storage
let response
let child
let week
let year
let lang
const wrapper = ({ children }) => (
<ApiProvider
api={api}
@ -35,11 +36,12 @@ describe('useTimetable(child, week, year)', () => {
})
))
storage = createStorage({
'123_timetable_10_15_2021': [{ id: 2 }],
'123_timetable_10_15_2021_sv': [{ id: 2 }],
}, 2)
child = { personGuid: '10' }
week = 15
year = 2021
lang = 'sv'
})
afterEach(async () => {
await act(async () => {
@ -48,14 +50,14 @@ describe('useTimetable(child, week, year)', () => {
})
})
it('returns correct initial value', () => {
const { result } = renderHook(() => useTimetable(child, week, year), { wrapper })
const { result } = renderHook(() => useTimetable(child, week, year, lang), { wrapper })
expect(result.current.status).toEqual('pending')
})
it('calls api', async () => {
await act(async () => {
api.isLoggedIn = true
const { waitForNextUpdate } = renderHook(() => useTimetable(child, week, year), { wrapper })
const { waitForNextUpdate } = renderHook(() => useTimetable(child, week, year, lang), { wrapper })
await waitForNextUpdate()
await waitForNextUpdate()
@ -66,16 +68,16 @@ describe('useTimetable(child, week, year)', () => {
it('only calls api once', async () => {
await act(async () => {
api.isLoggedIn = true
renderHook(() => useTimetable(child, week, year), { wrapper })
const { waitForNextUpdate } = renderHook(() => useTimetable(child, week, year), { wrapper })
renderHook(() => useTimetable(child, week, year, lang), { wrapper })
const { waitForNextUpdate } = renderHook(() => useTimetable(child, week, year, lang), { wrapper })
await waitForNextUpdate()
renderHook(() => useTimetable(child, week, year), { wrapper })
renderHook(() => useTimetable(child, week, year, lang), { wrapper })
await waitForNextUpdate()
renderHook(() => useTimetable(child, week, year), { wrapper })
renderHook(() => useTimetable(child, week, year, lang), { wrapper })
await waitForNextUpdate()
const { result } = renderHook(() => useTimetable(child, week, year), { wrapper })
const { result } = renderHook(() => useTimetable(child, week, year, lang), { wrapper })
expect(api.getTimetable).toHaveBeenCalledTimes(1)
expect(result.current.status).toEqual('loaded')
@ -84,7 +86,7 @@ describe('useTimetable(child, week, year)', () => {
it('calls cache', async () => {
await act(async () => {
api.isLoggedIn = true
const { result, waitForNextUpdate } = renderHook(() => useTimetable(child, week, year), { wrapper })
const { result, waitForNextUpdate } = renderHook(() => useTimetable(child, week, year, lang), { wrapper })
await waitForNextUpdate()
await waitForNextUpdate()
@ -95,7 +97,7 @@ describe('useTimetable(child, week, year)', () => {
it('updates status to loading', async () => {
await act(async () => {
api.isLoggedIn = true
const { result, waitForNextUpdate } = renderHook(() => useTimetable(child, week, year), { wrapper })
const { result, waitForNextUpdate } = renderHook(() => useTimetable(child, week, year, lang), { wrapper })
await waitForNextUpdate()
await waitForNextUpdate()
@ -106,7 +108,7 @@ describe('useTimetable(child, week, year)', () => {
it('updates status to loaded', async () => {
await act(async () => {
api.isLoggedIn = true
const { result, waitForNextUpdate } = renderHook(() => useTimetable(child, week, year), { wrapper })
const { result, waitForNextUpdate } = renderHook(() => useTimetable(child, week, year, lang), { wrapper })
await waitForNextUpdate()
await waitForNextUpdate()
@ -120,14 +122,14 @@ describe('useTimetable(child, week, year)', () => {
api.isLoggedIn = true
api.isFake = false
const { waitForNextUpdate } = renderHook(() => useTimetable(child, week, year), { wrapper })
const { waitForNextUpdate } = renderHook(() => useTimetable(child, week, year, lang), { wrapper })
await waitForNextUpdate()
await waitForNextUpdate()
await waitForNextUpdate()
await pause(20)
expect(storage.cache['123_timetable_10_15_2021']).toEqual('[{"id":1}]')
expect(storage.cache['123_timetable_10_15_2021_sv']).toEqual('[{"id":1}]')
})
})
it('does not store in cache if fake', async () => {
@ -135,13 +137,13 @@ describe('useTimetable(child, week, year)', () => {
api.isLoggedIn = true
api.isFake = true
const { waitForNextUpdate } = renderHook(() => useTimetable(child, week, year), { wrapper })
const { waitForNextUpdate } = renderHook(() => useTimetable(child, week, year, lang), { wrapper })
await waitForNextUpdate()
await waitForNextUpdate()
await pause(20)
expect(storage.cache['123_timetable_10_15_2021']).toEqual('[{"id":2}]')
expect(storage.cache['123_timetable_10_15_2021_sv']).toEqual('[{"id":2}]')
})
})
it('retries if api fails', async () => {
@ -150,7 +152,7 @@ describe('useTimetable(child, week, year)', () => {
const error = new Error('fail')
api.getTimetable.mockRejectedValueOnce(error)
const { result, waitForNextUpdate } = renderHook(() => useTimetable(child, week, year), { wrapper })
const { result, waitForNextUpdate } = renderHook(() => useTimetable(child, week, year, lang), { wrapper })
await waitForNextUpdate()
await waitForNextUpdate()
@ -178,7 +180,7 @@ describe('useTimetable(child, week, year)', () => {
api.getTimetable.mockRejectedValueOnce(error)
api.getTimetable.mockRejectedValueOnce(error)
const { result, waitForNextUpdate } = renderHook(() => useTimetable(child, week, year), { wrapper })
const { result, waitForNextUpdate } = renderHook(() => useTimetable(child, week, year, lang), { wrapper })
await waitForNextUpdate()
await waitForNextUpdate()
@ -205,7 +207,7 @@ describe('useTimetable(child, week, year)', () => {
const error = new Error('fail')
api.getTimetable.mockRejectedValueOnce(error)
const { result, waitForNextUpdate } = renderHook(() => useTimetable(child, week, year), { wrapper })
const { result, waitForNextUpdate } = renderHook(() => useTimetable(child, week, year, lang), { wrapper })
await waitForNextUpdate()
await waitForNextUpdate()

View File

@ -1304,19 +1304,23 @@
dependencies:
"@sinonjs/commons" "^1.7.0"
"@skolplattformen/embedded-api@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@skolplattformen/embedded-api/-/embedded-api-4.0.0.tgz#22ff23b12a111dbc92b20ee2017c78d417cd6e7d"
integrity sha512-leVEr1FXD2knV1K9ZT6bNcL+vCiuO+XpzASJAQOtYfgq869wF4Le5taP8N7jzxHh+Mm2hw7CaMsl5DIbL0YfFg==
"@skolplattformen/curriculum@^1.3.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@skolplattformen/curriculum/-/curriculum-1.3.0.tgz#841e2ff0095e39e174cffdd0b8a81a17956de7ed"
integrity sha512-nuwZX45gHe5JaiYfygDP1HmbhAJOEXuuWwR04tNAnl/PaDGqJscfzKt8YD2SL+MHqi3LARjSKLa4ms4SxVQFyw==
"@skolplattformen/embedded-api@^5.1.0":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@skolplattformen/embedded-api/-/embedded-api-5.1.0.tgz#924729bf82aad4e61663f54254b107cd9f6e8812"
integrity sha512-lne82FYZMx+fSJmWKA7gFtdsuL+t28HaRTGoqIZ+8Ys29ypU8uxHR7KMMo7rcykgKEe0ALWF3Vlmr66FrAG4Rg==
dependencies:
"@types/he" "^1.1.1"
camelcase-keys "^6.2.2"
change-case "^4.1.2"
events "^3.2.0"
events "^3.3.0"
h2m "^0.7.0"
he "^1.2.0"
js-htmlencode "^0.3.0"
luxon "^1.25.0"
luxon "^1.26.0"
node-html-parser "^2.1.0"
"@testing-library/dom@^7.28.1":
@ -1412,11 +1416,6 @@
dependencies:
"@types/node" "*"
"@types/he@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@types/he/-/he-1.1.1.tgz#19e14033c4ee8f1a702c74dcc6182664839ac2b7"
integrity sha512-jpzrsR1ns0n3kyWt92QfOUQhIuJGQ9+QGa7M62rO6toe98woQjnsnzjdMtsQXCdvjjmqjS2ZBCC7xKw0cdzU+Q==
"@types/hoist-non-react-statics@^3.3.0":
version "3.3.1"
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz"
@ -3024,11 +3023,6 @@ esutils@^2.0.2:
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz"
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
events@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz"
integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==
events@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
@ -4553,11 +4547,6 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
luxon@^1.25.0:
version "1.25.0"
resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.25.0.tgz#d86219e90bc0102c0eb299d65b2f5e95efe1fe72"
integrity sha512-hEgLurSH8kQRjY6i4YLey+mcKVAWXbDNlZRmM6AgWDJ1cY3atl8Ztf5wEY7VBReFbmGnwQPz7KYJblL8B2k0jQ==
luxon@^1.26.0:
version "1.26.0"
resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.26.0.tgz#d3692361fda51473948252061d0f8561df02b578"