From 695ee4649f4ce4df4a4aadd0413b8989da5a6e9c Mon Sep 17 00:00:00 2001 From: Kris Urbas <605420+krzysu@users.noreply.github.com> Date: Fri, 29 Sep 2023 14:35:59 +0200 Subject: [PATCH] add tests for useProfile and usePublication --- .../src/apollo/cache/createTypePolicies.ts | 3 +- .../createFeedFieldPolicy.ts | 2 +- .../src/apollo/cache/field-policies/index.ts | 1 + .../src/lens/__helpers__/queries/profile.ts | 36 ++++++------- .../lens/__helpers__/queries/publication.ts | 21 +++----- .../src/profile/__tests__/useProfile.spec.ts | 54 +++++++++++++++++++ .../__tests__/usePublication.spec.ts | 51 ++++++++++++++++++ 7 files changed, 133 insertions(+), 35 deletions(-) rename packages/api-bindings/src/apollo/cache/{ => field-policies}/createFeedFieldPolicy.ts (66%) create mode 100644 packages/react/src/profile/__tests__/useProfile.spec.ts create mode 100644 packages/react/src/publication/__tests__/usePublication.spec.ts diff --git a/packages/api-bindings/src/apollo/cache/createTypePolicies.ts b/packages/api-bindings/src/apollo/cache/createTypePolicies.ts index 206a9b8f9e..b3c825b476 100644 --- a/packages/api-bindings/src/apollo/cache/createTypePolicies.ts +++ b/packages/api-bindings/src/apollo/cache/createTypePolicies.ts @@ -1,10 +1,10 @@ import { TypePolicy } from '@apollo/client'; import { StrictTypedTypePolicies } from '../../lens'; -import { createFeedFieldPolicy } from './createFeedFieldPolicy'; import { createPublicationTypePolicy } from './createPublicationTypePolicy'; import { createQueryParamsLocalFields, QueryParams } from './createQueryParamsLocalFields'; import { + createFeedFieldPolicy, createFollowersFieldPolicy, createFollowingFieldPolicy, createMutualFollowersFieldPolicy, @@ -50,6 +50,7 @@ export function createTypePolicies( searchPublications: createSearchPublicationsFieldPolicy(), whoActedOnPublication: createWhoActedOnPublicationFieldPolicy(), whoReactedPublication: createWhoReactedPublicationFieldPolicy(), + ...createQueryParamsLocalFields(params), }, }, diff --git a/packages/api-bindings/src/apollo/cache/createFeedFieldPolicy.ts b/packages/api-bindings/src/apollo/cache/field-policies/createFeedFieldPolicy.ts similarity index 66% rename from packages/api-bindings/src/apollo/cache/createFeedFieldPolicy.ts rename to packages/api-bindings/src/apollo/cache/field-policies/createFeedFieldPolicy.ts index 03ff210368..b9b13ac28f 100644 --- a/packages/api-bindings/src/apollo/cache/createFeedFieldPolicy.ts +++ b/packages/api-bindings/src/apollo/cache/field-policies/createFeedFieldPolicy.ts @@ -1,4 +1,4 @@ -import { cursorBasedPagination } from './utils/cursorBasedPagination'; +import { cursorBasedPagination } from '../utils/cursorBasedPagination'; export function createFeedFieldPolicy() { return cursorBasedPagination([['request', ['where', ['feedEventItemTypes', 'metadata', 'for']]]]); diff --git a/packages/api-bindings/src/apollo/cache/field-policies/index.ts b/packages/api-bindings/src/apollo/cache/field-policies/index.ts index d649413fcc..c282014e3d 100644 --- a/packages/api-bindings/src/apollo/cache/field-policies/index.ts +++ b/packages/api-bindings/src/apollo/cache/field-policies/index.ts @@ -1,3 +1,4 @@ +export * from './createFeedFieldPolicy'; export * from './createFollowersFieldPolicy'; export * from './createFollowingFieldPolicy'; export * from './createMutualFollowersFieldPolicy'; diff --git a/packages/api-bindings/src/lens/__helpers__/queries/profile.ts b/packages/api-bindings/src/lens/__helpers__/queries/profile.ts index 051185ef81..327f28e340 100644 --- a/packages/api-bindings/src/lens/__helpers__/queries/profile.ts +++ b/packages/api-bindings/src/lens/__helpers__/queries/profile.ts @@ -27,6 +27,24 @@ import { import { mockPaginatedResultInfo } from '../fragments'; import { mockAnyPaginatedResponse, mockAnyResponse } from './mockAnyPaginatedResponse'; +export function mockProfileResponse({ + variables, + result, +}: { + variables: ProfileVariables; + result: Profile | null; +}) { + return mockAnyResponse({ + request: { + query: ProfileDocument, + variables, + }, + result: { + data: { result }, + }, + }); +} + export function mockProfilesResponse({ variables, items, @@ -187,21 +205,3 @@ export function mockWhoReactedToPublicationResponse({ query: WhoReactedPublicationDocument, }); } - -export function mockProfileResponse({ - variables, - result, -}: { - variables: ProfileVariables; - result: Profile | null; -}) { - return mockAnyResponse({ - request: { - query: ProfileDocument, - variables, - }, - result: { - data: { result }, - }, - }); -} diff --git a/packages/api-bindings/src/lens/__helpers__/queries/publication.ts b/packages/api-bindings/src/lens/__helpers__/queries/publication.ts index a8803ba7b8..e6344cbd27 100644 --- a/packages/api-bindings/src/lens/__helpers__/queries/publication.ts +++ b/packages/api-bindings/src/lens/__helpers__/queries/publication.ts @@ -1,6 +1,3 @@ -import { faker } from '@faker-js/faker'; - -import { Cursor } from '../../Cursor'; import { PaginatedResultInfo, PublicationDocument, @@ -12,30 +9,24 @@ import { } from '../../graphql/generated'; import { AnyPublication, PrimaryPublication } from '../../publication'; import { mockPaginatedResultInfo } from '../fragments'; -import { mockAnyPaginatedResponse } from './mockAnyPaginatedResponse'; - -export function mockCursor(): Cursor { - return faker.random.alphaNumeric(10) as Cursor; -} +import { mockAnyPaginatedResponse, mockAnyResponse } from './mockAnyPaginatedResponse'; export function mockPublicationResponse({ variables, - publication, + result, }: { variables: PublicationVariables; - publication: AnyPublication | null; + result: AnyPublication | null; }) { - return { + return mockAnyResponse({ request: { query: PublicationDocument, variables, }, result: { - data: { - result: publication, - }, + data: { result }, }, - }; + }); } export function mockPublicationsResponse({ diff --git a/packages/react/src/profile/__tests__/useProfile.spec.ts b/packages/react/src/profile/__tests__/useProfile.spec.ts new file mode 100644 index 0000000000..04c6bfc360 --- /dev/null +++ b/packages/react/src/profile/__tests__/useProfile.spec.ts @@ -0,0 +1,54 @@ +import { mockProfileFragment, mockProfileResponse } from '@lens-protocol/api-bindings/mocks'; +import { waitFor } from '@testing-library/react'; + +import { NotFoundError } from '../../NotFoundError'; +import { setupHookTestScenario } from '../../__helpers__/setupHookTestScenario'; +import { useProfile } from '../useProfile'; + +describe(`Given the ${useProfile.name} hook`, () => { + const profile = mockProfileFragment(); + const expectations = { __typename: 'Profile', id: profile.id }; + + describe.each([ + { + description: 'when invoked with a profile id', + args: { forProfileId: profile.id }, + }, + { + description: 'when invoked with a profile handle', + args: { forHandle: profile.handle }, + }, + ])('$description', ({ args }) => { + it('should settle with the profile data', async () => { + const { renderHook } = setupHookTestScenario([ + mockProfileResponse({ + variables: { + request: args, + }, + result: profile, + }), + ]); + + const { result } = renderHook(() => useProfile(args)); + + await waitFor(() => expect(result.current.loading).toBeFalsy()); + expect(result.current.data).toMatchObject(expectations); + }); + + it(`should settle with a ${NotFoundError.name} if not found`, async () => { + const { renderHook } = setupHookTestScenario([ + mockProfileResponse({ + variables: { + request: args, + }, + result: null, + }), + ]); + + const { result } = renderHook(() => useProfile(args)); + + await waitFor(() => expect(result.current.loading).toBeFalsy()); + expect(result.current.error).toBeInstanceOf(NotFoundError); + }); + }); +}); diff --git a/packages/react/src/publication/__tests__/usePublication.spec.ts b/packages/react/src/publication/__tests__/usePublication.spec.ts new file mode 100644 index 0000000000..1b091dd330 --- /dev/null +++ b/packages/react/src/publication/__tests__/usePublication.spec.ts @@ -0,0 +1,51 @@ +import { mockPostFragment, mockPublicationResponse } from '@lens-protocol/api-bindings/mocks'; +import { waitFor } from '@testing-library/react'; + +import { NotFoundError } from '../../NotFoundError'; +import { setupHookTestScenario } from '../../__helpers__/setupHookTestScenario'; +import { usePublication } from '../usePublication'; + +describe(`Given the ${usePublication.name} hook`, () => { + const publication = mockPostFragment(); + const expectations = { __typename: 'Post', id: publication.id }; + + describe('when the queried publication exists', () => { + const { renderHook } = setupHookTestScenario([ + mockPublicationResponse({ + variables: { + request: { + forId: publication.id, + }, + }, + result: publication, + }), + ]); + + it('should settle with the publication data', async () => { + const { result } = renderHook(() => usePublication({ forId: publication.id })); + + await waitFor(() => expect(result.current.loading).toBeFalsy()); + expect(result.current.data).toMatchObject(expectations); + }); + }); + + describe('when the queried publication does not exist', () => { + const { renderHook } = setupHookTestScenario([ + mockPublicationResponse({ + variables: { + request: { + forId: publication.id, + }, + }, + result: null, + }), + ]); + + it(`should settle with a ${NotFoundError.name} state`, async () => { + const { result } = renderHook(() => usePublication({ forId: publication.id })); + + await waitFor(() => expect(result.current.loading).toBeFalsy()); + expect(result.current.error).toBeInstanceOf(NotFoundError); + }); + }); +});