diff --git a/package.json b/package.json index 35a7e515f..8c65870f9 100644 --- a/package.json +++ b/package.json @@ -102,6 +102,7 @@ "@storybook/testing-library": "^0.0.9", "@testing-library/jest-dom": "^5.5.0", "@testing-library/react": "^10.0.3", + "@testing-library/react-hooks": "^7.0.2", "@types/cheerio": "^0.22.2", "@types/compression-webpack-plugin": "^9.1.1", "@types/d3-shape": "^1.2.6", diff --git a/src/components/Entities/EntityExecutions.tsx b/src/components/Entities/EntityExecutions.tsx index 877db8bac..b2b3780e8 100644 --- a/src/components/Entities/EntityExecutions.tsx +++ b/src/components/Entities/EntityExecutions.tsx @@ -42,7 +42,7 @@ export const EntityExecutions: React.FC = ({ const styles = useStyles(); const filtersState = useWorkflowExecutionFiltersState(); const archivedFilter = useExecutionShowArchivedState(); - const onlyMyExecutionsFilterState = useOnlyMyExecutionsFilterState(); + const onlyMyExecutionsFilterState = useOnlyMyExecutionsFilterState({}); const sort = { key: executionSortFields.createdAt, diff --git a/src/components/Executions/ExecutionFilters.tsx b/src/components/Executions/ExecutionFilters.tsx index e61a35d82..c93b3fb29 100644 --- a/src/components/Executions/ExecutionFilters.tsx +++ b/src/components/Executions/ExecutionFilters.tsx @@ -31,6 +31,12 @@ const useStyles = makeStyles((theme: Theme) => ({ }, })); +interface OnlyMyExecutionsFilterState { + onlyMyExecutionsValue: boolean; + isFilterDisabled: boolean; + onOnlyMyExecutionsFilterChange: (filterOnlyMyExecutions: boolean) => void; +} + const RenderFilter: React.FC<{ filter: FilterState }> = ({ filter }) => { const searchFilterState = filter as SearchFilterState; switch (filter.type) { @@ -57,11 +63,7 @@ export const ExecutionFilters: React.FC<{ clearCharts?: () => void; showArchived?: boolean; onArchiveFilterChange?: (showArchievedItems: boolean) => void; - onlyMyExecutionsFilterState?: { - onlyMyExecutionsValue: boolean; - isFilterDisabled: boolean; - onOnlyMyExecutionsFilterChange: (filterOnlyMyExecutions: boolean) => void; - }; + onlyMyExecutionsFilterState?: OnlyMyExecutionsFilterState; }> = ({ filters, chartIds, diff --git a/src/components/Executions/__stories__/ExecutionFilters.stories.tsx b/src/components/Executions/__stories__/ExecutionFilters.stories.tsx index 466720e52..62c32bd40 100644 --- a/src/components/Executions/__stories__/ExecutionFilters.stories.tsx +++ b/src/components/Executions/__stories__/ExecutionFilters.stories.tsx @@ -29,6 +29,11 @@ stories.add('Workflow executions - all', () => ( clearCharts={action('clearCharts')} showArchived={false} onArchiveFilterChange={action('onArchiveFilterChange')} + onlyMyExecutionsFilterState={{ + isFilterDisabled: false, + onlyMyExecutionsValue: false, + onOnlyMyExecutionsFilterChange: action('onOnlyMyExecutionsFilterChange'), + }} /> )); stories.add('Workflow executions - minimal', () => ( diff --git a/src/components/Executions/filters/test/useOnlyMyExecutionsFilterState.test.ts b/src/components/Executions/filters/test/useOnlyMyExecutionsFilterState.test.ts new file mode 100644 index 000000000..344b59913 --- /dev/null +++ b/src/components/Executions/filters/test/useOnlyMyExecutionsFilterState.test.ts @@ -0,0 +1,33 @@ +import { loadedFetchable } from 'components/hooks/__mocks__/fetchableData'; +import { useUserProfile } from 'components/hooks/useUserProfile'; +import { useOnlyMyExecutionsFilterState } from 'components/Executions/filters/useOnlyMyExecutionsFilterState'; +import { UserProfile } from 'models/Common/types'; +import { FetchableData } from 'components/hooks/types'; +import { renderHook } from '@testing-library/react-hooks'; + +jest.mock('components/hooks/useUserProfile'); + +describe('useOnlyMyExecutionsFilterState', () => { + const mockUseRemoteLiteralMap = useUserProfile as jest.Mock>; + mockUseRemoteLiteralMap.mockReturnValue(loadedFetchable(null, jest.fn())); + + describe.each` + isFilterDisabled | initialValue | expected + ${undefined} | ${undefined} | ${{ isFilterDisabled: false, onlyMyExecutionsValue: false }} + ${false} | ${undefined} | ${{ isFilterDisabled: false, onlyMyExecutionsValue: false }} + ${true} | ${undefined} | ${{ isFilterDisabled: true, onlyMyExecutionsValue: false }} + ${undefined} | ${false} | ${{ isFilterDisabled: false, onlyMyExecutionsValue: false }} + ${undefined} | ${true} | ${{ isFilterDisabled: false, onlyMyExecutionsValue: true }} + ${false} | ${false} | ${{ isFilterDisabled: false, onlyMyExecutionsValue: false }} + ${false} | ${true} | ${{ isFilterDisabled: false, onlyMyExecutionsValue: true }} + ${true} | ${false} | ${{ isFilterDisabled: true, onlyMyExecutionsValue: false }} + ${true} | ${true} | ${{ isFilterDisabled: true, onlyMyExecutionsValue: true }} + `('for each case', ({ isFilterDisabled, initialValue, expected }) => { + it(`should return ${expected} when called with isFilterDisabled = ${isFilterDisabled} and initialValue = ${initialValue}`, () => { + const { result } = renderHook(() => + useOnlyMyExecutionsFilterState({ isFilterDisabled, initialValue }), + ); + expect(result.current).toEqual(expect.objectContaining(expected)); + }); + }); +}); diff --git a/src/components/Executions/filters/useOnlyMyExecutionsFilterState.ts b/src/components/Executions/filters/useOnlyMyExecutionsFilterState.ts index 0f6a2e315..24976d453 100644 --- a/src/components/Executions/filters/useOnlyMyExecutionsFilterState.ts +++ b/src/components/Executions/filters/useOnlyMyExecutionsFilterState.ts @@ -9,17 +9,22 @@ interface OnlyMyExecutionsFilterState { getFilter: () => FilterOperation | null; } +interface OnlyMyExecutionsFilterStateProps { + isFilterDisabled?: boolean; + initialValue?: boolean; +} + /** * Allows to filter executions by Current User Id */ -export function useOnlyMyExecutionsFilterState( - isFilterDisabled?: boolean, - initialState?: boolean, -): OnlyMyExecutionsFilterState { +export function useOnlyMyExecutionsFilterState({ + isFilterDisabled, + initialValue, +}: OnlyMyExecutionsFilterStateProps): OnlyMyExecutionsFilterState { const profile = useUserProfile(); const userId = profile.value?.subject ? profile.value.subject : ''; const [onlyMyExecutionsValue, setOnlyMyExecutionsValue] = useState( - initialState ?? false, + initialValue ?? false, ); const getFilter = (): FilterOperation | null => { diff --git a/src/components/Project/ProjectExecutions.tsx b/src/components/Project/ProjectExecutions.tsx index d1c4379a7..10a6758a5 100644 --- a/src/components/Project/ProjectExecutions.tsx +++ b/src/components/Project/ProjectExecutions.tsx @@ -67,7 +67,7 @@ export const ProjectExecutions: React.FC = ({ const styles = useStyles(); const archivedFilter = useExecutionShowArchivedState(); const filtersState = useWorkflowExecutionFiltersState(); - const onlyMyExecutionsFilterState = useOnlyMyExecutionsFilterState(); + const onlyMyExecutionsFilterState = useOnlyMyExecutionsFilterState({}); const allFilters = compact([ ...filtersState.appliedFilters, diff --git a/yarn.lock b/yarn.lock index 420fdd931..4f727c618 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3800,6 +3800,17 @@ lodash "^4.17.15" redent "^3.0.0" +"@testing-library/react-hooks@^7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-7.0.2.tgz#3388d07f562d91e7f2431a4a21b5186062ecfee0" + integrity sha512-dYxpz8u9m4q1TuzfcUApqi8iFfR6R0FaMbr2hjZJy1uC8z+bO/K4v8Gs9eogGKYQop7QsrBTFkv/BCF7MzD2Cg== + dependencies: + "@babel/runtime" "^7.12.5" + "@types/react" ">=16.9.0" + "@types/react-dom" ">=16.9.0" + "@types/react-test-renderer" ">=16.9.0" + react-error-boundary "^3.1.0" + "@testing-library/react@^10.0.3": version "10.4.9" resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-10.4.9.tgz#9faa29c6a1a217bf8bbb96a28bd29d7a847ca150" @@ -4438,6 +4449,13 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== +"@types/react-dom@>=16.9.0": + version "17.0.14" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.14.tgz#c8f917156b652ddf807711f5becbd2ab018dea9f" + integrity sha512-H03xwEP1oXmSfl3iobtmQ/2dHF5aBHr8aUMwyGZya6OW45G+xtdzmq6HkncefiBt5JU8DVyaWl/nWZbjZCnzAQ== + dependencies: + "@types/react" "*" + "@types/react-dom@^16.9.7": version "16.9.10" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.10.tgz#4485b0bec3d41f856181b717f45fd7831101156f" @@ -4497,6 +4515,13 @@ dependencies: "@types/react" "*" +"@types/react-test-renderer@>=16.9.0": + version "17.0.1" + resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz#3120f7d1c157fba9df0118dae20cb0297ee0e06b" + integrity sha512-3Fi2O6Zzq/f3QR9dRnlnHso9bMl7weKCviFmfF6B4LS1Uat6Hkm15k0ZAQuDz+UBq6B3+g+NM6IT2nr5QgPzCw== + dependencies: + "@types/react" "*" + "@types/react-test-renderer@^16.9.0": version "16.9.4" resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-16.9.4.tgz#377ccf51ea25c656b08aa474fb8194661009b865" @@ -4527,6 +4552,15 @@ "@types/prop-types" "*" csstype "^3.0.2" +"@types/react@>=16.9.0": + version "17.0.41" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.41.tgz#6e179590d276394de1e357b3f89d05d7d3da8b85" + integrity sha512-chYZ9ogWUodyC7VUTRBfblysKLjnohhFY9bGLwvnUFFy48+vB9DikmB3lW0qTFmBcKSzmdglcvkHK71IioOlDA== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + "@types/react@^16", "@types/react@^16.9.34": version "16.14.2" resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.2.tgz#85dcc0947d0645349923c04ccef6018a1ab7538c" @@ -4540,6 +4574,11 @@ resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== +"@types/scheduler@*": + version "0.16.2" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" + integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== + "@types/serve-static@*", "@types/serve-static@^1.7.31": version "1.13.8" resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.8.tgz#851129d434433c7082148574ffec263d58309c46" @@ -16037,6 +16076,13 @@ react-element-to-jsx-string@^14.3.4: is-plain-object "5.0.0" react-is "17.0.2" +react-error-boundary@^3.1.0: + version "3.1.4" + resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.4.tgz#255db92b23197108757a888b01e5b729919abde0" + integrity sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA== + dependencies: + "@babel/runtime" "^7.12.5" + react-fast-compare@^2.0.2: version "2.0.4" resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"