Skip to content

Commit

Permalink
feat(client|redux): expose closet endpoints
Browse files Browse the repository at this point in the history
This exposes user closet endpoints
  • Loading branch information
andreecosta committed Aug 30, 2023
1 parent a33b504 commit d4b2eee
Show file tree
Hide file tree
Showing 60 changed files with 1,995 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,7 @@ Object {
"deleteToken": [Function],
"deleteUserAddress": [Function],
"deleteUserAttribute": [Function],
"deleteUserClosetItem": [Function],
"deleteUserContact": [Function],
"deleteUserDefaultContactAddress": [Function],
"deleteUserExternalLogin": [Function],
Expand Down Expand Up @@ -1146,6 +1147,8 @@ Object {
"getUserAttribute": [Function],
"getUserAttributes": [Function],
"getUserBenefits": [Function],
"getUserCloset": [Function],
"getUserClosets": [Function],
"getUserContact": [Function],
"getUserContacts": [Function],
"getUserCreditBalance": [Function],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export type ExchangeFilterCondition = ExchangeFilterLogicOperatorData;
export type ExchangeFilterLogicOperatorData = {
criteria: ExchangeFilterLogicOperatorCriteria;
comparator: ExchangeFilterLogicOperatorComparator;
value: string | string[];
values: string | string[];
};

export enum ExchangeFilterLogicOperatorCriteria {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { rest, type RestHandler } from 'msw';

const path = '/api/account/v1/users/:userId/closets/:closetId/items/:itemId';

const fixtures = {
success: (response: number): RestHandler =>
rest.delete(path, (_req, res, ctx) =>
res(ctx.status(200), ctx.json(response)),
),
failure: (): RestHandler =>
rest.delete(path, (_req, res, ctx) =>
res(ctx.status(404), ctx.json({ message: 'stub error' })),
),
};

export default fixtures;
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { rest, type RestHandler } from 'msw';
import type { Closet } from '../index.js';

const path = '/api/account/v1/users/:userId/closets/:closetId/items';

const fixtures = {
success: (response: Closet): RestHandler =>
rest.get(path, (_req, res, ctx) =>
res(ctx.status(200), ctx.json(response)),
),
failure: (): RestHandler =>
rest.get(path, (_req, res, ctx) =>
res(ctx.status(404), ctx.json({ message: 'stub error' })),
),
};

export default fixtures;
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { rest, type RestHandler } from 'msw';
import type { ClosetSummary } from '../index.js';

const path = '/api/account/v1/users/:userId/closets';

const fixtures = {
success: (response: ClosetSummary[]): RestHandler =>
rest.get(path, (_req, res, ctx) =>
res(ctx.status(200), ctx.json(response)),
),
failure: (): RestHandler =>
rest.get(path, (_req, res, ctx) =>
res(ctx.status(404), ctx.json({ message: 'stub error' })),
),
};

export default fixtures;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`deleteUserClosetItem should receive a client request error 1`] = `
Object {
"code": "-1",
"message": "stub error",
"name": "AxiosError",
"status": 404,
"transportLayerErrorCode": "ERR_BAD_REQUEST",
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`getUserCloset should receive a client request error 1`] = `
Object {
"code": "-1",
"message": "stub error",
"name": "AxiosError",
"status": 404,
"transportLayerErrorCode": "ERR_BAD_REQUEST",
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`getUserClosets should receive a client request error 1`] = `
Object {
"code": "-1",
"message": "stub error",
"name": "AxiosError",
"status": 404,
"transportLayerErrorCode": "ERR_BAD_REQUEST",
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {
closetId,
closetItemId,
userId,
} from 'tests/__fixtures__/users/index.mjs';
import { deleteUserClosetItem } from '../index.js';
import client from '../../../helpers/client/index.js';
import fixtures from '../__fixtures__/deleteUserClosetItem.fixtures.js';
import mswServer from '../../../../tests/mswServer.js';

describe('deleteUserClosetItem', () => {
const expectedConfig = undefined;
const spy = jest.spyOn(client, 'delete');

beforeEach(() => jest.clearAllMocks());

it('should handle a client request successfully', async () => {
const response = 200;

mswServer.use(fixtures.success(response));

await expect(
deleteUserClosetItem(userId, closetId, closetItemId),
).resolves.toBe(response);

expect(spy).toHaveBeenCalledWith(
`/account/v1/users/${userId}/closets/${closetId}/items/${closetItemId}`,
expectedConfig,
);
});

it('should receive a client request error', async () => {
mswServer.use(fixtures.failure());

await expect(
deleteUserClosetItem(userId, closetId, closetItemId),
).rejects.toMatchSnapshot();

expect(spy).toHaveBeenCalledWith(
`/account/v1/users/${userId}/closets/${closetId}/items/${closetItemId}`,
expectedConfig,
);
});
});
40 changes: 40 additions & 0 deletions packages/client/src/users/closets/__tests__/getUserCloset.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {
closetId,
mockGetUserClosetResponse,
userId,
} from 'tests/__fixtures__/users/index.mjs';
import { getUserCloset } from '../index.js';
import client from '../../../helpers/client/index.js';
import fixtures from '../__fixtures__/getUserCloset.fixtures.js';
import mswServer from '../../../../tests/mswServer.js';

describe('getUserCloset', () => {
const expectedConfig = undefined;
const spy = jest.spyOn(client, 'get');

beforeEach(() => jest.clearAllMocks());

it('should handle a client request successfully', async () => {
mswServer.use(fixtures.success(mockGetUserClosetResponse));

await expect(getUserCloset(userId, closetId)).resolves.toStrictEqual(
mockGetUserClosetResponse,
);

expect(spy).toHaveBeenCalledWith(
`/account/v1/users/${userId}/closets/${closetId}/items`,
expectedConfig,
);
});

it('should receive a client request error', async () => {
mswServer.use(fixtures.failure());

await expect(getUserCloset(userId, closetId)).rejects.toMatchSnapshot();

expect(spy).toHaveBeenCalledWith(
`/account/v1/users/${userId}/closets/${closetId}/items`,
expectedConfig,
);
});
});
39 changes: 39 additions & 0 deletions packages/client/src/users/closets/__tests__/getUserClosets.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { getUserClosets } from '../index.js';
import {
mockGetUserClosetsResponse,
userId,
} from 'tests/__fixtures__/users/index.mjs';
import client from '../../../helpers/client/index.js';
import fixtures from '../__fixtures__/getUserClosets.fixtures.js';
import mswServer from '../../../../tests/mswServer.js';

describe('getUserClosets', () => {
const expectedConfig = undefined;
const spy = jest.spyOn(client, 'get');

beforeEach(() => jest.clearAllMocks());

it('should handle a client request successfully', async () => {
mswServer.use(fixtures.success(mockGetUserClosetsResponse));

await expect(getUserClosets(userId)).resolves.toStrictEqual(
mockGetUserClosetsResponse,
);

expect(spy).toHaveBeenCalledWith(
`/account/v1/users/${userId}/closets`,
expectedConfig,
);
});

it('should receive a client request error', async () => {
mswServer.use(fixtures.failure());

await expect(getUserClosets(userId)).rejects.toMatchSnapshot();

expect(spy).toHaveBeenCalledWith(
`/account/v1/users/${userId}/closets`,
expectedConfig,
);
});
});
39 changes: 39 additions & 0 deletions packages/client/src/users/closets/deleteUserClosetItem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { adaptError } from '../../helpers/client/formatError.js';
import client from '../../helpers/client/index.js';
import join from 'proper-url-join';
import type { DeleteUserClosetItem } from './types/index.js';

/**
* Method responsible for deleting a user closet.
*
* @param userId - Universal identifier of the user.
* @param closetId - Closet identifier.
* @param itemId - Closet item identifier.
* @param config - Custom configurations to send to the client instance (axios).
*
* @returns Promise that will resolve when the call to the endpoint finishes.
*/
const deleteUserCloset: DeleteUserClosetItem = (
userId,
closetId,
itemId,
config,
) =>
client
.delete(
join(
'/account/v1/users',
userId,
'/closets/',
closetId,
'/items/',
itemId,
),
config,
)
.then(response => response.status)
.catch(error => {
throw adaptError(error);
});

export default deleteUserCloset;
29 changes: 29 additions & 0 deletions packages/client/src/users/closets/getUserCloset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { adaptError } from '../../helpers/client/formatError.js';
import client from '../../helpers/client/index.js';
import join from 'proper-url-join';
import type { GetUserCloset } from './types/index.js';

/**
* Method responsible for getting a specific user closet.
*
* @param userId - Universal identifier of the user.
* @param closetId - Closet identifier.
* @param query - Query params.
* @param config - Custom configurations to send to the client instance (axios).
*
* @returns Promise that will resolve when the call to the endpoint finishes.
*/
const getUserCloset: GetUserCloset = (userId, closetId, query, config) =>
client
.get(
join('/account/v1/users/', userId, '/closets/', closetId, '/items', {
query,
}),
config,
)
.then(response => response.data)
.catch(error => {
throw adaptError(error);
});

export default getUserCloset;
22 changes: 22 additions & 0 deletions packages/client/src/users/closets/getUserClosets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { adaptError } from '../../helpers/client/formatError.js';
import client from '../../helpers/client/index.js';
import join from 'proper-url-join';
import type { GetUserClosets } from './types/index.js';

/**
* Method responsible for getting user closets.
*
* @param userId - Universal identifier of the user.
* @param config - Custom configurations to send to the client instance (axios).
*
* @returns Promise that will resolve when the call to the endpoint finishes.
*/
const getUserClosets: GetUserClosets = (userId, config) =>
client
.get(join('/account/v1/users/', userId, '/closets'), config)
.then(response => response.data)
.catch(error => {
throw adaptError(error);
});

export default getUserClosets;
4 changes: 4 additions & 0 deletions packages/client/src/users/closets/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export { default as deleteUserClosetItem } from './deleteUserClosetItem.js';
export { default as getUserCloset } from './getUserCloset.js';
export { default as getUserClosets } from './getUserClosets.js';
export * from './types/index.js';
31 changes: 31 additions & 0 deletions packages/client/src/users/closets/types/closet.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { Brand } from '../../../brands/index.js';
import type {
Color,
PagedResponse,
ProductImageGroup,
ProductVariantAttribute,
} from '../../../types/index.js';
import type { Order } from '../../../orders/index.js';
import type { Price, Product } from '../../../products/index.js';
import type { ProductCategory } from '../../../categories/index.js';

export type Closet = PagedResponse<ClosetItem>;

export type ClosetItem = {
id: string;
orderId: Order['id'];
merchantId: number;
productId: Product['result']['id'];
productName: string;
productDescription: string;
attributes: ProductVariantAttribute[];
images: ProductImageGroup;
categories: ProductCategory[];
colors: Color[];
price: Price;
purchasePrice: Price;
brand: Brand;
customAttributes: string;
isAvailable: boolean;
createdDate: string;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export type ClosetSummary = {
id: string;
createdDate: string;
totalItems: number;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { ClosetItem } from './closet.types.js';
import type { ClosetSummary } from './closetSummary.types.js';
import type { Config } from '../../../types/index.js';
import type { User } from '../../authentication/types/user.types.js';

export type DeleteUserClosetItem = (
userId: User['id'],
closetId: ClosetSummary['id'],
itemId: ClosetItem['id'],
config?: Config,
) => Promise<number>;
Loading

0 comments on commit d4b2eee

Please sign in to comment.