diff --git a/src/infraestructure/hooks/__tests__/useDevices.spec.ts b/src/infraestructure/hooks/__tests__/useDevices.spec.ts index 200439f..b411a80 100644 --- a/src/infraestructure/hooks/__tests__/useDevices.spec.ts +++ b/src/infraestructure/hooks/__tests__/useDevices.spec.ts @@ -5,14 +5,11 @@ import DevicesRepositoryImpl from '../../repositories/DevicesRepositoryImpl'; import mockResponse from '../__mocks__/mockResponse.json'; import {getNumber} from '../../../../__mocks__/@react-native-firebase/remote-config'; +jest.useFakeTimers(); + describe('useDevices tests', () => { beforeEach(() => { jest.clearAllMocks(); - jest.useFakeTimers(); - }); - - afterEach(() => { - jest.useRealTimers(); }); beforeAll(() => { @@ -24,7 +21,7 @@ describe('useDevices tests', () => { { lineNumber: '803010', description: 'Tucapel', - locomotionType: 1, + locomotionType: '1', backgroundColor: 'Hexadecimal', letterColor: 'Hexadecimal', lineMessage: '', @@ -52,7 +49,7 @@ describe('useDevices tests', () => { { lineNumber: '5487', description: 'Centauro', - locomotionType: 1, + locomotionType: '1', backgroundColor: 'Hexadecimal', letterColor: 'Hexadecimal', lineMessage: 'Sin info. GPS, la informacion es estimada', @@ -84,8 +81,6 @@ describe('useDevices tests', () => { stopNumber: '37477', stopName: "O'Higgins - entre Angol y Salas", }); - - getNumber.mockReturnValue(20000).mockReturnValue(60000); }); it('should be defined', () => { @@ -139,7 +134,7 @@ describe('useDevices tests', () => { letterColor: 'Hexadecimal', lineMessage: '', lineNumber: '803010', - locomotionType: 1, + locomotionType: '1', }, { arrivals: [ @@ -167,7 +162,7 @@ describe('useDevices tests', () => { letterColor: 'Hexadecimal', lineMessage: 'Sin info. GPS, la informacion es estimada', lineNumber: '5487', - locomotionType: 1, + locomotionType: '1', }, ]); }); @@ -176,6 +171,7 @@ describe('useDevices tests', () => { }); it('should refresh devices list after 20000 miliseconds', async () => { + getNumber.mockReturnValue(20000); const mockDate = new Date('2023-01-01T00:01:00Z'); const spy = jest.spyOn(global, 'Date').mockImplementation(() => mockDate); jest @@ -188,7 +184,9 @@ describe('useDevices tests', () => { expect(result.current.state.currentIndex).toBe(0); }); - jest.advanceTimersByTime(20000); + act(() => { + jest.advanceTimersByTime(20000); + }); await waitFor(() => { expect(result.current.state.currentIndex).toBe(22); @@ -198,6 +196,7 @@ describe('useDevices tests', () => { }); it('should refresh devices list after 60000 miliseconds', async () => { + getNumber.mockReturnValue(60000); const mockDate = new Date('2023-01-01T00:01:00Z'); const spy = jest.spyOn(global, 'Date').mockImplementation(() => mockDate); const spp = jest.spyOn(DevicesRepositoryImpl.prototype, 'getDeviceInfo'); diff --git a/src/infraestructure/hooks/__tests__/useRemoteconfig.spec.ts b/src/infraestructure/hooks/__tests__/useRemoteconfig.spec.ts index 6e5cf33..76b3c80 100644 --- a/src/infraestructure/hooks/__tests__/useRemoteconfig.spec.ts +++ b/src/infraestructure/hooks/__tests__/useRemoteconfig.spec.ts @@ -48,20 +48,4 @@ describe('useRemoteconfig tests', () => { }); }); }); - - describe('get string', () => { - it('should be defined', async () => { - const {result} = renderHook(() => useRemoteConfig()); - - expect(result.current.getString).toBeDefined(); - }); - - it('should return a value', async () => { - getString.mockReturnValueOnce('someValue'); - - const {result} = renderHook(() => useRemoteConfig()); - - expect(result.current.getString('someKey')).toStrictEqual('someValue'); - }); - }); }); diff --git a/src/infraestructure/hooks/useDevices.ts b/src/infraestructure/hooks/useDevices.ts index e3fc7d3..57e19f0 100644 --- a/src/infraestructure/hooks/useDevices.ts +++ b/src/infraestructure/hooks/useDevices.ts @@ -30,7 +30,7 @@ const useDevices = () => { stopMessage: '', displayedLines: [], lines: [], - stopName: 'Sin información - Sin información', + stopName: '', }); const baseURL = remoteConfig().getString(RemoteConfigKeys.BASE_URL); @@ -180,7 +180,7 @@ const useDevices = () => { status: Status.SUCCESS, }, })); - } catch (error) { + } catch (error: unknown) { setState((prevState: State) => ({ ...prevState, status: Status.ERROR, @@ -199,8 +199,8 @@ const useDevices = () => { authRepository, devicesRepository, password, - username, updateBusesListInterval, + username, ]); useEffect(() => { @@ -212,8 +212,9 @@ const useDevices = () => { const init = () => { setState(prevState => { + const currentIndex = prevState.currentIndex || 1; const isGreatherThanLinesLength = - (prevState.currentIndex || 1) + BUSES_BY_PAGE >= state.lines.length; + currentIndex + BUSES_BY_PAGE >= state.lines.length; return { ...prevState, @@ -224,7 +225,7 @@ const useDevices = () => { }; }); - setTimeout(init, changePageInterval); + timeout = setTimeout(init, changePageInterval); }; init(); @@ -232,7 +233,7 @@ const useDevices = () => { return () => { clearTimeout(timeout); }; - }, [state.lines, state.status, changePageInterval]); + }, [changePageInterval, state.lines.length]); return {state}; }; diff --git a/src/infraestructure/hooks/useRemoteConfig.ts b/src/infraestructure/hooks/useRemoteConfig.ts index 58476fe..42566f5 100644 --- a/src/infraestructure/hooks/useRemoteConfig.ts +++ b/src/infraestructure/hooks/useRemoteConfig.ts @@ -1,4 +1,4 @@ -import {useCallback, useEffect, useState} from 'react'; +import {useEffect, useState} from 'react'; import remoteConfig from '@react-native-firebase/remote-config'; import Status from '../../utils/Status'; @@ -7,11 +7,6 @@ const ONE_HOUR = 3600000; const useRemoteConfig = () => { const [status, setStatus] = useState(Status.LOADING); - const getString = useCallback( - (key: string) => remoteConfig().getString(key), - [], - ); - useEffect(() => { const init = async () => { try { @@ -29,11 +24,9 @@ const useRemoteConfig = () => { UPDATE_BUSES_LIST_INTERVAL: 0, // in miliseconds }); - const isActivated = await remoteConfig().fetchAndActivate(); + await remoteConfig().fetchAndActivate(); - if (isActivated) { - setStatus(Status.SUCCESS); - } + setStatus(Status.SUCCESS); } catch (error) { setStatus(Status.ERROR); } @@ -42,7 +35,7 @@ const useRemoteConfig = () => { init(); }, []); - return {status, getString}; + return {status}; }; export default useRemoteConfig; diff --git a/src/presentation/components/BusList.tsx b/src/presentation/components/BusList.tsx index 6f1f018..1dfb634 100644 --- a/src/presentation/components/BusList.tsx +++ b/src/presentation/components/BusList.tsx @@ -19,17 +19,33 @@ const ERROR_MESSAGE = 'Ha ocurrido un error'; const EMPTY_MESSAGE = 'No buses available'; const BusList = ({buses, status, style}: BusListProps) => { + if (status === Status.LOADING) { + return ( + + + + ); + } + + if (status === Status.ERROR) { + return ( + + {ERROR_MESSAGE} + + ); + } + + if (status === Status.SUCCESS && buses.length === 0) { + return ( + + {EMPTY_MESSAGE} + + ); + } + return ( - {status === Status.LOADING && } - {status === Status.ERROR && ( - {ERROR_MESSAGE} - )} - {status === Status.SUCCESS && buses.length === 0 ? ( - {EMPTY_MESSAGE} - ) : ( - - )} +
); }; diff --git a/src/presentation/components/Header.tsx b/src/presentation/components/Header.tsx index 907672f..131768e 100644 --- a/src/presentation/components/Header.tsx +++ b/src/presentation/components/Header.tsx @@ -36,8 +36,8 @@ const Header = ({title, subTitle, style, image}: HeaderProps) => { }; const defaultProps = { - title: 'Sin información', - subTitle: 'Sin información', + title: '', + subTitle: '', }; Header.defaultProps = defaultProps; diff --git a/src/presentation/components/__tests__/__snapshots__/BusList.spec.tsx.snap b/src/presentation/components/__tests__/__snapshots__/BusList.spec.tsx.snap index 2f67b45..672fef8 100644 --- a/src/presentation/components/__tests__/__snapshots__/BusList.spec.tsx.snap +++ b/src/presentation/components/__tests__/__snapshots__/BusList.spec.tsx.snap @@ -5,288 +5,6 @@ exports[`BusList tests should render correctly with status LOADING 1`] = ` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - `; diff --git a/src/presentation/screens/App.tsx b/src/presentation/screens/App.tsx index 2ca278a..54b0c04 100644 --- a/src/presentation/screens/App.tsx +++ b/src/presentation/screens/App.tsx @@ -1,7 +1,28 @@ -import {SafeAreaView, StyleSheet} from 'react-native'; +import {ActivityIndicator, SafeAreaView, StyleSheet, Text} from 'react-native'; import BusStopInfoScreen from './BusStopInfoScreen'; +import useRemoteConfig from '../../infraestructure/hooks/useRemoteConfig'; +import Status from '../../utils/Status'; + +const ERROR_MESSAGE = 'Ha ocurrido un error'; const App = () => { + const {status} = useRemoteConfig(); + + if (status === Status.LOADING) { + return ( + + + + ); + } + + if (status === Status.ERROR) { + return ( + + {ERROR_MESSAGE} + + ); + } return ( @@ -13,6 +34,11 @@ const styles = StyleSheet.create({ container: { flex: 1, }, + centeredContainer: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, }); export default App; diff --git a/src/presentation/screens/BusStopInfoScreen.tsx b/src/presentation/screens/BusStopInfoScreen.tsx index 44136cc..09f51fb 100644 --- a/src/presentation/screens/BusStopInfoScreen.tsx +++ b/src/presentation/screens/BusStopInfoScreen.tsx @@ -1,43 +1,25 @@ -import {ActivityIndicator, Image, StyleSheet, Text, View} from 'react-native'; +import {Image, StyleSheet, View} from 'react-native'; +import remoteConfig from '@react-native-firebase/remote-config'; import Container from '../components/Container'; import Header from '../components/Header'; import useDevices from '../../infraestructure/hooks/useDevices'; import Banner from '../components/Banner'; import RemoteConfigKeys from '../../utils/RemoteConfigKeys'; import BusList from '../components/BusList'; -import useRemoteConfig from '../../infraestructure/hooks/useRemoteConfig'; -import Status from '../../utils/Status'; const BANNER_TEXT = 'Buses que se detienen en esta parada'; -const ERROR_MESSAGE = 'Ha ocurrido un error'; const BusStopInfoScreen = () => { const { state: {status, displayedLines, stopName}, } = useDevices(); - const {status: remoteConfigStatus, getString} = useRemoteConfig(); - const image = getString(RemoteConfigKeys.HEADER_IMAGE_URL); + const image = remoteConfig().getString(RemoteConfigKeys.HEADER_IMAGE_URL); + const [first, second] = stopName.split('-'); const title = first ? first.trim() : ''; const subTitle = second ? second.trim() : ''; - if (remoteConfigStatus === Status.LOADING) { - return ( - - - - ); - } - - if (remoteConfigStatus === Status.ERROR) { - return ( - - {ERROR_MESSAGE} - - ); - } - return (
{ jest.spyOn(useDevices, 'default').mockReturnValue({ state: mockState, }); + getString.mockReturnValue('https://www.google.com'); }); it('should be defined', () => { @@ -585,7 +587,6 @@ describe('BusStopInfoScreen tests', () => { it('should render the screen with status loading', () => { jest.spyOn(useRemoteConfig, 'default').mockReturnValue({ status: 0, - getString: () => 'https://www.google.com', }); const {toJSON} = render(); @@ -595,7 +596,6 @@ describe('BusStopInfoScreen tests', () => { it('should render the screen with status error', () => { jest.spyOn(useRemoteConfig, 'default').mockReturnValue({ status: 2, - getString: () => 'https://www.google.com', }); const {toJSON} = render(); @@ -606,7 +606,6 @@ describe('BusStopInfoScreen tests', () => { it('should render the screen with status success', () => { jest.spyOn(useRemoteConfig, 'default').mockReturnValue({ status: 1, - getString: () => 'https://www.google.com', }); const {toJSON} = render(); diff --git a/src/presentation/screens/__tests__/__snapshots__/BusStopInfoScreen.spec.tsx.snap b/src/presentation/screens/__tests__/__snapshots__/BusStopInfoScreen.spec.tsx.snap index 48b809a..d5bfe13 100644 --- a/src/presentation/screens/__tests__/__snapshots__/BusStopInfoScreen.spec.tsx.snap +++ b/src/presentation/screens/__tests__/__snapshots__/BusStopInfoScreen.spec.tsx.snap @@ -8,15 +8,2554 @@ exports[`BusStopInfoScreen tests should render the screen with status error 1`] "flex": 1, }, { - "alignItems": "center", "justifyContent": "center", }, ] } > - - Ha ocurrido un error - + + + + + + + + O'Higgins + + + esq. Salas + + + + + + + Buses que se detienen en esta parada + + + + + + + + + 10 + + + + N + + + + + + Vía Láctea + + + Los Bloques + + + Más de 10 minutos + + + + + + + 10 + + + + P + + + + + + Vía Láctea + + + Leonera + + + Más de 10 minutos + + + + + + + 10 + + + + L + + + + + + Vía Láctea + + + Los Bloques + + + Más de 10 minutos + + + + + + + + + 11 + + + + Q + + + + + + Vía Futuro + + + Los Bloques + + + Más de 10 minutos + + + + + + + 11 + + + + R + + + + + + Vía Futuro + + + Porvenir + + + Más de 10 minutos + + + + + + + 13 + + + + S + + + + + + Vía Siglo XXI + + + Leonera + + + Más de 10 minutos + + + + + + + + + 14 + + + + T + + + + + + Chiguayante Sur + + + Coquimbo + + + Más de 10 minutos + + + + + + + 14 + + + + U + + + + + + Chiguayante Sur + + + Los Altos + + + Más de 10 minutos + + + + + + + 16 + + + + K + + + + + + Vía Universo + + + Leonera + + + Más de 10 minutos + + + + + + + + + 16 + + + + V + + + + + + Vía Universo + + + Leonera + + + Más de 10 minutos + + + + + + + 17 + + + + W + + + + + + Expresos Chiguayante + + + Leonera + + + Más de 10 minutos + + + + + + + 17 + + + + X + + + + + + Expresos Chiguayante + + + Leonera + + + Más de 10 minutos + + + + + + + + + 18 + + + + Y + + + + + + Buses Palomares + + + Hualqui + + + Más de 10 minutos + + + + + + + 20 + + + + M + + + + + + Nueva Llacolén + + + San Pedro Costa + + + Más de 10 minutos + + + + + + + 20 + + + + A + + + + + + Nueva Llacolén + + + Boca Sur + + + Más de 10 minutos + + + + + + + + + 24 + + + + F + + + + + + San Remo + + + Candelaria + + + Más de 10 minutos + + + + + + + 30 + + + + Q + + + + + + Ruta Las Playas + + + Higueras + + + Más de 10 minutos + + + + + + + 30 + + + + R + + + + + + Ruta Las Playas + + + Higueras + + + Más de 10 minutos + + + + + + + + + 57 + + + + P + + + + + + Denavi Sur + + + San Vicente + + + Más de 10 minutos + + + + + + + 31 + + + + D + + + + + + Ruta del Mar + + + Lobos Viejos + + + Más de 10 minutos + + + + + + + 40 + + + + G + + + + + + Las Golondrinas + + + Candelaria + + + Más de 10 minutos + + + + + + + + + `; @@ -28,13 +2567,2554 @@ exports[`BusStopInfoScreen tests should render the screen with status loading 1` "flex": 1, }, { - "alignItems": "center", "justifyContent": "center", }, ] } > - + + + + + + + + O'Higgins + + + esq. Salas + + + + + + + Buses que se detienen en esta parada + + + + + + + + + 10 + + + + N + + + + + + Vía Láctea + + + Los Bloques + + + Más de 10 minutos + + + + + + + 10 + + + + P + + + + + + Vía Láctea + + + Leonera + + + Más de 10 minutos + + + + + + + 10 + + + + L + + + + + + Vía Láctea + + + Los Bloques + + + Más de 10 minutos + + + + + + + + + 11 + + + + Q + + + + + + Vía Futuro + + + Los Bloques + + + Más de 10 minutos + + + + + + + 11 + + + + R + + + + + + Vía Futuro + + + Porvenir + + + Más de 10 minutos + + + + + + + 13 + + + + S + + + + + + Vía Siglo XXI + + + Leonera + + + Más de 10 minutos + + + + + + + + + 14 + + + + T + + + + + + Chiguayante Sur + + + Coquimbo + + + Más de 10 minutos + + + + + + + 14 + + + + U + + + + + + Chiguayante Sur + + + Los Altos + + + Más de 10 minutos + + + + + + + 16 + + + + K + + + + + + Vía Universo + + + Leonera + + + Más de 10 minutos + + + + + + + + + 16 + + + + V + + + + + + Vía Universo + + + Leonera + + + Más de 10 minutos + + + + + + + 17 + + + + W + + + + + + Expresos Chiguayante + + + Leonera + + + Más de 10 minutos + + + + + + + 17 + + + + X + + + + + + Expresos Chiguayante + + + Leonera + + + Más de 10 minutos + + + + + + + + + 18 + + + + Y + + + + + + Buses Palomares + + + Hualqui + + + Más de 10 minutos + + + + + + + 20 + + + + M + + + + + + Nueva Llacolén + + + San Pedro Costa + + + Más de 10 minutos + + + + + + + 20 + + + + A + + + + + + Nueva Llacolén + + + Boca Sur + + + Más de 10 minutos + + + + + + + + + 24 + + + + F + + + + + + San Remo + + + Candelaria + + + Más de 10 minutos + + + + + + + 30 + + + + Q + + + + + + Ruta Las Playas + + + Higueras + + + Más de 10 minutos + + + + + + + 30 + + + + R + + + + + + Ruta Las Playas + + + Higueras + + + Más de 10 minutos + + + + + + + + + 57 + + + + P + + + + + + Denavi Sur + + + San Vicente + + + Más de 10 minutos + + + + + + + 31 + + + + D + + + + + + Ruta del Mar + + + Lobos Viejos + + + Más de 10 minutos + + + + + + + 40 + + + + G + + + + + + Las Golondrinas + + + Candelaria + + + Más de 10 minutos + + + + + + + + + `;