Compare commits
5 Commits
1d58f41b5f
...
5317050679
Author | SHA1 | Date | |
---|---|---|---|
5317050679 | |||
1055a14457 | |||
6082aa75a0 | |||
9bb252de00 | |||
db331acbb1 |
38
src/features/Filters/filterApi.test.ts
Normal file
38
src/features/Filters/filterApi.test.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import { pokedexSlice } from 'features/Pokedex/pokedexSlice';
|
||||
import { filterApi } from './filterApi';
|
||||
import { filterSlice } from './filterSlice';
|
||||
import { configureStore } from '@reduxjs/toolkit';
|
||||
|
||||
import { AppStore } from 'app/store';
|
||||
import { listenerMiddleware } from 'app/listenerMiddleware';
|
||||
import { TypeListResponseData } from 'features/Pokedex/types/api';
|
||||
|
||||
let store: AppStore;
|
||||
|
||||
describe('filterApi', () => {
|
||||
beforeEach(() => {
|
||||
store = configureStore({
|
||||
reducer: {
|
||||
pokedex: pokedexSlice.reducer,
|
||||
filter: filterSlice.reducer,
|
||||
[filterApi.reducerPath]: filterApi.reducer,
|
||||
},
|
||||
middleware: getDefaultMiddleware =>
|
||||
getDefaultMiddleware().concat(
|
||||
filterApi.middleware,
|
||||
listenerMiddleware.middleware,
|
||||
),
|
||||
});
|
||||
});
|
||||
|
||||
describe('JEST test against mock API', () => {
|
||||
test('visit https://pokeapi.co/api/v2/type should return correct data in list', async () => {
|
||||
await store.dispatch(filterApi.endpoints.getTypeList.initiate());
|
||||
|
||||
const typeListData = filterApi.endpoints.getTypeList.select()(
|
||||
store.getState(),
|
||||
).data as TypeListResponseData;
|
||||
expect(typeListData?.results).toHaveLength(typeListData.count + 1);
|
||||
});
|
||||
});
|
||||
});
|
@ -1,9 +1,6 @@
|
||||
import { createApi } from '@reduxjs/toolkit/query/react';
|
||||
import { pokeApiBaseQuery } from '../../services/pokeapi/paginationBaseQuery';
|
||||
import {
|
||||
RegionListResponseData,
|
||||
TypeListResponseData,
|
||||
} from '../Pokedex/types/api';
|
||||
import { RegionListResponseData, TypeListResponseData } from 'types/api';
|
||||
|
||||
export const filterApi = createApi({
|
||||
reducerPath: 'filterApi',
|
||||
|
@ -3,36 +3,38 @@ import {
|
||||
sortPokemonCardsByIdOrName,
|
||||
searchPokemonCardsByName,
|
||||
} from 'features/Pokedex/Pokedex';
|
||||
import { PokemonResponseData } from 'features/Pokedex/types/api';
|
||||
import pokemon3_Venusaur from 'features/Pokedex/__test__/pokemon3_Venusaur.json';
|
||||
import pokemon4_Charmander from 'features/Pokedex/__test__/pokemon4_charmander.json';
|
||||
import { PokemonCardProps } from 'components/PokemonCard';
|
||||
import pokemon3_venusaur_card from 'features/Pokedex/__test__/pokemon3_venusaur_Card.json';
|
||||
import pokemon4_charmander_card from 'features/Pokedex/__test__/pokemon4_charmandar_Card.json';
|
||||
import { AppStore } from 'app/store';
|
||||
import { configureStore } from '@reduxjs/toolkit';
|
||||
import { pokedexSlice } from 'features/Pokedex/pokedexSlice';
|
||||
import { pokedexApi } from 'features/Pokedex/pokedexApi';
|
||||
import { filterSlice } from 'features/Filters/filterSlice';
|
||||
import { filterApi } from 'features/Filters/filterApi';
|
||||
import { listenerMiddleware } from 'app/listenerMiddleware';
|
||||
|
||||
let store: AppStore;
|
||||
|
||||
describe('pokedex Component', () => {
|
||||
describe('filterPokemonByType works correctly', () => {
|
||||
beforeEach(() => {
|
||||
store = configureStore({
|
||||
reducer: {
|
||||
pokedex: pokedexSlice.reducer,
|
||||
[pokedexApi.reducerPath]: pokedexApi.reducer,
|
||||
},
|
||||
middleware: getDefaultMiddleware =>
|
||||
getDefaultMiddleware().concat(
|
||||
pokedexApi.middleware,
|
||||
listenerMiddleware.middleware,
|
||||
),
|
||||
});
|
||||
beforeEach(() => {
|
||||
store = configureStore({
|
||||
reducer: {
|
||||
pokedex: pokedexSlice.reducer,
|
||||
filter: filterSlice.reducer,
|
||||
[filterApi.reducerPath]: filterApi.reducer,
|
||||
},
|
||||
middleware: getDefaultMiddleware =>
|
||||
getDefaultMiddleware().concat(
|
||||
filterApi.middleware,
|
||||
listenerMiddleware.middleware,
|
||||
),
|
||||
});
|
||||
});
|
||||
|
||||
const pokemonList: PokemonResponseData[] = [
|
||||
pokemon3_Venusaur,
|
||||
pokemon4_Charmander,
|
||||
describe('filterPokemonByType works correctly', () => {
|
||||
const pokemonList: PokemonCardProps[] = [
|
||||
pokemon3_venusaur_card,
|
||||
pokemon4_charmander_card,
|
||||
];
|
||||
|
||||
it('should return all PokemonCard if the selected type is "All Types"', () => {
|
||||
@ -45,69 +47,47 @@ describe('pokedex Component', () => {
|
||||
const selectedType = 'fire';
|
||||
const filteredList = filterPokemonCardsByType(pokemonList, selectedType);
|
||||
const allPokemonAreOfTypeFire = filteredList.every(pokemon =>
|
||||
pokemon.types.some(type => type.type.name === selectedType),
|
||||
pokemon.types.some(type => type === selectedType),
|
||||
);
|
||||
expect(allPokemonAreOfTypeFire).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('sortPokemonsByIdOrName works correctly', () => {
|
||||
beforeEach(() => {
|
||||
store = configureStore({
|
||||
reducer: {
|
||||
pokedex: pokedexSlice.reducer,
|
||||
[pokedexApi.reducerPath]: pokedexApi.reducer,
|
||||
},
|
||||
middleware: getDefaultMiddleware =>
|
||||
getDefaultMiddleware().concat(
|
||||
pokedexApi.middleware,
|
||||
listenerMiddleware.middleware,
|
||||
),
|
||||
});
|
||||
});
|
||||
|
||||
const pokemonList: PokemonResponseData[] = [
|
||||
pokemon3_Venusaur,
|
||||
pokemon4_Charmander,
|
||||
const pokemonList: PokemonCardProps[] = [
|
||||
pokemon3_venusaur_card,
|
||||
pokemon4_charmander_card,
|
||||
];
|
||||
it('should sort by id if the selected sort is "id"', () => {
|
||||
const selectedSort = 'id';
|
||||
const sortedList = sortPokemonCardsByIdOrName(pokemonList, selectedSort);
|
||||
expect(sortedList).toEqual([pokemon3_Venusaur, pokemon4_Charmander]);
|
||||
expect(sortedList).toEqual([
|
||||
pokemon3_venusaur_card,
|
||||
pokemon4_charmander_card,
|
||||
]);
|
||||
});
|
||||
|
||||
it('should sort by name if the selected sort is "name"', () => {
|
||||
const selectedSort = 'name';
|
||||
const sortedList = sortPokemonCardsByIdOrName(pokemonList, selectedSort);
|
||||
expect(sortedList).toEqual([pokemon4_Charmander, pokemon3_Venusaur]);
|
||||
expect(sortedList).toEqual([
|
||||
pokemon4_charmander_card,
|
||||
pokemon3_venusaur_card,
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('searchPokemonByName works correctly', () => {
|
||||
beforeEach(() => {
|
||||
store = configureStore({
|
||||
reducer: {
|
||||
pokedex: pokedexSlice.reducer,
|
||||
[pokedexApi.reducerPath]: pokedexApi.reducer,
|
||||
},
|
||||
middleware: getDefaultMiddleware =>
|
||||
getDefaultMiddleware().concat(
|
||||
pokedexApi.middleware,
|
||||
listenerMiddleware.middleware,
|
||||
),
|
||||
});
|
||||
});
|
||||
|
||||
const pokemonList: PokemonResponseData[] = [
|
||||
pokemon3_Venusaur,
|
||||
pokemon4_Charmander,
|
||||
const pokemonList: PokemonCardProps[] = [
|
||||
pokemon3_venusaur_card,
|
||||
pokemon4_charmander_card,
|
||||
];
|
||||
|
||||
it('should search by name correctly', () => {
|
||||
const searchName = 'char';
|
||||
const searchedList = searchPokemonCardsByName(pokemonList, searchName);
|
||||
expect(searchedList).toHaveLength(1);
|
||||
expect(searchedList[0]).toEqual(pokemon4_Charmander);
|
||||
expect(searchedList[0]).toEqual(pokemon4_charmander_card);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,122 +0,0 @@
|
||||
import { pokedexApi } from 'features/Pokedex/pokedexApi';
|
||||
import { pokedexSlice } from 'features/Pokedex/pokedexSlice';
|
||||
import { configureStore } from '@reduxjs/toolkit';
|
||||
import region1 from 'features/Pokedex/__test__/responses/region1.json';
|
||||
import pokemon1 from 'features/Pokedex/__test__/responses/pokemon1.json';
|
||||
import { RegionListResponseData, TypeListResponseData } from '../types/api';
|
||||
import { AppStore } from 'app/store';
|
||||
import { listenerMiddleware } from 'app/listenerMiddleware';
|
||||
|
||||
let store: AppStore;
|
||||
describe('pokedexApi', () => {
|
||||
beforeEach(() => {
|
||||
store = configureStore({
|
||||
reducer: {
|
||||
pokedex: pokedexSlice.reducer,
|
||||
[pokedexApi.reducerPath]: pokedexApi.reducer,
|
||||
},
|
||||
middleware: getDefaultMiddleware =>
|
||||
getDefaultMiddleware().concat(
|
||||
pokedexApi.middleware,
|
||||
listenerMiddleware.middleware,
|
||||
),
|
||||
});
|
||||
});
|
||||
|
||||
describe('JEST test against real API', () => {
|
||||
test('visit https://pokeapi.co/api/v2/region/1 should return correct data', async () => {
|
||||
await store.dispatch(pokedexApi.endpoints.getRegion.initiate(1));
|
||||
|
||||
const region1Data = pokedexApi.endpoints.getRegion.select(1)(
|
||||
store.getState(),
|
||||
).data;
|
||||
expect(region1Data).toEqual(region1);
|
||||
});
|
||||
|
||||
test('visit https://pokeapi.co/api/v2/region/kanto should return correct data', async () => {
|
||||
await store.dispatch(pokedexApi.endpoints.getRegion.initiate('kanto'));
|
||||
|
||||
const region1Data = pokedexApi.endpoints.getRegion.select('kanto')(
|
||||
store.getState(),
|
||||
).data;
|
||||
expect(region1Data).toEqual(region1);
|
||||
});
|
||||
|
||||
test('visit https://pokeapi.co/api/v2/pokemon/1 should return correct data', async () => {
|
||||
await store.dispatch(pokedexApi.endpoints.getPokemon.initiate(1));
|
||||
|
||||
const region1Data = pokedexApi.endpoints.getPokemon.select(1)(
|
||||
store.getState(),
|
||||
).data;
|
||||
expect(region1Data).toEqual(pokemon1);
|
||||
});
|
||||
|
||||
test('visit https://pokeapi.co/api/v2/pokemon/bulbasaur should return correct data', async () => {
|
||||
await store.dispatch(
|
||||
pokedexApi.endpoints.getPokemon.initiate('bulbasaur'),
|
||||
);
|
||||
|
||||
const region1Data = pokedexApi.endpoints.getPokemon.select('bulbasaur')(
|
||||
store.getState(),
|
||||
).data;
|
||||
expect(region1Data).toEqual(pokemon1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('JEST test against mock API', () => {
|
||||
test('visit https://pokeapi.co/api/v2/region/999999 should return correct data', async () => {
|
||||
await store.dispatch(pokedexApi.endpoints.getRegion.initiate(999999));
|
||||
|
||||
const region1Data = pokedexApi.endpoints.getRegion.select(999999)(
|
||||
store.getState(),
|
||||
).data;
|
||||
expect(region1Data).toEqual(region1);
|
||||
});
|
||||
|
||||
test('visit https://pokeapi.co/api/v2/region/testregion should return correct data', async () => {
|
||||
await store.dispatch(
|
||||
pokedexApi.endpoints.getRegion.initiate('testregion'),
|
||||
);
|
||||
|
||||
const region1Data = pokedexApi.endpoints.getRegion.select('testregion')(
|
||||
store.getState(),
|
||||
).data;
|
||||
expect(region1Data).toEqual(region1);
|
||||
});
|
||||
|
||||
test('visit https://pokeapi.co/api/v2/region should return correct data in list', async () => {
|
||||
await store.dispatch(pokedexApi.endpoints.getRegionList.initiate());
|
||||
|
||||
const regionListData = pokedexApi.endpoints.getRegionList.select()(
|
||||
store.getState(),
|
||||
).data as RegionListResponseData;
|
||||
expect(regionListData?.results).toHaveLength(regionListData.count);
|
||||
});
|
||||
|
||||
test('visit https://pokeapi.co/api/v2/type should return correct data in list', async () => {
|
||||
await store.dispatch(pokedexApi.endpoints.getTypeList.initiate());
|
||||
|
||||
const typeListData = pokedexApi.endpoints.getTypeList.select()(
|
||||
store.getState(),
|
||||
).data as TypeListResponseData;
|
||||
expect(typeListData?.results).toHaveLength(typeListData.count + 1);
|
||||
});
|
||||
|
||||
test('visit https://pokeapi.co/api/v2/pokemon should return correct data in list', async () => {
|
||||
await store.dispatch(pokedexApi.endpoints.getPokemonList.initiate());
|
||||
|
||||
const pokemonListData = pokedexApi.endpoints.getPokemonList.select()(
|
||||
store.getState(),
|
||||
).data;
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
expect(pokemonListData?.results).toHaveLength(pokemonListData.count);
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
expect(pokemonListData?.next).toBeUndefined();
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
expect(pokemonListData?.previous).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"id": 3,
|
||||
"name": "venusaur",
|
||||
"image": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/dream-world/3.svg",
|
||||
"types": ["grass", "poison"]
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"id": 4,
|
||||
"name": "charmander",
|
||||
"image": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/dream-world/4.svg",
|
||||
"types": ["fire"]
|
||||
}
|
@ -4,7 +4,7 @@ import type { Slice, PayloadAction } from '@reduxjs/toolkit';
|
||||
import { PokedexState } from 'features/Pokedex/types/slice';
|
||||
|
||||
import { getStartAndEndIdsForRegion } from './utils';
|
||||
import { PokemonResponseData } from './types/api';
|
||||
import { PokemonResponseData } from 'types/api';
|
||||
import { RootState } from 'app/store';
|
||||
|
||||
export const fetchPokemonsInTheRegion = createAsyncThunk<
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { PokemonResponseData } from './api';
|
||||
import { PokemonCardProps } from 'components/PokemonCard';
|
||||
|
||||
export type PokedexState = {
|
||||
|
@ -2,7 +2,7 @@ import { rest } from 'msw';
|
||||
|
||||
import region1 from 'features/Pokedex/__test__/responses/region1.json';
|
||||
import regionList from 'features/Pokedex/__test__/responses/regionList.json';
|
||||
import typeList from 'features/Pokedex/__test__/responses/typeList.json';
|
||||
import typeList from 'features/Filters/__test__/responses/typeList.json';
|
||||
import pokemonListPg1 from 'features/Pokedex/__test__/responses/pokemonListPage1.json';
|
||||
import pokemonListPg2 from 'features/Pokedex/__test__/responses/pokemonListPage2.json';
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
// API Base types
|
||||
export interface nameUrlPair {
|
||||
name: string;
|
||||
url: string;
|
||||
@ -8,34 +9,11 @@ export interface ListResponse {
|
||||
results: nameUrlPair[];
|
||||
}
|
||||
|
||||
export type PokemonListResponseData = ListResponse;
|
||||
// Filter API
|
||||
export type RegionListResponseData = ListResponse;
|
||||
export type TypeListResponseData = ListResponse;
|
||||
|
||||
export interface PokemonListItem {
|
||||
name: string;
|
||||
id: number;
|
||||
type: string[];
|
||||
image: string;
|
||||
}
|
||||
|
||||
export interface PokemonList {
|
||||
PokemonList: PokemonListItem[];
|
||||
}
|
||||
|
||||
export interface RegionResponseData {
|
||||
// many fields are ignored
|
||||
id: number;
|
||||
locations: nameUrlPair[];
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface TypeResponseData {
|
||||
// many fields are ignored
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
// InfoDialog API
|
||||
export interface AbilityItem {
|
||||
ability: nameUrlPair;
|
||||
is_hidden: boolean;
|
||||
@ -82,22 +60,3 @@ export interface PokemonResponseData {
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export interface LocationResponseData {
|
||||
// many fields are ignored
|
||||
areas: nameUrlPair[];
|
||||
id: number;
|
||||
name: string;
|
||||
region: nameUrlPair;
|
||||
}
|
||||
|
||||
export interface PokemonEncounter {
|
||||
// many fields are ignored
|
||||
pokemon: nameUrlPair;
|
||||
}
|
||||
export interface AreaResponseData {
|
||||
// many fields are ignored
|
||||
id: number;
|
||||
name: string;
|
||||
pokemon_encounters: PokemonEncounter[];
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user