diff --git a/.eslintrc.js b/.eslintrc.js
index f2f614a..23a8334 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,9 +1,15 @@
module.exports = {
- extends: ['airbnb-typescript'],
+ extends: [
+ 'airbnb-typescript',
+ 'plugin:jest/recommended'
+ ],
parserOptions: {
- project: `./tsconfig.json`
+ project: `./tsconfig.json`,
},
rules: {
- '@typescript-eslint/semi': ['error', 'never']
- }
+ '@typescript-eslint/semi': ['error', 'never'],
+ 'jest/no-mocks-import': [0],
+ 'max-len': [1, 110],
+ 'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx'] }],
+ },
}
diff --git a/package.json b/package.json
index 7fbe3f9..6f62039 100644
--- a/package.json
+++ b/package.json
@@ -39,6 +39,7 @@
"eslint": "^7.19.0",
"eslint-config-airbnb-typescript": "^12.0.0",
"eslint-plugin-import": "^2.22.0",
+ "eslint-plugin-jest": "^24.1.3",
"eslint-plugin-jsx-a11y": "^6.3.1",
"eslint-plugin-react": "^7.20.3",
"eslint-plugin-react-hooks": "^4.0.8",
diff --git a/src/__mocks__/AsyncStorage.js b/src/__mocks__/AsyncStorage.js
index 254b7ac..b03ded4 100644
--- a/src/__mocks__/AsyncStorage.js
+++ b/src/__mocks__/AsyncStorage.js
@@ -13,5 +13,10 @@ export default (init = {}, delay = 0) => {
await pause(delay)
cache[key] = val
}
- return { getItem, setItem, cache }
+ const clear = () => {
+ Object.keys(cache).forEach((key) => { cache[key] = undefined })
+ }
+ return {
+ getItem, setItem, cache, clear,
+ }
}
diff --git a/src/fake.test.js b/src/fake.test.js
new file mode 100644
index 0000000..a9dc29a
--- /dev/null
+++ b/src/fake.test.js
@@ -0,0 +1,146 @@
+import React from 'react'
+import { act, renderHook } from '@testing-library/react-hooks'
+import { ApiProvider } from '.'
+import createStorage from './__mocks__/AsyncStorage'
+import {
+ useCalendar,
+ useChildList,
+ useClassmates,
+ useMenu,
+ useNews,
+ useNotifications,
+ useSchedule,
+ useUser,
+} from './hooks'
+
+const { default: init } = jest.requireActual('@skolplattformen/embedded-api')
+
+describe('hooks with fake data', () => {
+ let api
+ let storage
+ const wrapper = ({ children }) => (
+ {children}
+ )
+ beforeEach(async () => {
+ api = init(() => { }, () => { })
+ await api.login('121212121212')
+
+ storage = createStorage({})
+ })
+ it('returns user', async () => {
+ await act(async () => {
+ const {
+ result,
+ waitForNextUpdate,
+ } = renderHook(() => useUser(), { wrapper })
+
+ await waitForNextUpdate()
+ await waitForNextUpdate()
+
+ expect(result.current.data).toEqual({
+ firstName: 'Namn',
+ lastName: 'Namnsson',
+ })
+ })
+ })
+ it('returns child list', async () => {
+ await act(async () => {
+ const {
+ result,
+ waitForNextUpdate,
+ } = renderHook(() => useChildList(), { wrapper })
+
+ await waitForNextUpdate()
+ await waitForNextUpdate()
+
+ expect(result.current.data).toHaveLength(2)
+ })
+ })
+ describe('data belonging to one child', () => {
+ let child
+ beforeAll(async () => {
+ [child] = await api.getChildren()
+ })
+ it('returns calendar', async () => {
+ await act(async () => {
+ const {
+ result,
+ waitForNextUpdate,
+ } = renderHook(() => useCalendar(child), { wrapper })
+
+ await waitForNextUpdate()
+ await waitForNextUpdate()
+
+ expect(result.current.data.length).toBeGreaterThan(1)
+ })
+ })
+ it('returns classmates', async () => {
+ await act(async () => {
+ const {
+ result,
+ waitForNextUpdate,
+ } = renderHook(() => useClassmates(child), { wrapper })
+
+ await waitForNextUpdate()
+ await waitForNextUpdate()
+
+ expect(result.current.data.length).toBeGreaterThan(1)
+ })
+ })
+ it('returns menu', async () => {
+ await act(async () => {
+ const {
+ result,
+ waitForNextUpdate,
+ } = renderHook(() => useMenu(child), { wrapper })
+
+ await waitForNextUpdate()
+ await waitForNextUpdate()
+
+ expect(result.current.data.length).toBeGreaterThan(1)
+ })
+ })
+ it('returns news', async () => {
+ await act(async () => {
+ const {
+ result,
+ waitForNextUpdate,
+ } = renderHook(() => useNews(child), { wrapper })
+
+ await waitForNextUpdate()
+ await waitForNextUpdate()
+
+ expect(result.current.data.length).toBeGreaterThan(1)
+ })
+ })
+ it('returns notifications', async () => {
+ await act(async () => {
+ const {
+ result,
+ waitForNextUpdate,
+ } = renderHook(() => useNotifications(child), { wrapper })
+
+ await waitForNextUpdate()
+ await waitForNextUpdate()
+
+ expect(result.current.data.length).toBeGreaterThan(1)
+ })
+ })
+ it('returns schedule', async () => {
+ const from = '2021-01-01'
+ const to = '2021-01-08'
+ await act(async () => {
+ const {
+ result,
+ waitForNextUpdate,
+ } = renderHook(() => useSchedule(child, from, to), { wrapper })
+
+ await waitForNextUpdate()
+ await waitForNextUpdate()
+
+ // No fake schedule in embedded-api yet
+ expect(result.current.data.length).not.toBeGreaterThan(1)
+ })
+ })
+ })
+})
diff --git a/src/useCalendar.test.js b/src/useCalendar.test.js
index a64deb3..bc8f198 100644
--- a/src/useCalendar.test.js
+++ b/src/useCalendar.test.js
@@ -6,26 +6,26 @@ import store from './store'
import init from './__mocks__/@skolplattformen/embedded-api'
import createStorage from './__mocks__/AsyncStorage'
-const pause = (ms = 0) => new Promise(r => setTimeout(r, ms))
+const pause = (ms = 0) => new Promise((r) => setTimeout(r, ms))
describe('useCalendar(child)', () => {
let api
let storage
- let result
+ let response
let child
const wrapper = ({ children }) => (
{children}
)
beforeEach(() => {
- result = [{ id: 1 }]
+ response = [{ id: 1 }]
api = init()
api.getCalendar.mockImplementation(() => (
new Promise((res) => {
- setTimeout(() => res(result), 50)
+ setTimeout(() => res(response), 50)
})
))
storage = createStorage({
- calendar_10: [{ id: 2 }]
+ calendar_10: [{ id: 2 }],
}, 2)
child = { id: 10 }
})
@@ -69,7 +69,7 @@ describe('useCalendar(child)', () => {
expect(result.current.status).toEqual('loaded')
})
})
- it('calls cache', async () => {
+ it('retrieves data from cache', async () => {
await act(async () => {
api.isLoggedIn = true
const { result, waitForNextUpdate } = renderHook(() => useCalendar(child), { wrapper })
@@ -80,6 +80,18 @@ describe('useCalendar(child)', () => {
expect(result.current.data).toEqual([{ id: 2 }])
})
})
+ it('works when cache is empty', async () => {
+ storage.clear()
+ await act(async () => {
+ api.isLoggedIn = true
+ const { result, waitForNextUpdate } = renderHook(() => useCalendar(child), { wrapper })
+
+ await waitForNextUpdate()
+ await waitForNextUpdate()
+
+ expect(result.current.data).toEqual([{ id: 1 }])
+ })
+ })
it('updates status to loading', async () => {
await act(async () => {
api.isLoggedIn = true
@@ -115,7 +127,7 @@ describe('useCalendar(child)', () => {
await waitForNextUpdate()
await pause(20)
- expect(storage.cache['calendar_10']).toEqual('[{"id":1}]')
+ expect(storage.cache.calendar_10).toEqual('[{"id":1}]')
})
})
it('does not store in cache if fake', async () => {
@@ -130,7 +142,7 @@ describe('useCalendar(child)', () => {
await waitForNextUpdate()
await pause(20)
- expect(storage.cache['calendar_10']).toEqual('[{"id":2}]')
+ expect(storage.cache.calendar_10).toEqual('[{"id":2}]')
})
})
})
diff --git a/src/useChildlist.test.js b/src/useChildlist.test.js
index 87c3be2..96a0f0c 100644
--- a/src/useChildlist.test.js
+++ b/src/useChildlist.test.js
@@ -6,25 +6,25 @@ import store from './store'
import init from './__mocks__/@skolplattformen/embedded-api'
import createStorage from './__mocks__/AsyncStorage'
-const pause = (ms = 0) => new Promise(r => setTimeout(r, ms))
+const pause = (ms = 0) => new Promise((r) => setTimeout(r, ms))
describe('useChildList()', () => {
let api
let storage
- let result
+ let response
const wrapper = ({ children }) => (
{children}
)
beforeEach(() => {
- result = [{ id: 1 }]
+ response = [{ id: 1 }]
api = init()
api.getChildren.mockImplementation(() => (
new Promise((res) => {
- setTimeout(() => res(result), 50)
+ setTimeout(() => res(response), 50)
})
))
storage = createStorage({
- children: [{ id: 2 }]
+ children: [{ id: 2 }],
}, 2)
})
afterEach(async () => {
@@ -113,7 +113,7 @@ describe('useChildList()', () => {
await waitForNextUpdate()
await pause(20)
- expect(storage.cache['children']).toEqual('[{"id":1}]')
+ expect(storage.cache.children).toEqual('[{"id":1}]')
})
})
it('does not store in cache if fake', async () => {
@@ -128,7 +128,7 @@ describe('useChildList()', () => {
await waitForNextUpdate()
await pause(20)
- expect(storage.cache['children']).toEqual('[{"id":2}]')
+ expect(storage.cache.children).toEqual('[{"id":2}]')
})
})
})
diff --git a/src/useClassmates.test.js b/src/useClassmates.test.js
index abb4a69..6e116d7 100644
--- a/src/useClassmates.test.js
+++ b/src/useClassmates.test.js
@@ -6,26 +6,26 @@ import store from './store'
import init from './__mocks__/@skolplattformen/embedded-api'
import createStorage from './__mocks__/AsyncStorage'
-const pause = (ms = 0) => new Promise(r => setTimeout(r, ms))
+const pause = (ms = 0) => new Promise((r) => setTimeout(r, ms))
describe('useClassmates(child)', () => {
let api
let storage
- let result
+ let response
let child
const wrapper = ({ children }) => (
{children}
)
beforeEach(() => {
- result = [{ id: 1 }]
+ response = [{ id: 1 }]
api = init()
api.getClassmates.mockImplementation(() => (
new Promise((res) => {
- setTimeout(() => res(result), 50)
+ setTimeout(() => res(response), 50)
})
))
storage = createStorage({
- classmates_10: [{ id: 2 }]
+ classmates_10: [{ id: 2 }],
}, 2)
child = { id: 10 }
})
@@ -115,7 +115,7 @@ describe('useClassmates(child)', () => {
await waitForNextUpdate()
await pause(20)
- expect(storage.cache['classmates_10']).toEqual('[{"id":1}]')
+ expect(storage.cache.classmates_10).toEqual('[{"id":1}]')
})
})
it('does not store in cache if fake', async () => {
@@ -130,7 +130,7 @@ describe('useClassmates(child)', () => {
await waitForNextUpdate()
await pause(20)
- expect(storage.cache['classmates_10']).toEqual('[{"id":2}]')
+ expect(storage.cache.classmates_10).toEqual('[{"id":2}]')
})
})
})
diff --git a/src/useMenu.test.js b/src/useMenu.test.js
index ba53bcd..9be2217 100644
--- a/src/useMenu.test.js
+++ b/src/useMenu.test.js
@@ -6,26 +6,26 @@ import store from './store'
import init from './__mocks__/@skolplattformen/embedded-api'
import createStorage from './__mocks__/AsyncStorage'
-const pause = (ms = 0) => new Promise(r => setTimeout(r, ms))
+const pause = (ms = 0) => new Promise((r) => setTimeout(r, ms))
describe('useMenu(child)', () => {
let api
let storage
- let result
+ let response
let child
const wrapper = ({ children }) => (
{children}
)
beforeEach(() => {
- result = [{ id: 1 }]
+ response = [{ id: 1 }]
api = init()
api.getMenu.mockImplementation(() => (
new Promise((res) => {
- setTimeout(() => res(result), 50)
+ setTimeout(() => res(response), 50)
})
))
storage = createStorage({
- menu_10: [{ id: 2 }]
+ menu_10: [{ id: 2 }],
}, 2)
child = { id: 10 }
})
@@ -115,7 +115,7 @@ describe('useMenu(child)', () => {
await waitForNextUpdate()
await pause(20)
- expect(storage.cache['menu_10']).toEqual('[{"id":1}]')
+ expect(storage.cache.menu_10).toEqual('[{"id":1}]')
})
})
it('does not store in cache if fake', async () => {
@@ -130,7 +130,7 @@ describe('useMenu(child)', () => {
await waitForNextUpdate()
await pause(20)
- expect(storage.cache['menu_10']).toEqual('[{"id":2}]')
+ expect(storage.cache.menu_10).toEqual('[{"id":2}]')
})
})
})
diff --git a/src/useNews.test.js b/src/useNews.test.js
index 61ae9ef..e395386 100644
--- a/src/useNews.test.js
+++ b/src/useNews.test.js
@@ -6,26 +6,26 @@ import store from './store'
import init from './__mocks__/@skolplattformen/embedded-api'
import createStorage from './__mocks__/AsyncStorage'
-const pause = (ms = 0) => new Promise(r => setTimeout(r, ms))
+const pause = (ms = 0) => new Promise((r) => setTimeout(r, ms))
describe('useNews(child)', () => {
let api
let storage
- let result
+ let response
let child
const wrapper = ({ children }) => (
{children}
)
beforeEach(() => {
- result = [{ id: 1 }]
+ response = [{ id: 1 }]
api = init()
api.getNews.mockImplementation(() => (
new Promise((res) => {
- setTimeout(() => res(result), 50)
+ setTimeout(() => res(response), 50)
})
))
storage = createStorage({
- news_10: [{ id: 2 }]
+ news_10: [{ id: 2 }],
}, 2)
child = { id: 10 }
})
@@ -115,7 +115,7 @@ describe('useNews(child)', () => {
await waitForNextUpdate()
await pause(20)
- expect(storage.cache['news_10']).toEqual('[{"id":1}]')
+ expect(storage.cache.news_10).toEqual('[{"id":1}]')
})
})
it('does not store in cache if fake', async () => {
@@ -130,7 +130,7 @@ describe('useNews(child)', () => {
await waitForNextUpdate()
await pause(20)
- expect(storage.cache['news_10']).toEqual('[{"id":2}]')
+ expect(storage.cache.news_10).toEqual('[{"id":2}]')
})
})
})
diff --git a/src/useNotifications.test.js b/src/useNotifications.test.js
index 92f0523..ca37b45 100644
--- a/src/useNotifications.test.js
+++ b/src/useNotifications.test.js
@@ -6,26 +6,26 @@ import store from './store'
import init from './__mocks__/@skolplattformen/embedded-api'
import createStorage from './__mocks__/AsyncStorage'
-const pause = (ms = 0) => new Promise(r => setTimeout(r, ms))
+const pause = (ms = 0) => new Promise((r) => setTimeout(r, ms))
describe('useNotifications(child)', () => {
let api
let storage
- let result
+ let response
let child
const wrapper = ({ children }) => (
{children}
)
beforeEach(() => {
- result = [{ id: 1 }]
+ response = [{ id: 1 }]
api = init()
api.getNotifications.mockImplementation(() => (
new Promise((res) => {
- setTimeout(() => res(result), 50)
+ setTimeout(() => res(response), 50)
})
))
storage = createStorage({
- notifications_10: [{ id: 2 }]
+ notifications_10: [{ id: 2 }],
}, 2)
child = { id: 10 }
})
@@ -115,7 +115,7 @@ describe('useNotifications(child)', () => {
await waitForNextUpdate()
await pause(20)
- expect(storage.cache['notifications_10']).toEqual('[{"id":1}]')
+ expect(storage.cache.notifications_10).toEqual('[{"id":1}]')
})
})
it('does not store in cache if fake', async () => {
@@ -130,7 +130,7 @@ describe('useNotifications(child)', () => {
await waitForNextUpdate()
await pause(20)
- expect(storage.cache['notifications_10']).toEqual('[{"id":2}]')
+ expect(storage.cache.notifications_10).toEqual('[{"id":2}]')
})
})
})
diff --git a/src/useSchedule.test.js b/src/useSchedule.test.js
index 835a953..e275638 100644
--- a/src/useSchedule.test.js
+++ b/src/useSchedule.test.js
@@ -6,12 +6,12 @@ import store from './store'
import init from './__mocks__/@skolplattformen/embedded-api'
import createStorage from './__mocks__/AsyncStorage'
-const pause = (ms = 0) => new Promise(r => setTimeout(r, ms))
+const pause = (ms = 0) => new Promise((r) => setTimeout(r, ms))
describe('useSchedule(child, from, to)', () => {
let api
let storage
- let result
+ let response
let child
let from
let to
@@ -19,15 +19,15 @@ describe('useSchedule(child, from, to)', () => {
{children}
)
beforeEach(() => {
- result = [{ id: 1 }]
+ response = [{ id: 1 }]
api = init()
api.getSchedule.mockImplementation(() => (
new Promise((res) => {
- setTimeout(() => res(result), 50)
+ setTimeout(() => res(response), 50)
})
))
storage = createStorage({
- 'schedule_10_2021-01-01_2021-01-08': [{ id: 2 }]
+ 'schedule_10_2021-01-01_2021-01-08': [{ id: 2 }],
}, 2)
child = { id: 10 }
from = '2021-01-01'
diff --git a/src/useUser.test.js b/src/useUser.test.js
index be644e7..3758897 100644
--- a/src/useUser.test.js
+++ b/src/useUser.test.js
@@ -6,25 +6,25 @@ import store from './store'
import init from './__mocks__/@skolplattformen/embedded-api'
import createStorage from './__mocks__/AsyncStorage'
-const pause = (ms = 0) => new Promise(r => setTimeout(r, ms))
+const pause = (ms = 0) => new Promise((r) => setTimeout(r, ms))
describe('useUser()', () => {
let api
let storage
- let result
+ let response
const wrapper = ({ children }) => (
{children}
)
beforeEach(() => {
- result = { id: 1 }
+ response = { id: 1 }
api = init()
api.getUser.mockImplementation(() => (
new Promise((res) => {
- setTimeout(() => res(result), 50)
+ setTimeout(() => res(response), 50)
})
))
storage = createStorage({
- user: { id: 2 }
+ user: { id: 2 },
}, 2)
})
afterEach(async () => {
@@ -113,7 +113,7 @@ describe('useUser()', () => {
await waitForNextUpdate()
await pause(20)
- expect(storage.cache['user']).toEqual('{"id":1}')
+ expect(storage.cache.user).toEqual('{"id":1}')
})
})
it('does not store in cache if fake', async () => {
@@ -128,7 +128,7 @@ describe('useUser()', () => {
await waitForNextUpdate()
await pause(20)
- expect(storage.cache['user']).toEqual('{"id":2}')
+ expect(storage.cache.user).toEqual('{"id":2}')
})
})
})
diff --git a/yarn.lock b/yarn.lock
index 805750b..cec830c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1400,7 +1400,7 @@
semver "^7.3.2"
tsutils "^3.17.1"
-"@typescript-eslint/experimental-utils@4.14.2":
+"@typescript-eslint/experimental-utils@4.14.2", "@typescript-eslint/experimental-utils@^4.0.1":
version "4.14.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.14.2.tgz#9df35049d1d36b6cbaba534d703648b9e1f05cbb"
integrity sha512-mV9pmET4C2y2WlyHmD+Iun8SAEqkLahHGBkGqDVslHkmoj3VnxnGP4ANlwuxxfq1BsKdl/MPieDbohCEQgKrwA==
@@ -2540,6 +2540,13 @@ eslint-plugin-import@^2.22.0:
resolve "^1.17.0"
tsconfig-paths "^3.9.0"
+eslint-plugin-jest@^24.1.3:
+ version "24.1.3"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-24.1.3.tgz#fa3db864f06c5623ff43485ca6c0e8fc5fe8ba0c"
+ integrity sha512-dNGGjzuEzCE3d5EPZQ/QGtmlMotqnYWD/QpCZ1UuZlrMAdhG5rldh0N0haCvhGnUkSeuORS5VNROwF9Hrgn3Lg==
+ dependencies:
+ "@typescript-eslint/experimental-utils" "^4.0.1"
+
eslint-plugin-jsx-a11y@^6.3.1:
version "6.4.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.4.1.tgz#a2d84caa49756942f42f1ffab9002436391718fd"