diff --git a/static/app/utils/teams.tsx b/static/app/utils/teams.tsx new file mode 100644 index 00000000000000..c84c1a193e1851 --- /dev/null +++ b/static/app/utils/teams.tsx @@ -0,0 +1,22 @@ +import {Fragment} from 'react'; + +import useTeams from 'app/utils/useTeams'; + +type RenderProps = ReturnType; + +type Props = Parameters[0] & { + children: (props: RenderProps) => React.ReactNode; +}; + +/** + * This is a utility component to leverage the useTeams hook to provide + * a render props component which returns teams through a variety of inputs + * such as a list of slugs or user teams. + */ +function Teams({children, ...props}: Props) { + const renderProps = useTeams(props); + + return {children(renderProps)}; +} + +export default Teams; diff --git a/tests/js/spec/utils/teams.spec.jsx b/tests/js/spec/utils/teams.spec.jsx new file mode 100644 index 00000000000000..6ae013717c5c5e --- /dev/null +++ b/tests/js/spec/utils/teams.spec.jsx @@ -0,0 +1,43 @@ +import {act, mountWithTheme} from 'sentry-test/reactTestingLibrary'; + +import TeamStore from 'app/stores/teamStore'; +import Teams from 'app/utils/teams'; + +describe('utils.teams', function () { + const renderer = jest.fn(() => null); + + const createWrapper = props => mountWithTheme({renderer}); + + beforeEach(function () { + TeamStore.loadInitialData([ + TestStubs.Team({id: '1', slug: 'bar'}), + TestStubs.Team({id: '2', slug: 'foo'}), + ]); + renderer.mockClear(); + }); + + afterEach(async function () { + act(() => void TeamStore.loadInitialData([])); + }); + + it('sends projects to children', function () { + createWrapper(); + expect(renderer).toHaveBeenCalledWith( + expect.objectContaining({ + fetching: false, + hasMore: null, + fetchError: null, + teams: [ + expect.objectContaining({ + id: '1', + slug: 'bar', + }), + expect.objectContaining({ + id: '2', + slug: 'foo', + }), + ], + }) + ); + }); +});