Skip to content

Commit

Permalink
Create a new React hook to access Projects Images rewrite configurati…
Browse files Browse the repository at this point in the history
…on (#2639)

* feat(image regexconfig hook): write hook for image regex rewrite configuration

* feat(image regexconfig hook): cover more test cases

* feat(image regexconfig hook): update component deprecation warning message

* feat(image regexconfig hook): add tiny warning package

* feat(image regexconfig hook): mock tiny warning package

* feat(image regexconfig hook): update changeset with more description

* feat(image regexconfig hook): format changeset snippet

* feat(image regexconfig hook): update changeset formatting

* feat(image regexconfig hook): update test foreach array in describe block
  • Loading branch information
ddouglasz authored Jun 15, 2022
1 parent 5b0ad17 commit 78de0ec
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 107 deletions.
31 changes: 31 additions & 0 deletions .changeset/angry-days-swim.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
'@commercetools-frontend/application-shell-connectors': patch
---

There is a new React hook which you can use to access the Project Images rewrite configuration [see documentation](https://docs.commercetools.com/custom-applications/api-reference/commercetools-frontend-application-shell-connectors#project-image-settings).

You would use it like this:

```js
function MyComponent() {
const { isLoading, imageRegex } = useProjectExtensionImageRegex();

if (isLoading) return <LoadingSpinner />;

return (
<div>
<h1>Project images regex: {imageRegex}</h1>
</div>
);
}

function MyApp() {
return (
<ProjectExtensionProviderForImageRegex>
<MyComponent />
</ProjectExtensionProviderForImageRegex>
);
}
```

Both `GetProjectExtensionImageRegex` component and `withProjectExtensionImageRegex` still exists for backwards compatibility but have been marked as deprecated.
3 changes: 2 additions & 1 deletion packages/application-shell-connectors/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"graphql": "15.8.0",
"lodash": "4.17.21",
"moment-timezone": "^0.5.34",
"prop-types": "15.8.1"
"prop-types": "15.8.1",
"tiny-warning": "1.0.3"
},
"devDependencies": {
"@apollo/client": "3.6.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export {
GetProjectExtensionImageRegex,
ProjectExtensionProviderForImageRegex,
withProjectExtensionImageRegex,
useProjectExtensionImageRegex,
} from './project-extension-image-regex';
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { MockedResponse } from '@apollo/client/testing';
import type { TImageRegexContext } from './project-extension-image-regex';

import {
screen,
Expand All @@ -10,141 +9,159 @@ import { MockedProvider as ApolloMockProvider } from '@apollo/client/testing';
import {
ProjectExtensionProviderForImageRegex,
GetProjectExtensionImageRegex,
useProjectExtensionImageRegex,
withProjectExtensionImageRegex,
TImageRegexContext,
} from './project-extension-image-regex';
import FetchProjectExtensionImageRegex from './fetch-project-extension-image-regex.settings.graphql';
import { GRAPHQL_TARGETS } from '@commercetools-frontend/constants';
import type { ComponentType } from 'react';

jest.mock('@commercetools-frontend/sentry');
jest.mock('tiny-warning');

type TestProps = {
imageRegex: TImageRegexContext['imageRegex'];
type TBasicTestComponentProps = {
imageRegexData: TImageRegexContext;
};
const TestComponent = (props: TestProps) => (
<>
<div>
{props.imageRegex &&
props.imageRegex.small &&
props.imageRegex.small.replace}
</div>
<div>
{props.imageRegex &&
props.imageRegex.thumb &&
props.imageRegex.thumb.replace}
</div>
</>
);

const renderComponent = (
mocks: ReadonlyArray<MockedResponse>,
skipQuery?: boolean
) =>
render(
const BasicTestComponent = (props: TBasicTestComponentProps) => {
const { imageRegex } = useProjectExtensionImageRegex();
if (props.imageRegexData.isLoading) {
return <div>{'Loading...'}</div>;
}
if (!props.imageRegexData.imageRegex) {
return <div>{'Not found'}</div>;
}
return (
<>
<div>{imageRegex?.small?.replace}</div>
<div>{imageRegex?.thumb?.replace}</div>
</>
);
};

const HookTestComponent = () => {
const imageRegexData = useProjectExtensionImageRegex();
return <BasicTestComponent imageRegexData={imageRegexData} />;
};

const WrappedTestComponent =
withProjectExtensionImageRegex<TBasicTestComponentProps>()(
BasicTestComponent
) as ComponentType<unknown>;

const RenderPropTestComponent = () => {
return (
<GetProjectExtensionImageRegex
render={(imageRegexData) => (
<BasicTestComponent imageRegexData={imageRegexData} />
)}
/>
);
};

const renderTestComponent = ({
Component,
mocks,
skipQuery = false,
includeProvider = true,
}: {
Component: ComponentType<unknown>;
mocks: ReadonlyArray<MockedResponse>;
skipQuery?: boolean;
includeProvider?: boolean;
}) => {
if (!includeProvider) {
return render(<Component />);
}
return render(
<ApolloMockProvider mocks={mocks} addTypename={true}>
<ProjectExtensionProviderForImageRegex skip={skipQuery}>
<div>
<GetProjectExtensionImageRegex
render={(imageRegexContext) => {
if (imageRegexContext.isLoading) {
return <div>{'Loading...'}</div>;
}
if (!imageRegexContext.imageRegex) {
return <div>{'Not found'}</div>;
}
return (
<TestComponent imageRegex={imageRegexContext.imageRegex} />
);
}}
/>
</div>
<Component />
</ProjectExtensionProviderForImageRegex>
</ApolloMockProvider>
);
const renderComponentWithoutProvider = () =>
render(
<div>
<GetProjectExtensionImageRegex
render={(imageRegexContext) => {
if (imageRegexContext.isLoading) {
return <div>{'Loading...'}</div>;
}
if (!imageRegexContext.imageRegex) {
return <div>{'Not found'}</div>;
}
return <TestComponent imageRegex={imageRegexContext.imageRegex} />;
}}
/>
</div>
);
};

describe('rendering', () => {
describe.each([
HookTestComponent,
WrappedTestComponent,
RenderPropTestComponent,
])('rendering #%#', (Component) => {
describe('when image regex is defined', () => {
it('should render regex info', async () => {
renderComponent([
{
request: {
query: FetchProjectExtensionImageRegex,
context: {
target: GRAPHQL_TARGETS.SETTINGS_SERVICE,
renderTestComponent({
Component,
mocks: [
{
request: {
query: FetchProjectExtensionImageRegex,
context: {
target: GRAPHQL_TARGETS.SETTINGS_SERVICE,
},
},
},
result: {
data: {
projectExtension: {
__typename: 'ProjectExtension',
id: 'p1',
imageRegex: {
__typename: 'ImageRegex',
thumb: {
__typename: 'ImageRegexOptions',
flag: 'gi',
replace: '-thumb.jpg',
search: '.[^.]+$',
result: {
data: {
projectExtension: {
__typename: 'ProjectExtension',
id: 'p1',
imageRegex: {
__typename: 'ImageRegex',
thumb: {
__typename: 'ImageRegexOptions',
flag: 'gi',
replace: '-thumb.jpg',
search: '.[^.]+$',
},
small: null,
},
small: null,
},
},
},
},
},
]);
],
});
await waitForElementToBeRemoved(() => screen.queryByText('Loading...'));
expect(screen.getByText('-thumb.jpg')).toBeInTheDocument();
});
});
describe('when image regex is not defined', () => {
it('should not render regex info', async () => {
renderComponent([
{
request: {
query: FetchProjectExtensionImageRegex,
context: {
target: GRAPHQL_TARGETS.SETTINGS_SERVICE,
renderTestComponent({
Component,
mocks: [
{
request: {
query: FetchProjectExtensionImageRegex,
context: {
target: GRAPHQL_TARGETS.SETTINGS_SERVICE,
},
},
},
result: {
data: {
projectExtension: {
__typename: 'ProjectExtension',
id: 'p1',
imageRegex: null,
result: {
data: {
projectExtension: {
__typename: 'ProjectExtension',
id: 'p1',
imageRegex: null,
},
},
},
},
},
]);
],
});
await waitForElementToBeRemoved(() => screen.queryByText('Loading...'));
expect(screen.getByText('Not found')).toBeInTheDocument();
});
});
describe('when fetching regex settings is skipped', () => {
it('should not render regex info', () => {
renderComponent([], true);
renderTestComponent({ Component, mocks: [], skipQuery: true });
expect(screen.getByText('Not found')).toBeInTheDocument();
});
});
describe('when context provider is not defined', () => {
it('should not render regex info', () => {
renderComponentWithoutProvider();
renderTestComponent({ Component, mocks: [], includeProvider: false });
expect(screen.getByText('Not found')).toBeInTheDocument();
});
});
Expand Down
Loading

1 comment on commit 78de0ec

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deploy preview for merchant-center-application-kit ready!

✅ Preview
https://merchant-center-application-lhrl571b3-commercetools.vercel.app

Built with commit 78de0ec.
This pull request is being automatically deployed with vercel-action

Please sign in to comment.