import { render, screen, within } from '@testing-library/react' import { MemoryRouter } from 'react-router-dom' import React from 'react' import { CityPresenterBuilder, CityPresenterFactory, CityPresenterVM } from '@grenoble-hands-on/web-adapters' import { City } from '../src/modules/City' import { GeoPosition, WeatherState } from '@grenoble-hands-on/domain' describe('CityComponent', () => { it('display header with city name', () => { // Given const vm = new CityPresenterVM() vm.city = { name: 'Grenoble', position: new GeoPosition(45, 5) } const presenter = new CityPresenterBuilder(vm).build() const presenterFactory = { build: (_: string) => presenter } as CityPresenterFactory // When render(, { wrapper: MemoryRouter }) // Then const header = screen.getByText('Grenoble') expect(header).toBeTruthy() }) it('display daily weather with temperature', async () => { // Given const vm = new CityPresenterVM() vm.dailyWeather = [ { weather: WeatherState.sunny, temperatureMin: 8, temperatureMax: 15, day: '12/01/2021', unite: 'C' } ] const presenter = new CityPresenterBuilder(vm).build() const presenterFactory = { build: (_: string) => presenter } as CityPresenterFactory // When render(, { wrapper: MemoryRouter }) // Then const weather = screen.queryAllByRole('row') const weatherCol = weather[1] const weatherDate = await within(weatherCol!).findByText('12/01/2021') const temperatureMax = await within(weatherCol!).findByText('15 C°') const temperatureMin = await within(weatherCol!).findByText('8 C°') expect(weatherDate).toBeTruthy() expect(temperatureMax).toBeTruthy() expect(temperatureMin).toBeTruthy() }) it('display hourly weather with temperature', async () => { // Given const vm = new CityPresenterVM() vm.hourlyWeather = [ { weather: WeatherState.sunny, temperature: 8, time: '12:00', unite: 'C' } ] const presenter = new CityPresenterBuilder(vm).build() const presenterFactory = { build: (_: string) => presenter } as CityPresenterFactory // When render(, { wrapper: MemoryRouter }) // Then const weather = screen.queryAllByRole('row') const weatherCol = weather[1] const weatherDate = await within(weatherCol!).findByText('12:00') const temperature = await within(weatherCol!).findByText('8 C°') expect(weatherDate).toBeTruthy() expect(temperature).toBeTruthy() }) test('fetch weather on init', async () => { const hasFetchDailyWeather = await new Promise(resolve => { // Given const presenter = new CityPresenterBuilder() .withFetchWeather(() => Promise.resolve().then(() => resolve(true))) .build() const presenterFactory = { build: (_: string) => presenter } as CityPresenterFactory // When render(, { wrapper: MemoryRouter }) }) // Then expect(hasFetchDailyWeather).toBe(true) }) test('fetch city on init', async () => { const hasFetchCity = await new Promise(resolve => { // Given const presenter = new CityPresenterBuilder() .withFetchCity(() => Promise.resolve().then(() => resolve(true))) .build() const presenterFactory = { build: (_: string) => presenter } as CityPresenterFactory // When render(, { wrapper: MemoryRouter }) }) // Then expect(hasFetchCity).toBe(true) }) test('update weather mode on hourly view select', async () => { const requestWithMode = await new Promise(resolve => { // Given const vm = new CityPresenterVM() vm.mode = 'daily' const presenter = new CityPresenterBuilder(vm) .withUpdateMode((mode) => resolve(mode)) .build() const presenterFactory = { build: (_: string) => presenter } as CityPresenterFactory // When render(, { wrapper: MemoryRouter }) screen.getByRole('radio', { name: /detailed/i }).click() }) // Then expect(requestWithMode).toBe('hourly') }) test('update weather mode on daily view select', async () => { const requestWithMode = await new Promise(resolve => { // Given const vm = new CityPresenterVM() vm.mode = 'hourly' const presenter = new CityPresenterBuilder(vm) .withUpdateMode((mode) => resolve(mode)) .build() const presenterFactory = { build: (_: string) => presenter } as CityPresenterFactory // When render(, { wrapper: MemoryRouter }) screen.getByRole('radio', { name: /simple/i }).click() }) // Then expect(requestWithMode).toBe('daily') }) test('update temperature unit on celsius select', async () => { const requestWithTemperature = await new Promise(resolve => { // Given const vm = new CityPresenterVM() vm.temperatureUnite = 'F' const presenter = new CityPresenterBuilder(vm) .withUpdateTemperatureUnit((temperatureUnit) => resolve(temperatureUnit)) .build() const presenterFactory = { build: (_: string) => presenter } as CityPresenterFactory // When render(, { wrapper: MemoryRouter }) screen.getByRole('radio', { name: /C°/ }).click() }) // Then expect(requestWithTemperature).toBe('C') }) test('update temperature unit on fahrenheit select', async () => { const requestWithTemperature = await new Promise(resolve => { // Given const vm = new CityPresenterVM() vm.temperatureUnite = 'C' const presenter = new CityPresenterBuilder() .withUpdateTemperatureUnit((temperatureUnit) => resolve(temperatureUnit)) .build() const presenterFactory = { build: (_: string) => presenter } as CityPresenterFactory // When render(, { wrapper: MemoryRouter }) screen.getByRole('radio', { name: /F°/ }).click() }) // Then expect(requestWithTemperature).toBe('F') }) })