Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module.exports = {
{
displayName: 'client',
testEnvironment: 'jsdom',
testMatch: ['**/**/*.test.(js|jsx)', '!**/**/*.server.test.(js|jsx)'],
testMatch: ['**/**/*.test.(js|jsx|ts|tsx)', '!**/**/*.server.test.(js|jsx|ts|tsx)'],
},
{
displayName: 'server',
Expand Down
9 changes: 6 additions & 3 deletions spec/useRequestConfigs.server.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@ describe('Testing Hook on the server: useRequestConfigs', () => {
).not.toThrow();
});

it('Should return any empty object', async () => {
const { result } = renderHookServerSideWithCioPlp(() => useRequestConfigs(), {
it('Should return an empty object and a setter', async () => {
const {
result: { requestConfigs, setRequestConfigs },
} = renderHookServerSideWithCioPlp(() => useRequestConfigs(), {
apiKey: DEMO_API_KEY,
});

expect(result).toEqual({});
expect(requestConfigs).toEqual({});
expect(typeof setRequestConfigs).toBe('function');
});
});
35 changes: 30 additions & 5 deletions spec/useRequestConfigs.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ describe('Testing Hook: useRequestConfigs', () => {

it('Should return an empty object if no defaults have been specified', () => {
function TestReactComponent() {
const requestConfigs = useRequestConfigs();
const { requestConfigs, setRequestConfigs } = useRequestConfigs();
expect(requestConfigs).toEqual({});
expect(typeof setRequestConfigs).toEqual('function');
return <div>hello</div>;
}

Expand All @@ -48,7 +49,7 @@ describe('Testing Hook: useRequestConfigs', () => {
it('Should return configurations set as defaults at Plp Context', () => {
window.location.href = 'https://example.com/group_id/Styles';
function TestReactComponent() {
const requestConfigs = useRequestConfigs();
const { requestConfigs } = useRequestConfigs();
expect(requestConfigs).toEqual(testRequestState);
return <div>hello</div>;
}
Expand All @@ -65,7 +66,7 @@ describe('Testing Hook: useRequestConfigs', () => {
it('Should return configurations set in the URL path/query parameters', () => {
function TestReactComponent() {
window.location.href = testUrl;
const requestConfigs = useRequestConfigs();
const { requestConfigs } = useRequestConfigs();
const { fmtOptions, qsParam, preFilterExpression, variationsMap, ...sampleRequestState } =
testRequestState;

Expand All @@ -87,7 +88,7 @@ describe('Testing Hook: useRequestConfigs', () => {
it('Should return merged configurations with the URL query parameters taking priority', () => {
function TestReactComponent() {
window.location.href = 'https://www.example.com/water/fall?q=fire&page=2';
const requestConfigs = useRequestConfigs();
const { requestConfigs } = useRequestConfigs();
const decodedRequestState = testRequestState;
decodedRequestState.page = 2;
decodedRequestState.query = 'fire';
Expand Down Expand Up @@ -121,7 +122,7 @@ describe('Testing Hook: useRequestConfigs', () => {

function TestReactComponent() {
window.location.href = 'https://www.example.com/water/fall?q=fire&page=2';
const decodedRequestState = useRequestConfigs();
const { requestConfigs: decodedRequestState } = useRequestConfigs();

expect(typeof decodedRequestState).toBe('object');
expect(decodedRequestState.page).toBe(7);
Expand All @@ -142,4 +143,28 @@ describe('Testing Hook: useRequestConfigs', () => {
</CioPlpProvider>,
);
});

test('Using setRequestConfigs should work', () => {
function TestReactComponent() {
window.location.href = 'https://www.example.com/search?q=item&page=3';
const { setRequestConfigs } = useRequestConfigs();

const oldUrlObj = new URL(window.location.href);
setRequestConfigs({ page: 12 });
const newUrlObj = new URL(window.location.href);

expect(newUrlObj.searchParams.get('page')).toEqual('12');

// Check the remaining query parameters are the same
expect(newUrlObj.searchParams.get('q')).toEqual(oldUrlObj.searchParams.get('q'));

return <div>hello</div>;
}

render(
<CioPlpProvider apiKey={DEMO_API_KEY}>
<TestReactComponent />
</CioPlpProvider>,
);
});
});
4 changes: 3 additions & 1 deletion src/components/SearchResults/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ export default function SearchResults(props: SearchResultsWithRenderProps) {
throw new Error('<SearchResults /> component must be rendered within CioPlpContext');
}

const requestConfigs = useRequestConfigs() as SearchParameters & { query?: string };
const { requestConfigs } = useRequestConfigs() as {
requestConfigs: SearchParameters & { query?: string };
};
const { query, ...restRequestConfigs } = requestConfigs;
if (!query) {
throw new Error('query is a required parameter of type string');
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/callbacks/useOnAddToCart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default function useOnAddToCart(
getPrice: (item: Item) => number,
callback?: (event: React.MouseEvent, item: Item) => void,
) {
const requestConfigs = useRequestConfigs();
const { requestConfigs } = useRequestConfigs();

if (!requestConfigs) {
throw new Error('This hook is meant to be used within the CioPlp provider.');
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/callbacks/useOnProductCardClick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function useOnProductCardClick(
cioClient: Nullable<ConstructorIO>,
callback?: (event: React.MouseEvent, item: Item) => void,
) {
const requestConfigs = useRequestConfigs();
const { requestConfigs } = useRequestConfigs();

if (!requestConfigs) {
throw new Error('This hook is meant to be used within the CioPlp provider.');
Expand Down
25 changes: 22 additions & 3 deletions src/hooks/useRequestConfigs.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { useCioPlpContext } from './useCioPlpContext';
import { RequestConfigs } from '../types';

export default function useRequestConfigs(): RequestConfigs {
interface UseRequestConfigsReturn {
requestConfigs: RequestConfigs;
setRequestConfigs: (configsToUpdate: Partial<RequestConfigs>) => void;
}

export default function useRequestConfigs(): UseRequestConfigsReturn {
const context = useCioPlpContext();
if (!context) {
throw new Error('This Hook needs to be called within the C.io PLP Context Provider.');
}

const { urlHelpers, staticRequestConfigs } = context;
const { getUrl, getStateFromUrl } = urlHelpers;
const { getUrl, setUrl, getStateFromUrl, getUrlFromState } = urlHelpers;

const url = getUrl();
const urlRequestConfigs = url ? getStateFromUrl(url) : {};
Expand All @@ -20,5 +25,19 @@ export default function useRequestConfigs(): RequestConfigs {
delete requestConfigs.filterValue;
}

return requestConfigs;
const setRequestConfigs = (configsToUpdate: Partial<RequestConfigs>) => {
const oldUrl = getUrl();
if (!oldUrl) {
throw new Error('getUrl returns undefined when attempting to call setRequestConfigs');
}

const urlObj = new URL(oldUrl);
const oldRequestConfigs = oldUrl ? getStateFromUrl(oldUrl) : {};
const newRequestConfigs = { ...oldRequestConfigs, ...configsToUpdate };
const newUrl = getUrlFromState(newRequestConfigs, urlObj);

setUrl(newUrl);
};

return { requestConfigs, setRequestConfigs };
}
6 changes: 4 additions & 2 deletions src/stories/hooks/UseRequestConfigs/Code Example.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ function MyComponent() {
const cioClient = useCioClient('MY_API_KEY')

// For Search
const { query, ...requestParameters } = useRequestConfigs()
const { requestConfigs } = useRequestConfigs()
const { query, ...requestParameters } = requestConfigs
const { searchResults } = cioClient.search.getSearchResults(requestParameters)

// For Browse
const { filterName, filterValue, ...requestParameters } = useRequestConfigs()
const { requestConfigs } = useRequestConfigs()
const { filterName, filterValue, ...requestParameters } = requestConfigs
const { browseResults } = cioClient.browse.getBrowseResults(filterName, filterValue, requestParameters)
...
}
Expand Down
6 changes: 4 additions & 2 deletions src/stories/hooks/UseRequestConfigs/Props.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@ For more details on request parameters, please see [This Page](https://www.todo.
`useRequestConfigs` doesn't take in any arguments.

## Returns
`RequestConfigs` object
<Markdown>{ReturnValue}</Markdown>
An object that contains:
- `setRequestConfigs` function
- `RequestConfigs` object
<Markdown>{ReturnValue}</Markdown>