diff --git a/app/soapbox/api/hooks/groups/__tests__/useGroup.test.ts b/app/soapbox/api/hooks/groups/__tests__/useGroup.test.ts new file mode 100644 index 000000000..8afd06f1a --- /dev/null +++ b/app/soapbox/api/hooks/groups/__tests__/useGroup.test.ts @@ -0,0 +1,41 @@ +import { __stub } from 'soapbox/api'; +import { buildGroup } from 'soapbox/jest/factory'; +import { renderHook, waitFor } from 'soapbox/jest/test-helpers'; + +import { useGroup } from '../useGroup'; + +const group = buildGroup({ id: '1', display_name: 'soapbox' }); + +describe('useGroup hook', () => { + describe('with a successful request', () => { + beforeEach(() => { + __stub((mock) => { + mock.onGet(`/api/v1/groups/${group.id}`).reply(200, group); + }); + }); + + it('is successful', async () => { + const { result } = renderHook(() => useGroup(group.id)); + + await waitFor(() => expect(result.current.isFetching).toBe(false)); + + expect(result.current.group?.id).toBe(group.id); + }); + }); + + describe('with an unsuccessful query', () => { + beforeEach(() => { + __stub((mock) => { + mock.onGet(`/api/v1/groups/${group.id}`).networkError(); + }); + }); + + it('is has error state', async() => { + const { result } = renderHook(() => useGroup(group.id)); + + await waitFor(() => expect(result.current.isFetching).toBe(false)); + + expect(result.current.group).toBeUndefined(); + }); + }); +}); \ No newline at end of file diff --git a/app/soapbox/api/hooks/groups/__tests__/useGroupLookup.test.ts b/app/soapbox/api/hooks/groups/__tests__/useGroupLookup.test.ts new file mode 100644 index 000000000..2397b16ce --- /dev/null +++ b/app/soapbox/api/hooks/groups/__tests__/useGroupLookup.test.ts @@ -0,0 +1,41 @@ +import { __stub } from 'soapbox/api'; +import { buildGroup } from 'soapbox/jest/factory'; +import { renderHook, waitFor } from 'soapbox/jest/test-helpers'; + +import { useGroupLookup } from '../useGroupLookup'; + +const group = buildGroup({ id: '1', slug: 'soapbox' }); + +describe('useGroupLookup hook', () => { + describe('with a successful request', () => { + beforeEach(() => { + __stub((mock) => { + mock.onGet(`/api/v1/groups/lookup?name=${group.slug}`).reply(200, group); + }); + }); + + it('is successful', async () => { + const { result } = renderHook(() => useGroupLookup(group.slug)); + + await waitFor(() => expect(result.current.isFetching).toBe(false)); + + expect(result.current.entity?.id).toBe(group.id); + }); + }); + + describe('with an unsuccessful query', () => { + beforeEach(() => { + __stub((mock) => { + mock.onGet(`/api/v1/groups/lookup?name=${group.slug}`).networkError(); + }); + }); + + it('is has error state', async() => { + const { result } = renderHook(() => useGroupLookup(group.slug)); + + await waitFor(() => expect(result.current.isFetching).toBe(false)); + + expect(result.current.entity).toBeUndefined(); + }); + }); +}); \ No newline at end of file diff --git a/app/soapbox/api/hooks/groups/__tests__/useGroupMedia.test.ts b/app/soapbox/api/hooks/groups/__tests__/useGroupMedia.test.ts new file mode 100644 index 000000000..a68b79eb1 --- /dev/null +++ b/app/soapbox/api/hooks/groups/__tests__/useGroupMedia.test.ts @@ -0,0 +1,44 @@ +import { __stub } from 'soapbox/api'; +import { buildStatus } from 'soapbox/jest/factory'; +import { renderHook, waitFor } from 'soapbox/jest/test-helpers'; + +import { useGroupMedia } from '../useGroupMedia'; + +const status = buildStatus(); +const groupId = '1'; + +describe('useGroupMedia hook', () => { + describe('with a successful request', () => { + beforeEach(() => { + __stub((mock) => { + mock.onGet(`/api/v1/timelines/group/${groupId}?only_media=true`).reply(200, [status]); + }); + }); + + it('is successful', async () => { + const { result } = renderHook(() => useGroupMedia(groupId)); + + await waitFor(() => expect(result.current.isFetching).toBe(false)); + + expect(result.current.entities.length).toBe(1); + expect(result.current.entities[0].id).toBe(status.id); + }); + }); + + describe('with an unsuccessful query', () => { + beforeEach(() => { + __stub((mock) => { + mock.onGet(`/api/v1/timelines/group/${groupId}?only_media=true`).networkError(); + }); + }); + + it('is has error state', async() => { + const { result } = renderHook(() => useGroupMedia(groupId)); + + await waitFor(() => expect(result.current.isFetching).toBe(false)); + + expect(result.current.entities.length).toBe(0); + expect(result.current.isError).toBeTruthy(); + }); + }); +}); \ No newline at end of file diff --git a/app/soapbox/api/hooks/groups/__tests__/useGroupMembers.test.ts b/app/soapbox/api/hooks/groups/__tests__/useGroupMembers.test.ts new file mode 100644 index 000000000..6f2fb6eac --- /dev/null +++ b/app/soapbox/api/hooks/groups/__tests__/useGroupMembers.test.ts @@ -0,0 +1,45 @@ +import { __stub } from 'soapbox/api'; +import { buildGroupMember } from 'soapbox/jest/factory'; +import { renderHook, waitFor } from 'soapbox/jest/test-helpers'; +import { GroupRoles } from 'soapbox/schemas/group-member'; + +import { useGroupMembers } from '../useGroupMembers'; + +const groupMember = buildGroupMember(); +const groupId = '1'; + +describe('useGroupMembers hook', () => { + describe('with a successful request', () => { + beforeEach(() => { + __stub((mock) => { + mock.onGet(`/api/v1/groups/${groupId}/memberships?role=${GroupRoles.ADMIN}`).reply(200, [groupMember]); + }); + }); + + it('is successful', async () => { + const { result } = renderHook(() => useGroupMembers(groupId, GroupRoles.ADMIN)); + + await waitFor(() => expect(result.current.isFetching).toBe(false)); + + expect(result.current.groupMembers.length).toBe(1); + expect(result.current.groupMembers[0].id).toBe(groupMember.id); + }); + }); + + describe('with an unsuccessful query', () => { + beforeEach(() => { + __stub((mock) => { + mock.onGet(`/api/v1/groups/${groupId}/memberships?role=${GroupRoles.ADMIN}`).networkError(); + }); + }); + + it('is has error state', async() => { + const { result } = renderHook(() => useGroupMembers(groupId, GroupRoles.ADMIN)); + + await waitFor(() => expect(result.current.isFetching).toBe(false)); + + expect(result.current.groupMembers.length).toBe(0); + expect(result.current.isError).toBeTruthy(); + }); + }); +}); \ No newline at end of file diff --git a/app/soapbox/api/hooks/groups/__tests__/useGroups.test.ts b/app/soapbox/api/hooks/groups/__tests__/useGroups.test.ts new file mode 100644 index 000000000..adff805f3 --- /dev/null +++ b/app/soapbox/api/hooks/groups/__tests__/useGroups.test.ts @@ -0,0 +1,43 @@ +import { __stub } from 'soapbox/api'; +import { buildGroup } from 'soapbox/jest/factory'; +import { renderHook, waitFor } from 'soapbox/jest/test-helpers'; + +import { useGroups } from '../useGroups'; + +const group = buildGroup({ id: '1', display_name: 'soapbox' }); + +describe('useGroups hook', () => { + describe('with a successful request', () => { + beforeEach(() => { + __stub((mock) => { + mock.onGet('/api/v1/groups?q=').reply(200, [group]); + }); + }); + + it('is successful', async () => { + const { result } = renderHook(() => useGroups()); + + console.log(result.current); + + await waitFor(() => expect(result.current.isFetching).toBe(false)); + + expect(result.current.groups.length).toHaveLength(1); + }); + }); + + // describe('with an unsuccessful query', () => { + // beforeEach(() => { + // __stub((mock) => { + // mock.onGet('/api/v1/groups').networkError(); + // }); + // }); + + // it('is has error state', async() => { + // const { result } = renderHook(() => useGroups()); + + // await waitFor(() => expect(result.current.isFetching).toBe(false)); + + // expect(result.current.groups).toHaveLength(0); + // }); + // }); +}); \ No newline at end of file diff --git a/app/soapbox/jest/factory.ts b/app/soapbox/jest/factory.ts index 35ea063e0..4d8ff336a 100644 --- a/app/soapbox/jest/factory.ts +++ b/app/soapbox/jest/factory.ts @@ -19,6 +19,7 @@ import { type Relationship, } from 'soapbox/schemas'; import { GroupRoles } from 'soapbox/schemas/group-member'; +import { statusSchema, type Status } from 'soapbox/schemas/status'; // TODO: there's probably a better way to create these factory functions. // This looks promising but didn't work on my first attempt: https://github.com/anatine/zod-plugins/tree/main/packages/zod-mock @@ -77,6 +78,12 @@ function buildRelationship(props: Partial = {}): Relationship { }, props)); } +function buildStatus(props: Partial = {}): Status { + return statusSchema.parse(Object.assign({ + id: uuidv4(), + }, props)); +} + export { buildAd, buildCard, @@ -85,4 +92,5 @@ export { buildGroupRelationship, buildGroupTag, buildRelationship, + buildStatus, }; \ No newline at end of file