Skip to content

Commit

Permalink
chore(cache): add cache duration to 1h
Browse files Browse the repository at this point in the history
  • Loading branch information
FranceBe committed Jul 24, 2024
1 parent c24b45c commit 6b02d40
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 10 deletions.
10 changes: 7 additions & 3 deletions src/hooks/useFetchEligibility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ApiConfig, statusResponse, ConfigPlan, EligibilityPlan } from 'types'
import { fetchFromApi } from 'utils/fetch'
import filterEligibility from 'utils/filterEligibility'
import { useSessionStorage } from 'hooks/useSessionStorage'
import { isMoreThanOneHourAgo } from '../utils/utilsForStorage'

const useFetchEligibility = (
purchaseAmount: number,
Expand All @@ -22,7 +23,10 @@ const useFetchEligibility = (
customerBillingCountry,
customerShippingCountry,
})
const currentCache = getCache(key)
const currentCache = getCache(key)?.value
const lastCacheTimestamp = getCache(key)?.timestamp
// If the stored date is more than an hour ago, we should invalidate the cache
const shouldInvalidate = lastCacheTimestamp && isMoreThanOneHourAgo(lastCacheTimestamp)

const configInstallments = plans?.map((plan) => ({
installments_count: plan.installmentsCount,
Expand All @@ -44,12 +48,12 @@ const useFetchEligibility = (
country: customerShippingCountry,
}
}
if (currentCache) {
if (currentCache && !shouldInvalidate) {
setEligibility(currentCache)
setStatus(statusResponse.SUCCESS)
}

if (!currentCache) {
if (!currentCache || shouldInvalidate) {
fetchFromApi(
domain + '/v2/payments/eligibility',
{
Expand Down
12 changes: 10 additions & 2 deletions src/hooks/useSessionStorage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ describe('useSessionStorage', () => {
act(() => result.current.setCache('someKey', mockButtonPlans))

// We check that storage has been updated
expect(result.current.getCache('someKey')).toStrictEqual(mockButtonPlans)
expect(result.current.getCache('someKey')).toStrictEqual({
value: mockButtonPlans,
// Date.now() is mocked to return 1638350762000 in setupTests.ts
timestamp: 1638350762000,
})

// We set another value for the another key
act(() => result.current.setCache('otherKey', [mockButtonPlans[0]]))
Expand All @@ -47,7 +51,11 @@ describe('useSessionStorage', () => {
// We check that storage is empty again for this key
expect(result.current.getCache('someKey')).toEqual(null)
// But it's still filled for the other key
expect(result.current.getCache('otherKey')).toStrictEqual([mockButtonPlans[0]])
expect(result.current.getCache('otherKey')).toStrictEqual({
value: [mockButtonPlans[0]],
// Date.now() is mocked to return 1638350762000 in setupTests.ts
timestamp: 1638350762000,
})

// We clean the storage
act(() => result.current.clearCache())
Expand Down
14 changes: 10 additions & 4 deletions src/hooks/useSessionStorage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@ type CreateKeyType = {
customerShippingCountry?: string
}

type StorageType = {
value: EligibilityPlan[]
timestamp: number
}

type UseSessionStorageType = {
getCache: (key: string) => EligibilityPlan[] | null
getCache: (key: string) => StorageType | null
setCache: (key: string, value: EligibilityPlan[]) => void
clearCache: () => void
deleteCache: (key: string) => void
Expand All @@ -18,11 +23,12 @@ type UseSessionStorageType = {

export const useSessionStorage: () => UseSessionStorageType = () => {
const setCache = (key: string, value: EligibilityPlan[]) => {
// Save data to sessionStorage
sessionStorage.setItem(key, JSON.stringify(value))
// Save data to sessionStorage and create timestamp
const timestamp = Date.now()
sessionStorage.setItem(key, JSON.stringify({ value, timestamp }))
}

const getCache = (key: string): EligibilityPlan[] | null => {
const getCache = (key: string): StorageType | null => {
// Get saved data from sessionStorage
const stringData = sessionStorage.getItem(key) || ''
// Parse cached data to use it directly as an array of EligibilityPlan
Expand Down
14 changes: 13 additions & 1 deletion src/utils/utilsForStorage.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { hashStringForStorage } from 'utils/utilsForStorage'
import { hashStringForStorage, isMoreThanOneHourAgo } from 'utils/utilsForStorage'

describe('utilsForStorage', () => {
describe('hashStringForStorage', () => {
Expand All @@ -12,4 +12,16 @@ describe('utilsForStorage', () => {
expect(hash).toBe(result)
})
})
describe('isMoreThanOneHourAgo', () => {
it('should return true if the timestamp is more than one hour ago', () => {
const date = Date.now() - 1000 * 60 * 60 - 1
const result = isMoreThanOneHourAgo(date)
expect(result).toBe(true)
})
it('should return false if the timestamp is less than one hour ago', () => {
const date = Date.now() - 1000
const result = isMoreThanOneHourAgo(date)
expect(result).toBe(false)
})
})
})
8 changes: 8 additions & 0 deletions src/utils/utilsForStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,11 @@ export const hashStringForStorage = (str: string): string => {
.replace('-', 'A')
) // If the hash is negative (which is represented by a leading '-'), it's replaced with 'A' to ensure the hash is alphanumeric.
}

export const isMoreThanOneHourAgo = (date: number): boolean => {
const ONE_HOUR_IN_MILLISECONDS = 1000 * 60 * 60
const currentTime = Date.now()
const difference = currentTime - date

return difference >= ONE_HOUR_IN_MILLISECONDS
}

0 comments on commit 6b02d40

Please sign in to comment.