Skip to content

Commit

Permalink
refactor: add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
pyphilia committed Jan 29, 2024
1 parent 0fdce43 commit 0fc1baa
Show file tree
Hide file tree
Showing 6 changed files with 272 additions and 16 deletions.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
"Alexandre Chau"
],
"dependencies": {
"@graasp/sdk": "github:graasp/graasp-sdk#item-geolocation",
"@graasp/translations": "1.22.1",
"@graasp/sdk": "3.6.0",
"@graasp/translations": "github:graasp/graasp-translations#geolocation",
"axios": "0.27.2",
"crypto-js": "4.2.0",
"date-fns": "3.3.1",
"http-status-codes": "2.3.0",
"qs": "6.11.2",
"react-query": "3.39.3",
Expand Down
51 changes: 51 additions & 0 deletions src/mutations/item.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import nock from 'nock';

import {
ITEMS,
ITEM_GEOLOCATION,
OK_RESPONSE,
RECYCLED_ITEM_DATA,
THUMBNAIL_BLOB_RESPONSE,
Expand Down Expand Up @@ -44,6 +45,7 @@ import {
buildItemKey,
buildItemThumbnailKey,
getKeyForParentId,
itemsWithGeolocationKeys,
} from '../config/keys';
import { uploadFileRoutine, uploadItemThumbnailRoutine } from '../routines';
import {
Expand Down Expand Up @@ -137,6 +139,55 @@ describe('Items Mutations', () => {
).toBeTruthy();
});

it('Post item with geoloc', async () => {
const parentItem = ITEMS[1]!;
const singleKey = itemsWithGeolocationKeys.inBounds({
lat1: 1,
lat2: 2,
lng1: 1,
lng2: 2,
});
const response = {
...newItem,
id: 'someid',
path: buildPath({ prefix: parentItem.path, ids: ['someid'] }),
};

// set default data
queryClient.setQueryData(getKeyForParentId(parentItem.id), [ITEMS[2]]);
queryClient.setQueryData(singleKey, [ITEM_GEOLOCATION]);

const endpoints = [
{
response,
method: HttpMethod.POST,
route: `/${buildPostItemRoute(parentItem.id)}`,
},
];

const mockedMutation = await mockMutation({
endpoints,
mutation,
wrapper,
});

await act(async () => {
await mockedMutation.mutate({
...newItem,
parentId: parentItem.id,
lat: 1,
lng: 1,
});
await waitForMutation();
});

expect(
queryClient.getQueryState(getKeyForParentId(parentItem.id))
?.isInvalidated,
).toBeTruthy();
expect(queryClient.getQueryState(singleKey)?.isInvalidated).toBeTruthy();
});

it('Unauthorized', async () => {
const route = `/${buildPostItemRoute()}`;
queryClient.setQueryData(accessibleItemsKeys.all, [ITEMS[1]]);
Expand Down
1 change: 1 addition & 0 deletions src/mutations/item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ export default (queryConfig: QueryClientConfig) => {
notifier?.({ type: createItemRoutine.FAILURE, payload: { error } });
},
onSettled: (_data, _error, { lat, lng, parentId }) => {
console.log(lat, lng);

Check warning on line 118 in src/mutations/item.ts

View workflow job for this annotation

GitHub Actions / test-coverage

Unexpected console statement
const key = getKeyForParentId(parentId);
queryClient.invalidateQueries(key);

Expand Down
195 changes: 195 additions & 0 deletions src/mutations/itemGeolocation.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
import { HttpMethod } from '@graasp/sdk';
import { SUCCESS_MESSAGES } from '@graasp/translations';

import { StatusCodes } from 'http-status-codes';
import nock from 'nock';
import { act } from 'react-test-renderer';
import { v4 } from 'uuid';

import { ITEM_GEOLOCATION, UNAUTHORIZED_RESPONSE } from '../../test/constants';
import { mockMutation, setUpTest, waitForMutation } from '../../test/utils';
import { buildPutItemGeolocationRoute } from '../api/routes';
import {
buildItemGeolocationKey,
itemsWithGeolocationKeys,
} from '../config/keys';
import {
deleteItemGeolocationRoutine,
putItemGeolocationRoutine,
} from '../routines';

const mockedNotifier = jest.fn();
const { wrapper, queryClient, mutations } = setUpTest({
notifier: mockedNotifier,
});

describe('Item Flag Mutations', () => {
afterEach(() => {
queryClient.clear();
nock.cleanAll();
});

describe('usePutItemGeolocation', () => {
const itemId = v4();
const key = buildItemGeolocationKey(itemId);
const route = `/${buildPutItemGeolocationRoute(itemId)}`;
const mutation = mutations.usePutItemGeolocation;
const singleKey = itemsWithGeolocationKeys.inBounds({
lat1: 0,
lng1: 0,
lat2: 1,
lng2: 1,
});

it('Put item geolocation', async () => {
// set some starting data
queryClient.setQueryData(key, ITEM_GEOLOCATION);
queryClient.setQueryData(singleKey, [ITEM_GEOLOCATION]);

const response = {};

const endpoints = [
{
response,
method: HttpMethod.PUT,
route,
},
];

const mockedMutation = await mockMutation({
endpoints,
mutation,
wrapper,
});

await act(async () => {
await mockedMutation.mutate({ lat: 1, lng: 1, itemId });
await waitForMutation();
});

expect(queryClient.getQueryState(key)?.isInvalidated).toBeTruthy();
expect(queryClient.getQueryState(singleKey)?.isInvalidated).toBeTruthy();
expect(mockedNotifier).toHaveBeenCalledWith({
type: putItemGeolocationRoutine.SUCCESS,
payload: { message: SUCCESS_MESSAGES.PUT_ITEM_GEOLOCATION },
});
});

it('Unauthorized to put item geolocation', async () => {
// set some starting data
queryClient.setQueryData(key, ITEM_GEOLOCATION);
queryClient.setQueryData(singleKey, [ITEM_GEOLOCATION]);

const endpoints = [
{
response: UNAUTHORIZED_RESPONSE,
statusCode: StatusCodes.UNAUTHORIZED,
method: HttpMethod.PUT,
route,
},
];

const mockedMutation = await mockMutation({
endpoints,
mutation,
wrapper,
});

await act(async () => {
await mockedMutation.mutate({ lat: 1, lng: 1, itemId });
await waitForMutation();
});

expect(queryClient.getQueryState(key)?.isInvalidated).toBeTruthy();
expect(queryClient.getQueryState(singleKey)?.isInvalidated).toBeTruthy();
expect(mockedNotifier).toHaveBeenCalledWith(
expect.objectContaining({
type: putItemGeolocationRoutine.FAILURE,
payload: { error: expect.anything() },
}),
);
});
});

describe('useDeleteItemGeolocation', () => {
const itemId = v4();
const key = buildItemGeolocationKey(itemId);
const route = `/${buildPutItemGeolocationRoute(itemId)}`;
const mutation = mutations.useDeleteItemGeolocation;
const singleKey = itemsWithGeolocationKeys.inBounds({
lat1: 0,
lng1: 0,
lat2: 1,
lng2: 1,
});

it('Delete item geolocation', async () => {
// set some starting data
queryClient.setQueryData(key, ITEM_GEOLOCATION);
queryClient.setQueryData(singleKey, [ITEM_GEOLOCATION]);

const response = {};

const endpoints = [
{
response,
method: HttpMethod.DELETE,
route,
},
];

const mockedMutation = await mockMutation({
endpoints,
mutation,
wrapper,
});

await act(async () => {
await mockedMutation.mutate({ itemId });
await waitForMutation();
});

expect(queryClient.getQueryState(key)?.isInvalidated).toBeTruthy();
expect(queryClient.getQueryState(singleKey)?.isInvalidated).toBeTruthy();
expect(mockedNotifier).toHaveBeenCalledWith({
type: deleteItemGeolocationRoutine.SUCCESS,
payload: { message: SUCCESS_MESSAGES.DELETE_ITEM_GEOLOCATION },
});
});

it('Unauthorized to delete item geolocation', async () => {
// set some starting data
queryClient.setQueryData(key, ITEM_GEOLOCATION);
queryClient.setQueryData(singleKey, [ITEM_GEOLOCATION]);

const endpoints = [
{
response: UNAUTHORIZED_RESPONSE,
statusCode: StatusCodes.UNAUTHORIZED,
method: HttpMethod.DELETE,
route,
},
];

const mockedMutation = await mockMutation({
endpoints,
mutation,
wrapper,
});

await act(async () => {
await mockedMutation.mutate({ itemId });
await waitForMutation();
});

expect(queryClient.getQueryState(key)?.isInvalidated).toBeTruthy();
expect(queryClient.getQueryState(singleKey)?.isInvalidated).toBeTruthy();
expect(mockedNotifier).toHaveBeenCalledWith(
expect.objectContaining({
type: deleteItemGeolocationRoutine.FAILURE,
payload: { error: expect.anything() },
}),
);
});
});
});
12 changes: 9 additions & 3 deletions src/mutations/itemGeolocation.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Item, ItemGeolocation } from '@graasp/sdk';
import { DiscriminatedItem, ItemGeolocation } from '@graasp/sdk';
import { SUCCESS_MESSAGES } from '@graasp/translations';

import { useMutation, useQueryClient } from 'react-query';

Expand All @@ -18,12 +19,16 @@ export default (queryConfig: QueryClientConfig) => {
const queryClient = useQueryClient();
return useMutation(
(
payload: { itemId: Item['id'] } & Pick<ItemGeolocation, 'lat' | 'lng'>,
payload: { itemId: DiscriminatedItem['id'] } & Pick<
ItemGeolocation,
'lat' | 'lng'
>,
) => putItemGeolocation(payload, queryConfig),
{
onSuccess: () => {
queryConfig.notifier?.({
type: putItemGeolocationRoutine.SUCCESS,
payload: { message: SUCCESS_MESSAGES.PUT_ITEM_GEOLOCATION },
});
},
onError: (error: Error) => {
Expand All @@ -43,12 +48,13 @@ export default (queryConfig: QueryClientConfig) => {
const useDeleteItemGeolocation = () => {
const queryClient = useQueryClient();
return useMutation(
(payload: { itemId: Item['id'] }) =>
(payload: { itemId: DiscriminatedItem['id'] }) =>
deleteItemGeolocation(payload, queryConfig),
{
onSuccess: () => {
queryConfig.notifier?.({
type: deleteItemGeolocationRoutine.SUCCESS,
payload: { message: SUCCESS_MESSAGES.DELETE_ITEM_GEOLOCATION },
});
},
onError: (error: Error) => {
Expand Down
24 changes: 13 additions & 11 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1791,8 +1791,8 @@ __metadata:
"@babel/preset-typescript": "npm:7.23.3"
"@commitlint/cli": "npm:18.6.0"
"@commitlint/config-conventional": "npm:18.6.0"
"@graasp/sdk": "github:graasp/graasp-sdk#item-geolocation"
"@graasp/translations": "npm:1.22.1"
"@graasp/sdk": "npm:3.6.0"
"@graasp/translations": "github:graasp/graasp-translations#geolocation"
"@testing-library/dom": "npm:9.3.4"
"@testing-library/jest-dom": "npm:6.3.0"
"@testing-library/react": "npm:14.1.2"
Expand All @@ -1812,6 +1812,7 @@ __metadata:
axios: "npm:0.27.2"
babel-jest: "npm:29.7.0"
crypto-js: "npm:4.2.0"
date-fns: "npm:3.3.1"
env-cmd: "npm:10.1.0"
eslint: "npm:8.56.0"
eslint-config-airbnb: "npm:19.0.4"
Expand Down Expand Up @@ -1843,24 +1844,25 @@ __metadata:
languageName: unknown
linkType: soft

"@graasp/sdk@github:graasp/graasp-sdk#item-geolocation":
version: 3.5.0
resolution: "@graasp/sdk@https://github.com/graasp/graasp-sdk.git#commit=c2a2b310ec7989f2b7358521d04c563a155a8c91"
"@graasp/sdk@npm:3.6.0":
version: 3.6.0
resolution: "@graasp/sdk@npm:3.6.0"
dependencies:
date-fns: "npm:3.3.1"
js-cookie: "npm:3.0.5"
uuid: "npm:9.0.1"
validator: "npm:13.11.0"
checksum: c865daa5256c9e0946fcc0b096cb0bd9d2e0c69374f3e9ef4a18de5d45b717028d12e83694a5254c42febe052ff8467427aa1b890187cc01ffaf8d102627fa3d
peerDependencies:
date-fns: ^3
uuid: ^9
checksum: df52e11764c727e17ce69d247805fd8a2d49ba291b84e00ca390f853f0b0eb7fc4a2153e7003044cb8f84edf9c2c9cae91b79a55d1e71e71c69317e40145ad12
languageName: node
linkType: hard

"@graasp/translations@npm:1.22.1":
"@graasp/translations@github:graasp/graasp-translations#geolocation":
version: 1.22.1
resolution: "@graasp/translations@npm:1.22.1"
resolution: "@graasp/translations@https://github.com/graasp/graasp-translations.git#commit=38e9980b5d0450a1fe80b942aae798b20b01ab89"
dependencies:
i18next: "npm:23.7.16"
checksum: 29043007a9926ff54236101c41ceb92eead09d8ce99edf46943790171f3275fb2cc1acd552bfa605247c42b4866bbf1f83dd889da3f571d388eca5f2dd598e17
checksum: d4499181f921aa08bbaf8c7f191d03d5b463c3d55ebb377ccd17edb6603643b239eb5d33af2e8476bca906f1ed5e3bc47271bbfedac1ba471fd393c0ecddb426
languageName: node
linkType: hard

Expand Down

0 comments on commit 0fc1baa

Please sign in to comment.