diff options
Diffstat (limited to '__tests__/view/com')
-rw-r--r-- | __tests__/view/com/composer/Autocomplete.test.tsx | 43 | ||||
-rw-r--r-- | __tests__/view/com/composer/ComposePost.test.tsx | 117 | ||||
-rw-r--r-- | __tests__/view/com/composer/PhotoCarouselPicker.test.tsx | 92 | ||||
-rw-r--r-- | __tests__/view/com/composer/SelectedPhoto.test.tsx | 70 | ||||
-rw-r--r-- | __tests__/view/com/login/CreateAccount.test.tsx | 60 | ||||
-rw-r--r-- | __tests__/view/com/login/Signin.test.tsx | 128 | ||||
-rw-r--r-- | __tests__/view/com/profile/ProfileHeader.test.tsx | 109 |
7 files changed, 619 insertions, 0 deletions
diff --git a/__tests__/view/com/composer/Autocomplete.test.tsx b/__tests__/view/com/composer/Autocomplete.test.tsx new file mode 100644 index 000000000..57539b75e --- /dev/null +++ b/__tests__/view/com/composer/Autocomplete.test.tsx @@ -0,0 +1,43 @@ +import React from 'react' +import {Autocomplete} from '../../../../src/view/com/composer/Autocomplete' +import {cleanup, fireEvent, render} from '../../../../jest/test-utils' + +describe('Autocomplete', () => { + const onSelectMock = jest.fn() + const mockedProps = { + active: true, + items: [ + { + handle: 'handle.test', + displayName: 'Test Display', + }, + { + handle: 'handle2.test', + displayName: 'Test Display 2', + }, + ], + onSelect: onSelectMock, + } + + afterAll(() => { + jest.clearAllMocks() + cleanup() + }) + + it('renders a button for each user', async () => { + const {findAllByTestId} = render(<Autocomplete {...mockedProps} />) + const autocompleteButton = await findAllByTestId('autocompleteButton') + expect(autocompleteButton.length).toBe(2) + }) + + it('triggers onSelect by pressing the button', async () => { + const {findAllByTestId} = render(<Autocomplete {...mockedProps} />) + const autocompleteButton = await findAllByTestId('autocompleteButton') + + fireEvent.press(autocompleteButton[0]) + expect(onSelectMock).toHaveBeenCalledWith('handle.test') + + fireEvent.press(autocompleteButton[1]) + expect(onSelectMock).toHaveBeenCalledWith('handle2.test') + }) +}) diff --git a/__tests__/view/com/composer/ComposePost.test.tsx b/__tests__/view/com/composer/ComposePost.test.tsx new file mode 100644 index 000000000..84377f62f --- /dev/null +++ b/__tests__/view/com/composer/ComposePost.test.tsx @@ -0,0 +1,117 @@ +import React from 'react' +import {ComposePost} from '../../../../src/view/com/composer/ComposePost' +import {cleanup, fireEvent, render, waitFor} from '../../../../jest/test-utils' +import * as apilib from '../../../../src/state/lib/api' +import { + mockedAutocompleteViewStore, + mockedRootStore, +} from '../../../../__mocks__/state-mock' +import Toast from 'react-native-root-toast' + +describe('ComposePost', () => { + const mockedProps = { + replyTo: { + uri: 'testUri', + cid: 'testCid', + text: 'testText', + author: { + handle: 'test.handle', + displayName: 'test name', + avatar: '', + }, + }, + onPost: jest.fn(), + onClose: jest.fn(), + } + + afterAll(() => { + jest.clearAllMocks() + cleanup() + }) + + it('renders post composer', async () => { + const {findByTestId} = render(<ComposePost {...mockedProps} />) + const composePostView = await findByTestId('composePostView') + expect(composePostView).toBeTruthy() + }) + + it('closes composer', async () => { + const {findByTestId} = render(<ComposePost {...mockedProps} />) + const composerCancelButton = await findByTestId('composerCancelButton') + fireEvent.press(composerCancelButton) + expect(mockedProps.onClose).toHaveBeenCalled() + }) + + it('changes text and publishes post', async () => { + const postSpy = jest.spyOn(apilib, 'post').mockResolvedValue({ + uri: '', + cid: '', + }) + const toastSpy = jest.spyOn(Toast, 'show') + + const wrapper = render(<ComposePost {...mockedProps} />) + + const composerTextInput = await wrapper.findByTestId('composerTextInput') + fireEvent.changeText(composerTextInput, 'testing publish') + + const composerPublishButton = await wrapper.findByTestId( + 'composerPublishButton', + ) + fireEvent.press(composerPublishButton) + + expect(postSpy).toHaveBeenCalledWith( + mockedRootStore, + 'testing publish', + 'testUri', + [], + new Set<string>(), + expect.anything(), + ) + + // Waits for request to be resolved + await waitFor(() => { + expect(mockedProps.onPost).toHaveBeenCalled() + expect(mockedProps.onClose).toHaveBeenCalled() + expect(toastSpy).toHaveBeenCalledWith('Your reply has been published', { + animation: true, + duration: 3500, + hideOnPress: true, + position: 50, + shadow: true, + }) + }) + }) + + it('selects autocomplete item', async () => { + jest + .spyOn(React, 'useMemo') + .mockReturnValueOnce(mockedAutocompleteViewStore) + + const {findAllByTestId} = render(<ComposePost {...mockedProps} />) + const autocompleteButton = await findAllByTestId('autocompleteButton') + + fireEvent.press(autocompleteButton[0]) + expect(mockedAutocompleteViewStore.setActive).toHaveBeenCalledWith(false) + }) + + it('selects photos', async () => { + const {findByTestId, queryByTestId} = render( + <ComposePost {...mockedProps} />, + ) + let photoCarouselPickerView = queryByTestId('photoCarouselPickerView') + expect(photoCarouselPickerView).toBeFalsy() + + const composerSelectPhotosButton = await findByTestId( + 'composerSelectPhotosButton', + ) + fireEvent.press(composerSelectPhotosButton) + + photoCarouselPickerView = await findByTestId('photoCarouselPickerView') + expect(photoCarouselPickerView).toBeTruthy() + + fireEvent.press(composerSelectPhotosButton) + + photoCarouselPickerView = queryByTestId('photoCarouselPickerView') + expect(photoCarouselPickerView).toBeFalsy() + }) +}) diff --git a/__tests__/view/com/composer/PhotoCarouselPicker.test.tsx b/__tests__/view/com/composer/PhotoCarouselPicker.test.tsx new file mode 100644 index 000000000..ef8477652 --- /dev/null +++ b/__tests__/view/com/composer/PhotoCarouselPicker.test.tsx @@ -0,0 +1,92 @@ +import React from 'react' +import {PhotoCarouselPicker} from '../../../../src/view/com/composer/PhotoCarouselPicker' +import {cleanup, fireEvent, render} from '../../../../jest/test-utils' +import { + openCamera, + openCropper, + openPicker, +} from 'react-native-image-crop-picker' + +describe('PhotoCarouselPicker', () => { + const mockedProps = { + selectedPhotos: ['mock-uri', 'mock-uri-2'], + onSelectPhotos: jest.fn(), + localPhotos: { + photos: [ + { + node: { + image: { + uri: 'mock-uri', + }, + }, + }, + ], + }, + } + + afterAll(() => { + jest.clearAllMocks() + cleanup() + }) + + it('renders carousel picker', async () => { + const {findByTestId} = render(<PhotoCarouselPicker {...mockedProps} />) + const photoCarouselPickerView = await findByTestId( + 'photoCarouselPickerView', + ) + expect(photoCarouselPickerView).toBeTruthy() + }) + + it('triggers openCamera', async () => { + const {findByTestId} = render(<PhotoCarouselPicker {...mockedProps} />) + const openCameraButton = await findByTestId('openCameraButton') + fireEvent.press(openCameraButton) + + expect(openCamera).toHaveBeenCalledWith({ + compressImageQuality: 1, + cropping: true, + forceJpg: true, + freeStyleCropEnabled: true, + height: 1000, + mediaType: 'photo', + width: 1000, + }) + }) + + it('triggers openCropper', async () => { + const {findByTestId} = render(<PhotoCarouselPicker {...mockedProps} />) + const openSelectPhotoButton = await findByTestId('openSelectPhotoButton') + fireEvent.press(openSelectPhotoButton) + + expect(openCropper).toHaveBeenCalledWith({ + compressImageQuality: 1, + forceJpg: true, + freeStyleCropEnabled: true, + height: 1000, + mediaType: 'photo', + path: 'mock-uri', + width: 1000, + }) + }) + + it('triggers openPicker', async () => { + const {findByTestId} = render(<PhotoCarouselPicker {...mockedProps} />) + const openGalleryButton = await findByTestId('openGalleryButton') + fireEvent.press(openGalleryButton) + + expect(openPicker).toHaveBeenCalledWith({ + maxFiles: 2, + mediaType: 'photo', + multiple: true, + }) + expect(openCropper).toHaveBeenCalledWith({ + compressImageQuality: 1, + forceJpg: true, + freeStyleCropEnabled: true, + height: 1000, + mediaType: 'photo', + path: 'mock-uri', + width: 1000, + }) + }) +}) diff --git a/__tests__/view/com/composer/SelectedPhoto.test.tsx b/__tests__/view/com/composer/SelectedPhoto.test.tsx new file mode 100644 index 000000000..26059ae30 --- /dev/null +++ b/__tests__/view/com/composer/SelectedPhoto.test.tsx @@ -0,0 +1,70 @@ +import React from 'react' +import {SelectedPhoto} from '../../../../src/view/com/composer/SelectedPhoto' +import {cleanup, fireEvent, render} from '../../../../jest/test-utils' + +describe('SelectedPhoto', () => { + const mockedProps = { + selectedPhotos: ['mock-uri', 'mock-uri-2'], + onSelectPhotos: jest.fn(), + } + + afterAll(() => { + jest.clearAllMocks() + cleanup() + }) + + it('has no photos to render', () => { + const {queryByTestId} = render( + <SelectedPhoto selectedPhotos={[]} onSelectPhotos={jest.fn()} />, + ) + const selectedPhotosView = queryByTestId('selectedPhotosView') + expect(selectedPhotosView).toBeNull() + + const selectedPhotoImage = queryByTestId('selectedPhotoImage') + expect(selectedPhotoImage).toBeNull() + }) + + it('has 1 photos to render', async () => { + const {findByTestId} = render( + <SelectedPhoto + selectedPhotos={['mock-uri']} + onSelectPhotos={jest.fn()} + />, + ) + const selectedPhotosView = await findByTestId('selectedPhotosView') + expect(selectedPhotosView).toBeTruthy() + + const selectedPhotoImage = await findByTestId('selectedPhotoImage') + expect(selectedPhotoImage).toBeTruthy() + // @ts-expect-error + expect(selectedPhotoImage).toHaveStyle({width: 250}) + }) + + it('has 2 photos to render', async () => { + const {findAllByTestId} = render(<SelectedPhoto {...mockedProps} />) + const selectedPhotoImage = await findAllByTestId('selectedPhotoImage') + expect(selectedPhotoImage[0]).toBeTruthy() + // @ts-expect-error + expect(selectedPhotoImage[0]).toHaveStyle({width: 175}) + }) + + it('has 3 photos to render', async () => { + const {findAllByTestId} = render( + <SelectedPhoto + selectedPhotos={['mock-uri', 'mock-uri-2', 'mock-uri-3']} + onSelectPhotos={jest.fn()} + />, + ) + const selectedPhotoImage = await findAllByTestId('selectedPhotoImage') + expect(selectedPhotoImage[0]).toBeTruthy() + // @ts-expect-error + expect(selectedPhotoImage[0]).toHaveStyle({width: 85}) + }) + + it('removes a photo', async () => { + const {findAllByTestId} = render(<SelectedPhoto {...mockedProps} />) + const removePhotoButton = await findAllByTestId('removePhotoButton') + fireEvent.press(removePhotoButton[0]) + expect(mockedProps.onSelectPhotos).toHaveBeenCalledWith(['mock-uri-2']) + }) +}) diff --git a/__tests__/view/com/login/CreateAccount.test.tsx b/__tests__/view/com/login/CreateAccount.test.tsx new file mode 100644 index 000000000..2de99b2a3 --- /dev/null +++ b/__tests__/view/com/login/CreateAccount.test.tsx @@ -0,0 +1,60 @@ +import React from 'react' +import {Keyboard} from 'react-native' +import {CreateAccount} from '../../../../src/view/com/login/CreateAccount' +import {cleanup, fireEvent, render} from '../../../../jest/test-utils' +import { + mockedLogStore, + mockedRootStore, + mockedSessionStore, + mockedShellStore, +} from '../../../../__mocks__/state-mock' + +describe('CreateAccount', () => { + const mockedProps = { + onPressBack: jest.fn(), + } + afterAll(() => { + jest.clearAllMocks() + cleanup() + }) + + it('renders form and creates new account', async () => { + const {findByTestId} = render(<CreateAccount {...mockedProps} />) + + const registerEmailInput = await findByTestId('registerEmailInput') + expect(registerEmailInput).toBeTruthy() + fireEvent.changeText(registerEmailInput, 'test@email.com') + + const registerHandleInput = await findByTestId('registerHandleInput') + expect(registerHandleInput).toBeTruthy() + fireEvent.changeText(registerHandleInput, 'test.handle') + + const registerPasswordInput = await findByTestId('registerPasswordInput') + expect(registerPasswordInput).toBeTruthy() + fireEvent.changeText(registerPasswordInput, 'testpass') + + const registerIs13Input = await findByTestId('registerIs13Input') + expect(registerIs13Input).toBeTruthy() + fireEvent.press(registerIs13Input) + + const createAccountButton = await findByTestId('createAccountButton') + expect(createAccountButton).toBeTruthy() + fireEvent.press(createAccountButton) + + expect(mockedSessionStore.createAccount).toHaveBeenCalled() + }) + + it('renders and selects service', async () => { + const keyboardSpy = jest.spyOn(Keyboard, 'dismiss') + const {findByTestId} = render(<CreateAccount {...mockedProps} />) + + const registerSelectServiceButton = await findByTestId( + 'registerSelectServiceButton', + ) + expect(registerSelectServiceButton).toBeTruthy() + fireEvent.press(registerSelectServiceButton) + + expect(mockedShellStore.openModal).toHaveBeenCalled() + expect(keyboardSpy).toHaveBeenCalled() + }) +}) diff --git a/__tests__/view/com/login/Signin.test.tsx b/__tests__/view/com/login/Signin.test.tsx new file mode 100644 index 000000000..51b411836 --- /dev/null +++ b/__tests__/view/com/login/Signin.test.tsx @@ -0,0 +1,128 @@ +import React from 'react' +import {Signin} from '../../../../src/view/com/login/Signin' +import {cleanup, fireEvent, render} from '../../../../jest/test-utils' +import {SessionServiceClient, sessionClient as AtpApi} from '@atproto/api' +import { + mockedLogStore, + mockedRootStore, + mockedSessionStore, + mockedShellStore, +} from '../../../../__mocks__/state-mock' +import {Keyboard} from 'react-native' + +describe('Signin', () => { + const requestPasswordResetMock = jest.fn() + const resetPasswordMock = jest.fn() + jest.spyOn(AtpApi, 'service').mockReturnValue({ + com: { + atproto: { + account: { + requestPasswordReset: requestPasswordResetMock, + resetPassword: resetPasswordMock, + }, + }, + }, + } as unknown as SessionServiceClient) + const mockedProps = { + onPressBack: jest.fn(), + } + afterAll(() => { + jest.clearAllMocks() + cleanup() + }) + + it('renders logs in form', async () => { + const {findByTestId} = render(<Signin {...mockedProps} />) + + const loginFormView = await findByTestId('loginFormView') + expect(loginFormView).toBeTruthy() + + const loginUsernameInput = await findByTestId('loginUsernameInput') + expect(loginUsernameInput).toBeTruthy() + + fireEvent.changeText(loginUsernameInput, 'testusername') + + const loginPasswordInput = await findByTestId('loginPasswordInput') + expect(loginPasswordInput).toBeTruthy() + + fireEvent.changeText(loginPasswordInput, 'test pass') + + const loginNextButton = await findByTestId('loginNextButton') + expect(loginNextButton).toBeTruthy() + + fireEvent.press(loginNextButton) + + expect(mockedSessionStore.login).toHaveBeenCalled() + }) + + it('renders selects service from login form', async () => { + const keyboardSpy = jest.spyOn(Keyboard, 'dismiss') + const {findByTestId} = render(<Signin {...mockedProps} />) + + const loginSelectServiceButton = await findByTestId( + 'loginSelectServiceButton', + ) + expect(loginSelectServiceButton).toBeTruthy() + + fireEvent.press(loginSelectServiceButton) + + expect(mockedShellStore.openModal).toHaveBeenCalled() + expect(keyboardSpy).toHaveBeenCalled() + }) + + it('renders new password form', async () => { + const {findByTestId} = render(<Signin {...mockedProps} />) + + const forgotPasswordButton = await findByTestId('forgotPasswordButton') + expect(forgotPasswordButton).toBeTruthy() + + fireEvent.press(forgotPasswordButton) + const forgotPasswordView = await findByTestId('forgotPasswordView') + expect(forgotPasswordView).toBeTruthy() + + const forgotPasswordEmail = await findByTestId('forgotPasswordEmail') + expect(forgotPasswordEmail).toBeTruthy() + fireEvent.changeText(forgotPasswordEmail, 'test@email.com') + + const newPasswordButton = await findByTestId('newPasswordButton') + expect(newPasswordButton).toBeTruthy() + fireEvent.press(newPasswordButton) + + expect(requestPasswordResetMock).toHaveBeenCalled() + + const newPasswordView = await findByTestId('newPasswordView') + expect(newPasswordView).toBeTruthy() + + const newPasswordInput = await findByTestId('newPasswordInput') + expect(newPasswordInput).toBeTruthy() + const resetCodeInput = await findByTestId('resetCodeInput') + expect(resetCodeInput).toBeTruthy() + + fireEvent.changeText(newPasswordInput, 'test pass') + fireEvent.changeText(resetCodeInput, 'test reset code') + + const setNewPasswordButton = await findByTestId('setNewPasswordButton') + expect(setNewPasswordButton).toBeTruthy() + + fireEvent.press(setNewPasswordButton) + + expect(resetPasswordMock).toHaveBeenCalled() + }) + + it('renders forgot password form', async () => { + const {findByTestId} = render(<Signin {...mockedProps} />) + + const forgotPasswordButton = await findByTestId('forgotPasswordButton') + expect(forgotPasswordButton).toBeTruthy() + + fireEvent.press(forgotPasswordButton) + const forgotPasswordSelectServiceButton = await findByTestId( + 'forgotPasswordSelectServiceButton', + ) + expect(forgotPasswordSelectServiceButton).toBeTruthy() + + fireEvent.press(forgotPasswordSelectServiceButton) + + expect(mockedShellStore.openModal).toHaveBeenCalled() + }) +}) diff --git a/__tests__/view/com/profile/ProfileHeader.test.tsx b/__tests__/view/com/profile/ProfileHeader.test.tsx new file mode 100644 index 000000000..52b04e649 --- /dev/null +++ b/__tests__/view/com/profile/ProfileHeader.test.tsx @@ -0,0 +1,109 @@ +import React from 'react' +import {cleanup, fireEvent, render} from '../../../../jest/test-utils' +import {ProfileViewModel} from '../../../../src/state/models/profile-view' +import {ProfileHeader} from '../../../../src/view/com/profile/ProfileHeader' +import { + mockedNavigationStore, + mockedProfileStore, + mockedShellStore, +} from '../../../../__mocks__/state-mock' + +describe('ProfileHeader', () => { + const mockedProps = { + view: mockedProfileStore, + onRefreshAll: jest.fn(), + } + afterAll(() => { + jest.clearAllMocks() + cleanup() + }) + + it('renders ErrorMessage on error', async () => { + const {findByTestId} = render( + <ProfileHeader + {...{ + view: { + ...mockedProfileStore, + hasError: true, + } as ProfileViewModel, + onRefreshAll: jest.fn(), + }} + />, + ) + + const profileHeaderHasError = await findByTestId('profileHeaderHasError') + expect(profileHeaderHasError).toBeTruthy() + }) + + it('presses and opens edit profile', async () => { + const {findByTestId} = render(<ProfileHeader {...mockedProps} />) + + const profileHeaderEditProfileButton = await findByTestId( + 'profileHeaderEditProfileButton', + ) + expect(profileHeaderEditProfileButton).toBeTruthy() + fireEvent.press(profileHeaderEditProfileButton) + + expect(mockedShellStore.openModal).toHaveBeenCalled() + }) + + it('presses and opens followers page', async () => { + const {findByTestId} = render(<ProfileHeader {...mockedProps} />) + + const profileHeaderFollowersButton = await findByTestId( + 'profileHeaderFollowersButton', + ) + expect(profileHeaderFollowersButton).toBeTruthy() + fireEvent.press(profileHeaderFollowersButton) + + expect(mockedNavigationStore.navigate).toHaveBeenCalledWith( + '/profile/testhandle/followers', + ) + }) + + it('presses and opens avatar modal', async () => { + const {findByTestId} = render(<ProfileHeader {...mockedProps} />) + + const profileHeaderAviButton = await findByTestId('profileHeaderAviButton') + expect(profileHeaderAviButton).toBeTruthy() + fireEvent.press(profileHeaderAviButton) + + expect(mockedShellStore.openLightbox).toHaveBeenCalled() + }) + + it('presses and opens follows page', async () => { + const {findByTestId} = render(<ProfileHeader {...mockedProps} />) + + const profileHeaderFollowsButton = await findByTestId( + 'profileHeaderFollowsButton', + ) + expect(profileHeaderFollowsButton).toBeTruthy() + fireEvent.press(profileHeaderFollowsButton) + + expect(mockedNavigationStore.navigate).toHaveBeenCalledWith( + '/profile/testhandle/follows', + ) + }) + + it('toggles following', async () => { + const {findByTestId} = render( + <ProfileHeader + {...{ + view: { + ...mockedProfileStore, + did: 'test did 2', + } as ProfileViewModel, + onRefreshAll: jest.fn(), + }} + />, + ) + + const profileHeaderToggleFollowButton = await findByTestId( + 'profileHeaderToggleFollowButton', + ) + expect(profileHeaderToggleFollowButton).toBeTruthy() + fireEvent.press(profileHeaderToggleFollowButton) + + expect(mockedProps.view.toggleFollowing).toHaveBeenCalled() + }) +}) |