Unit Testing (#35)

* add testing lib

* remove coverage folder from git

* finished basic test setup

* fix tests typescript and import paths

* add first snapshot

* testing utils

* rename test files; update script flags; ++tests

* testing utils functions

* testing downloadAndResize wip

* remove download test

* specify unwanted coverage paths;
remove update snapshots flag

* fix strings tests

* testing downloadAndResize method

* increasing testing

* fixing snapshots wip

* fixed shell mobile snapshot

* adding snapshots for the screens

* fix onboard snapshot

* fix typescript issues

* fix TabsSelector snapshot

* Account for testing device's locale in ago() tests

* Remove platform detection on regex

* mocking store state wip

* mocking store state

* increasing test coverage

* increasing test coverage

* increasing test coverage on src/screens

* src/screens (except for profile) above 80% cov

* testing profile screen wip

* increase coverage on Menu and TabsSelector

* mocking profile ui state wip

* mocking profile ui state wip

* fixing mobileshell tests wip

* snapshots using testing-library

* fixing profile tests wip

* removing mobile shell tests

* src/view/com tests wip

* remove unnecessary patch-package

* fixed profile test error

* clear mocks after every test

* fix base mocked store values (getters)

* fix base mocked store values
(hasLoaded, nonReplyFeed)

* profile screen above 80% coverage

* testing custom hooks

* improving composer coverage

* fix tests after merge

* finishing composer coverage

* improving src/com/discover coverage

* improve src/view/com/login coverage
fix SuggestedFollows tests
adding some comments

* fix SuggestedFollows tests

* improve src/view/com/profile coverage
extra minor fixes

* improve src/view/com/notifications coverage

* update coverage ignore patterns

* rename errorMessageTryAgainButton
increase SuggestedFollows converage

* improve src/view/com/posts coverage

* improve src/view/com/onboard coverage

* update snapshot

* improve src/view/com/post coverage

* improve src/view/com/post-thread coverage
rename ErrorMessage tests
test Debug and Log components

* init testing state

* testing root-store

* updating comments

* small fixes

* removed extra console logs

* improve src/state/models coverage
refactor rootStore
rename some spies

* adding cleanup method after tests

* improve src/state/models coverage

* improve src/state/models coverage

* improve src/state/models coverage

* improve src/state/models coverage

* test setInterval in setupState

* Clean up tests and update Home screen state management

* Remove some tests we dont need

* Remove snapshot tests

* Remove any tests that dont demonstrate clear value

* Cleanup

Co-authored-by: Paul Frazee <pfrazee@gmail.com>
zio/stable
João Ferreiro 2023-01-17 16:06:00 +00:00 committed by GitHub
parent 11c861d2d3
commit 5abcc8e336
95 changed files with 2852 additions and 9936 deletions

View File

@ -1,3 +1,9 @@
export default { export const CameraRoll = {
CameraRoll: jest.fn(), getPhotos: jest.fn().mockResolvedValue({
edges: [
{node: {image: {uri: 'path/to/image1.jpg'}}},
{node: {image: {uri: 'path/to/image2.jpg'}}},
{node: {image: {uri: 'path/to/image3.jpg'}}},
],
}),
} }

View File

@ -1,3 +1,9 @@
export default { export const openPicker = jest
openPicker: jest.fn().mockImplementation(() => Promise.resolve(result)), .fn()
} .mockImplementation(() => Promise.resolve({uri: ''}))
export const openCamera = jest
.fn()
.mockImplementation(() => Promise.resolve({uri: ''}))
export const openCropper = jest
.fn()
.mockImplementation(() => Promise.resolve({uri: ''}))

View File

@ -0,0 +1,934 @@
import {LogModel} from './../src/state/models/log'
import {LRUMap} from 'lru_map'
import {RootStoreModel} from './../src/state/models/root-store'
import {NavigationTabModel} from './../src/state/models/navigation'
import {SessionModel} from '../src/state/models/session'
import {NavigationModel} from '../src/state/models/navigation'
import {ShellUiModel} from '../src/state/models/shell-ui'
import {MeModel} from '../src/state/models/me'
import {OnboardModel} from '../src/state/models/onboard'
import {ProfilesViewModel} from '../src/state/models/profiles-view'
import {LinkMetasViewModel} from '../src/state/models/link-metas-view'
import {MembershipsViewModel} from '../src/state/models/memberships-view'
import {FeedModel} from '../src/state/models/feed-view'
import {NotificationsViewModel} from '../src/state/models/notifications-view'
import {ProfileViewModel} from '../src/state/models/profile-view'
import {MembersViewModel} from '../src/state/models/members-view'
import {ProfileUiModel, Sections} from '../src/state/models/profile-ui'
import {SessionServiceClient} from '@atproto/api'
import {UserAutocompleteViewModel} from '../src/state/models/user-autocomplete-view'
import {UserLocalPhotosModel} from '../src/state/models/user-local-photos'
import {SuggestedActorsViewModel} from '../src/state/models/suggested-actors-view'
import {UserFollowersViewModel} from '../src/state/models/user-followers-view'
import {UserFollowsViewModel} from '../src/state/models/user-follows-view'
import {NotificationsViewItemModel} from './../src/state/models/notifications-view'
import {
PostThreadViewModel,
PostThreadViewPostModel,
} from '../src/state/models/post-thread-view'
import {FeedItemModel} from '../src/state/models/feed-view'
import {RepostedByViewModel} from '../src/state/models/reposted-by-view'
import {VotesViewModel} from '../src/state/models/votes-view'
export const mockedProfileStore = {
isLoading: false,
isRefreshing: false,
hasLoaded: true,
error: '',
params: {
actor: '',
},
did: 'test did',
handle: 'testhandle',
declaration: {
cid: '',
actorType: '',
},
creator: 'test did',
displayName: '',
description: '',
avatar: '',
banner: '',
followersCount: 0,
followsCount: 0,
membersCount: 0,
postsCount: 0,
myState: {
follow: '',
member: '',
},
rootStore: {} as RootStoreModel,
hasContent: true,
hasError: false,
isEmpty: false,
isUser: true,
isScene: false,
setup: jest.fn().mockResolvedValue({aborted: false}),
refresh: jest.fn(),
toggleFollowing: jest.fn().mockResolvedValue({}),
updateProfile: jest.fn(),
// unknown required because of the missing private methods: _xLoading, _xIdle, _load, _replaceAll
} as unknown as ProfileViewModel
export const mockedMembersStore = {
isLoading: false,
isRefreshing: false,
hasLoaded: true,
error: '',
params: {
actor: 'test actor',
},
subject: {
did: 'test did',
handle: '',
displayName: '',
declaration: {
cid: '',
actorType: '',
},
avatar: undefined,
},
members: [
{
did: 'test did2',
declaration: {
cid: '',
actorType: '',
},
handle: 'testhandle',
displayName: 'test name',
indexedAt: '',
},
],
rootStore: {} as RootStoreModel,
hasContent: true,
hasError: false,
isEmpty: false,
isMember: jest.fn(),
setup: jest.fn().mockResolvedValue({aborted: false}),
refresh: jest.fn(),
loadMore: jest.fn(),
removeMember: jest.fn(),
// unknown required because of the missing private methods: _xLoading, _xIdle, _fetch, _replaceAll, _append
} as unknown as MembersViewModel
export const mockedMembershipsStore = {
isLoading: false,
isRefreshing: false,
hasLoaded: true,
error: '',
params: {
actor: '',
limit: 1,
before: '',
},
subject: {
did: 'test did',
handle: '',
displayName: '',
declaration: {cid: '', actorType: ''},
avatar: undefined,
},
memberships: [
{
did: 'test did',
declaration: {
cid: '',
actorType: 'app.bsky.system.actorUser',
},
handle: ',',
displayName: '',
createdAt: '',
indexedAt: '',
_reactKey: 'item-1',
},
],
rootStore: {} as RootStoreModel,
hasContent: true,
hasError: false,
isEmpty: false,
isMemberOf: jest.fn(),
setup: jest.fn().mockResolvedValue({aborted: false}),
refresh: jest.fn(),
loadMore: jest.fn(),
// unknown required because of the missing private methods: _xLoading, _xIdle, _fetch, _replaceAll, _append
} as unknown as MembershipsViewModel
export const mockedFeedItemStore = {
_reactKey: 'item-1',
_isThreadParent: false,
_isThreadChildElided: false,
_isThreadChild: false,
post: {
uri: 'testuri',
cid: 'test cid',
author: {
did: 'test did',
handle: 'test.handle',
displayName: 'test name',
declaration: {cid: '', actorType: ''},
},
record: {
$type: 'app.bsky.feed.post',
createdAt: '2022-12-29T16:39:57.919Z',
text: 'Sup',
},
replyCount: 0,
repostCount: 0,
upvoteCount: 0,
downvoteCount: 0,
indexedAt: '2022-12-29T16:39:57.919Z',
viewer: {},
},
postRecord: {
$type: 'app.bsky.feed.post',
text: 'test text',
createdAt: '1',
reply: {
root: {
uri: 'testuri',
cid: 'tes cid',
},
parent: {
uri: 'testuri',
cid: 'tes cid',
},
},
},
rootStore: {} as RootStoreModel,
copy: jest.fn(),
toggleUpvote: jest.fn().mockResolvedValue({}),
toggleDownvote: jest.fn(),
toggleRepost: jest.fn().mockResolvedValue({}),
delete: jest.fn().mockResolvedValue({}),
reasonRepost: {
by: {
did: 'test did',
handle: 'test.handle',
declaration: {cid: '', actorType: ''},
},
indexedAt: '',
},
reasonTrend: {
by: {
did: 'test did',
handle: 'test.handle',
declaration: {cid: '', actorType: ''},
},
indexedAt: '',
},
reply: {
parent: {
author: {
did: 'test did',
handle: 'test.handle',
displayName: 'test name',
declaration: {cid: '', actorType: ''},
},
cid: '',
downvoteCount: 0,
indexedAt: '2023-01-10T11:17:46.945Z',
record: {},
replyCount: 1,
repostCount: 0,
upvoteCount: 0,
uri: 'testuri',
viewer: {},
},
root: {
author: {
did: 'test did',
handle: 'test.handle',
displayName: 'test name',
declaration: {cid: '', actorType: ''},
},
cid: '',
downvoteCount: 0,
indexedAt: '2023-01-10T11:17:46.739Z',
record: {},
replyCount: 1,
repostCount: 0,
upvoteCount: 1,
uri: 'testuri',
viewer: {},
},
},
} as FeedItemModel
export const mockedFeedStore = {
isLoading: false,
isRefreshing: false,
hasNewLatest: false,
hasLoaded: true,
error: '',
hasMore: true,
params: {
actor: '',
limit: 1,
before: '',
},
feed: [],
rootStore: {} as RootStoreModel,
feedType: 'home',
hasContent: true,
hasError: false,
isEmpty: false,
nonReplyFeed: [
{
_reactKey: 'item-1',
post: {
author: {
handle: 'handle.test',
displayName: 'test name',
avatar: '',
},
cid: 'bafyreihkwjoy2vbfqld2lp3tv4ce6yfr354sqgp32qoplrudso4gyyjiwe',
downvoteCount: 0,
indexedAt: '2022-12-29T16:35:55.270Z',
record: {
$type: 'app.bsky.feed.post',
createdAt: '2022-12-29T16:39:57.919Z',
text: 'Sup',
},
replyCount: 0,
repostCount: 0,
upvoteCount: 0,
uri: 'at://did:plc:wcizmlgv3rdslk64t6q4silu/app.bsky.feed.post/3jkzce5kfvn2h',
viewer: {
handle: 'handle.test',
displayName: 'test name',
avatar: '',
},
},
reason: undefined,
reply: undefined,
},
],
setHasNewLatest: jest.fn(),
setup: jest.fn().mockResolvedValue({}),
refresh: jest.fn().mockResolvedValue({}),
loadMore: jest.fn().mockResolvedValue({}),
loadLatest: jest.fn(),
update: jest.fn(),
checkForLatest: jest.fn().mockRejectedValue('Error checking for latest'),
// unknown required because of the missing private methods: _xLoading, _xIdle, _pendingWork, _initialLoad, _loadLatest, _loadMore, _update, _replaceAll, _appendAll, _prependAll, _updateAll, _getFeed, loadMoreCursor, pollCursor, _loadPromise, _updatePromise, _loadLatestPromise, _loadMorePromise
} as unknown as FeedModel
export const mockedPostThreadViewPostStore = {
_reactKey: 'item-1',
_depth: 0,
_isHighlightedPost: false,
_hasMore: false,
postRecord: {
text: 'test text',
createdAt: '',
reply: {
root: {
uri: 'testuri',
cid: 'tes cid',
},
parent: {
uri: 'testuri',
cid: 'tes cid',
},
},
},
post: {
uri: 'testuri',
cid: 'testcid',
record: {},
author: {
did: 'test did',
handle: 'test.handle',
declaration: {cid: '', actorType: ''},
viewer: {
muted: true,
},
},
replyCount: 0,
repostCount: 0,
upvoteCount: 0,
downvoteCount: 0,
indexedAt: '',
viewer: {
repost: '',
upvote: '',
downvote: '',
},
},
rootStore: {} as RootStoreModel,
assignTreeModels: jest.fn(),
toggleRepost: jest.fn().mockRejectedValue({}),
toggleUpvote: jest.fn().mockRejectedValue({}),
toggleDownvote: jest.fn(),
delete: jest.fn(),
} as PostThreadViewPostModel
export const mockedPostThreadViewStore = {
isLoading: false,
isRefreshing: false,
hasLoaded: false,
error: '',
notFound: false,
resolvedUri: 'testuri',
params: {
uri: 'testuri',
},
thread: mockedPostThreadViewPostStore,
hasContent: true,
hasError: false,
setup: jest.fn(),
refresh: jest.fn().mockResolvedValue({}),
update: jest.fn(),
// unknown required because of the missing private methods: _xLoading, _xIdle, _resolveUri, _load, _replaceAll
} as unknown as PostThreadViewModel
export const mockedNotificationsViewItemStore = {
_reactKey: 'item-1',
uri: 'testuri',
cid: '',
author: {
did: 'test did',
handle: 'test.handle',
declaration: {cid: '', actorType: ''},
},
rootStore: {} as RootStoreModel,
copy: jest.fn(),
reason: 'test reason',
isRead: true,
indexedAt: '',
isUpvote: true,
isRepost: false,
isTrend: false,
isMention: false,
isReply: false,
isFollow: false,
isAssertion: false,
needsAdditionalData: false,
isInvite: false,
subjectUri: 'testuri',
toSupportedRecord: jest.fn().mockReturnValue({
text: 'test text',
createdAt: '',
}),
fetchAdditionalData: jest.fn(),
} as NotificationsViewItemModel
export const mockedNotificationsStore = {
isLoading: false,
isRefreshing: false,
hasLoaded: true,
error: '',
params: {
limit: 1,
before: '',
},
hasMore: true,
notifications: [mockedNotificationsViewItemStore],
rootStore: {} as RootStoreModel,
hasContent: true,
hasError: false,
isEmpty: false,
setup: jest.fn().mockResolvedValue({aborted: false}),
refresh: jest.fn().mockResolvedValue({}),
loadMore: jest.fn().mockResolvedValue({}),
update: jest.fn().mockResolvedValue(null),
updateReadState: jest.fn(),
// unknown required because of the missing private methods: _xLoading, _xIdle, _pendingWork, _initialLoad, _loadMore, _update, _replaceAll, _appendAll, _updateAll, loadMoreCursor, _loadPromise, _updatePromise, _loadLatestPromise, _loadMorePromise
} as unknown as NotificationsViewModel
export const mockedSessionStore = {
serialize: jest.fn(),
hydrate: jest.fn(),
data: {
service: '',
refreshJwt: '',
accessJwt: '',
handle: '',
did: 'test did',
},
online: false,
attemptingConnect: false,
rootStore: {} as RootStoreModel,
hasSession: true,
clear: jest.fn(),
setState: jest.fn(),
setOnline: jest.fn(),
updateAuthTokens: jest.fn(),
connect: jest.fn(),
describeService: jest.fn().mockResolvedValue({
availableUserDomains: ['test'],
links: {
termsOfService: 'https://testTermsOfService',
privacyPolicy: 'https://testPrivacyPolicy',
},
}),
login: jest.fn(),
createAccount: jest.fn(),
logout: jest.fn(),
// unknown required because of the missing private methods: _connectPromise, configureApi & _connect
} as unknown as SessionModel
export const mockedNavigationTabStore = {
serialize: jest.fn(),
hydrate: jest.fn(),
id: 0,
history: [
{
url: '',
ts: 0,
title: '',
id: 0,
},
],
index: 0,
isNewTab: false,
current: {
url: '',
ts: 0,
title: '',
id: 0,
},
canGoBack: false,
canGoForward: false,
backTen: [
{
url: '',
title: '',
index: 0,
id: 0,
},
],
forwardTen: [
{
url: '',
title: '',
index: 0,
id: 0,
},
],
navigate: jest.fn(),
refresh: jest.fn(),
goBack: jest.fn(),
fixedTabReset: jest.fn(),
goForward: jest.fn(),
goToIndex: jest.fn(),
setTitle: jest.fn(),
setIsNewTab: jest.fn(),
fixedTabPurpose: 0,
getBackList: () => [
{
url: '/',
title: '',
index: 1,
id: 1,
},
],
getForwardList: jest.fn(),
} as NavigationTabModel
export const mockedNavigationStore = {
serialize: jest.fn(),
hydrate: jest.fn(),
tabs: [mockedNavigationTabStore],
tabIndex: 0,
clear: jest.fn(),
tab: mockedNavigationTabStore,
tabCount: 1,
isCurrentScreen: jest.fn(),
navigate: jest.fn(),
refresh: jest.fn(),
setTitle: jest.fn(),
handleLink: jest.fn(),
switchTo: jest.fn(),
setActiveTab: jest.fn(),
closeTab: jest.fn(),
newTab: jest.fn(),
} as NavigationModel
export const mockedShellStore = {
serialize: jest.fn(),
hydrate: jest.fn(),
minimalShellMode: false,
isMainMenuOpen: false,
isModalActive: false,
activeModal: undefined,
isLightboxActive: false,
activeLightbox: undefined,
isComposerActive: false,
composerOpts: undefined,
darkMode: false,
setDarkMode: jest.fn(),
setMainMenuOpen: jest.fn(),
setMinimalShellMode: jest.fn(),
openModal: jest.fn(),
closeModal: jest.fn(),
closeComposer: jest.fn(),
closeLightbox: jest.fn(),
openComposer: jest.fn(),
openLightbox: jest.fn(),
} as ShellUiModel
export const mockedMeStore = {
serialize: jest.fn(),
hydrate: jest.fn(),
did: 'test did',
handle: 'test',
displayName: 'test',
description: 'test',
avatar: '',
notificationCount: 0,
rootStore: {} as RootStoreModel,
memberships: mockedMembershipsStore,
mainFeed: mockedFeedStore,
notifications: mockedNotificationsStore,
clear: jest.fn(),
load: jest.fn(),
clearNotificationCount: jest.fn(),
fetchStateUpdate: jest.fn(),
refreshMemberships: jest.fn(),
} as MeModel
export const mockedOnboardStore = {
serialize: jest.fn(),
hydrate: jest.fn(),
isOnboarding: false,
stage: '',
start: jest.fn(),
stop: jest.fn(),
next: jest.fn(),
} as OnboardModel
export const mockedProfilesStore = {
hydrate: jest.fn(),
serialize: jest.fn(),
cache: new LRUMap(100),
rootStore: {} as RootStoreModel,
getProfile: jest.fn().mockResolvedValue({data: {}}),
overwrite: jest.fn(),
} as ProfilesViewModel
export const mockedLinkMetasStore = {
hydrate: jest.fn(),
serialize: jest.fn(),
cache: new LRUMap(100),
rootStore: {} as RootStoreModel,
getLinkMeta: jest.fn(),
} as LinkMetasViewModel
export const mockedLogStore = {
entries: [],
serialize: jest.fn(),
hydrate: jest.fn(),
debug: jest.fn(),
warn: jest.fn(),
error: jest.fn(),
// unknown required because of the missing private methods: add
} as unknown as LogModel
export const mockedRootStore = {
api: {
com: {},
app: {
bsky: {
graph: {
confirmation: {
delete: jest.fn().mockResolvedValue({}),
},
getFollowers: jest.fn().mockResolvedValue({}),
getMembers: jest.fn().mockResolvedValue({}),
},
},
},
} as unknown as SessionServiceClient,
resolveName: jest.fn(),
serialize: jest.fn(),
hydrate: jest.fn(),
fetchStateUpdate: jest.fn(),
clearAll: jest.fn(),
session: mockedSessionStore,
nav: mockedNavigationStore,
shell: mockedShellStore,
me: mockedMeStore,
onboard: mockedOnboardStore,
profiles: mockedProfilesStore,
linkMetas: mockedLinkMetasStore,
log: mockedLogStore,
} as RootStoreModel
export const mockedProfileUiStore = {
profile: mockedProfileStore,
feed: mockedFeedStore,
memberships: mockedMembershipsStore,
members: mockedMembersStore,
selectedViewIndex: 0,
rootStore: mockedRootStore,
params: {
user: 'test user',
},
currentView: mockedFeedStore,
isInitialLoading: false,
isRefreshing: false,
isUser: true,
isScene: false,
selectorItems: [Sections.Posts, Sections.PostsWithReplies, Sections.Scenes],
selectedView: Sections.Posts,
setSelectedViewIndex: jest.fn(),
setup: jest.fn().mockResolvedValue({aborted: false}),
update: jest.fn(),
refresh: jest.fn(),
loadMore: jest.fn(),
} as ProfileUiModel
export const mockedAutocompleteViewStore = {
isLoading: false,
isActive: true,
prefix: '',
follows: [
{
did: 'test did',
declaration: {
cid: '',
actorType: 'app.bsky.system.actorUser',
},
handle: '',
displayName: '',
createdAt: '',
indexedAt: '',
},
],
searchRes: [
{
did: 'test did',
declaration: {
cid: '',
actorType: 'app.bsky.system.actorUser',
},
handle: '',
displayName: '',
},
],
knownHandles: new Set<string>(),
suggestions: [
{
handle: 'handle.test',
displayName: 'Test Display',
},
{
handle: 'handle2.test',
displayName: 'Test Display 2',
},
],
rootStore: {} as RootStoreModel,
setup: jest.fn(),
setActive: jest.fn(),
setPrefix: jest.fn(),
// unknown required because of the missing private methods: _searchPromise, _getFollows , _search
} as unknown as UserAutocompleteViewModel
export const mockedLocalPhotosStore = {
photos: {
node: {
type: '',
group_name: '',
image: {
filename: '',
extension: '',
uri: '',
height: 1000,
width: 1000,
fileSize: null,
playableDuration: 0,
},
timestamp: 1672847197,
location: null,
},
},
rootStore: {} as RootStoreModel,
setup: jest.fn(),
// unknown required because of the missing private methods: _getPhotos
} as unknown as UserLocalPhotosModel
export const mockedSuggestedActorsStore = {
isLoading: false,
isRefreshing: false,
hasLoaded: false,
error: '',
suggestions: [
{
did: '1',
declaration: {
cid: '',
actorType: 'app.bsky.system.actorUser',
},
handle: 'handle1.test',
displayName: 'test name 1',
description: 'desc',
indexedAt: '',
_reactKey: '1',
},
{
did: '2',
declaration: {
cid: '',
actorType: 'app.bsky.system.actorUser',
},
handle: '',
displayName: 'handle2.test',
description: 'desc',
indexedAt: '',
_reactKey: '2',
},
],
rootStore: {} as RootStoreModel,
hasContent: true,
hasError: false,
isEmpty: false,
setup: jest.fn().mockResolvedValue(null),
refresh: jest.fn(),
// unknown required because of the missing private methods: _xLoading, _xIdle, _fetch, _appendAll, _append
} as unknown as SuggestedActorsViewModel
export const mockedUserFollowersStore = {
isLoading: false,
isRefreshing: false,
hasLoaded: false,
error: '',
params: {
user: 'test user',
},
subject: {
did: 'test did',
handle: '',
declaration: {cid: '', actorType: ''},
},
followers: [
{
did: 'test did',
declaration: {cid: '', actorType: ''},
handle: 'testhandle',
displayName: 'test name',
indexedAt: '',
_reactKey: '1',
},
{
did: 'test did2',
declaration: {cid: '', actorType: ''},
handle: 'testhandle2',
displayName: 'test name 2',
indexedAt: '',
_reactKey: '2',
},
],
rootStore: {} as RootStoreModel,
hasContent: true,
hasError: false,
isEmpty: false,
setup: jest.fn(),
refresh: jest.fn(),
loadMore: jest.fn(),
// unknown required because of the missing private methods: _xIdle, _xLoading, _fetch, _replaceAll, _append
} as unknown as UserFollowersViewModel
export const mockedUserFollowsStore = {
isLoading: false,
isRefreshing: false,
hasLoaded: false,
error: '',
params: {
user: 'test user',
},
subject: {
did: 'test did',
handle: '',
declaration: {cid: '', actorType: ''},
},
follows: [
{
did: 'test did',
declaration: {cid: '', actorType: ''},
handle: 'testhandle',
displayName: 'test name',
indexedAt: '',
_reactKey: '1',
},
{
did: 'test did2',
declaration: {cid: '', actorType: ''},
handle: 'testhandle2',
displayName: 'test name 2',
indexedAt: '',
_reactKey: '2',
},
],
rootStore: {} as RootStoreModel,
hasContent: true,
hasError: false,
isEmpty: false,
setup: jest.fn(),
refresh: jest.fn(),
loadMore: jest.fn(),
// unknown required because of the missing private methods: _xIdle, _xLoading, _fetch, _replaceAll, _append
} as unknown as UserFollowsViewModel
export const mockedRepostedByViewStore = {
isLoading: false,
isRefreshing: false,
hasLoaded: false,
error: '',
resolvedUri: '',
params: {
uri: 'testuri',
},
uri: '',
repostedBy: [
{
_reactKey: '',
did: '',
handle: '',
displayName: '',
declaration: {cid: '', actorType: ''},
indexedAt: '',
},
],
hasContent: false,
hasError: false,
isEmpty: false,
setup: jest.fn().mockResolvedValue({}),
refresh: jest.fn().mockResolvedValue({}),
loadMore: jest.fn().mockResolvedValue({}),
// unknown required because of the missing private methods: _xIdle, _xLoading, _resolveUri, _fetch, _refresh, _replaceAll, _append
} as unknown as RepostedByViewModel
export const mockedVotesViewStore = {
isLoading: false,
isRefreshing: false,
hasLoaded: false,
error: '',
resolvedUri: '',
params: {
uri: 'testuri',
},
uri: '',
votes: [
{
_reactKey: '',
direction: 'up',
indexedAt: '',
createdAt: '',
actor: {
did: '',
handle: '',
declaration: {cid: '', actorType: ''},
},
},
],
hasContent: false,
hasError: false,
isEmpty: false,
setup: jest.fn(),
refresh: jest.fn().mockResolvedValue({}),
loadMore: jest.fn().mockResolvedValue({}),
// unknown required because of the missing private methods: _xIdle, _xLoading, _resolveUri, _fetch, _replaceAll, _append
} as unknown as VotesViewModel

View File

@ -2,31 +2,27 @@ import {downloadAndResize, DownloadAndResizeOpts} from '../../src/lib/images'
import ImageResizer from '@bam.tech/react-native-image-resizer' import ImageResizer from '@bam.tech/react-native-image-resizer'
import RNFetchBlob from 'rn-fetch-blob' import RNFetchBlob from 'rn-fetch-blob'
jest.mock('rn-fetch-blob', () => ({
config: jest.fn().mockReturnThis(),
cancel: jest.fn(),
fetch: jest.fn(),
}))
jest.mock('@bam.tech/react-native-image-resizer', () => ({
createResizedImage: jest.fn(),
}))
describe('downloadAndResize', () => { describe('downloadAndResize', () => {
const errorSpy = jest.spyOn(global.console, 'error') const errorSpy = jest.spyOn(global.console, 'error')
const mockResizedImage = { const mockResizedImage = {
path: jest.fn().mockReturnValue('file://resized-image.jpg'), path: jest.fn().mockReturnValue('file://resized-image.jpg'),
size: 100, size: 100,
width: 50,
height: 50,
mime: 'image/jpeg',
} }
beforeEach(() => { beforeEach(() => {
jest.clearAllMocks()
const mockedCreateResizedImage = const mockedCreateResizedImage =
ImageResizer.createResizedImage as jest.Mock ImageResizer.createResizedImage as jest.Mock
mockedCreateResizedImage.mockResolvedValue(mockResizedImage) mockedCreateResizedImage.mockResolvedValue(mockResizedImage)
}) })
afterEach(() => {
jest.clearAllMocks()
})
it('should return resized image for valid URI and options', async () => { it('should return resized image for valid URI and options', async () => {
const mockedFetch = RNFetchBlob.fetch as jest.Mock const mockedFetch = RNFetchBlob.fetch as jest.Mock
mockedFetch.mockResolvedValueOnce({ mockedFetch.mockResolvedValueOnce({

View File

@ -0,0 +1,72 @@
import {RootStoreModel} from '../../../src/state/models/root-store'
import {LinkMetasViewModel} from '../../../src/state/models/link-metas-view'
import * as LinkMetaLib from '../../../src/lib/link-meta'
import {LikelyType} from './../../../src/lib/link-meta'
import {sessionClient, SessionServiceClient} from '@atproto/api'
import {DEFAULT_SERVICE} from '../../../src/state'
describe('LinkMetasViewModel', () => {
let viewModel: LinkMetasViewModel
let rootStore: RootStoreModel
const getLinkMetaMockSpy = jest.spyOn(LinkMetaLib, 'getLinkMeta')
const mockedMeta = {
title: 'Test Title',
url: 'testurl',
likelyType: LikelyType.Other,
}
beforeEach(() => {
const api = sessionClient.service(DEFAULT_SERVICE) as SessionServiceClient
rootStore = new RootStoreModel(api)
viewModel = new LinkMetasViewModel(rootStore)
})
afterAll(() => {
jest.clearAllMocks()
})
describe('getLinkMeta', () => {
it('should return link meta if it is cached', async () => {
const url = 'http://example.com'
viewModel.cache.set(url, mockedMeta)
const result = await viewModel.getLinkMeta(url)
expect(getLinkMetaMockSpy).not.toHaveBeenCalled()
expect(result).toEqual(mockedMeta)
})
it('should return link meta if it is not cached', async () => {
getLinkMetaMockSpy.mockResolvedValueOnce(mockedMeta)
const result = await viewModel.getLinkMeta(mockedMeta.url)
expect(getLinkMetaMockSpy).toHaveBeenCalledWith(mockedMeta.url)
expect(result).toEqual(mockedMeta)
})
it('should cache the link meta if it is successfully returned', async () => {
getLinkMetaMockSpy.mockResolvedValueOnce(mockedMeta)
await viewModel.getLinkMeta(mockedMeta.url)
expect(viewModel.cache.get(mockedMeta.url)).toEqual(mockedMeta)
})
it('should not cache the link meta if it fails to return', async () => {
const url = 'http://example.com'
const error = new Error('Failed to fetch link meta')
getLinkMetaMockSpy.mockRejectedValueOnce(error)
try {
await viewModel.getLinkMeta(url)
fail('Error was not thrown')
} catch (e) {
expect(e).toEqual(error)
expect(viewModel.cache.get(url)).toBeUndefined()
}
})
})
})

View File

@ -0,0 +1,153 @@
import {LogModel} from '../../../src/state/models/log'
describe('LogModel', () => {
let logModel: LogModel
beforeEach(() => {
logModel = new LogModel()
jest.spyOn(console, 'debug')
})
afterAll(() => {
jest.clearAllMocks()
})
it('should call a log method and add a log entry to the entries array', () => {
logModel.debug('Test log')
expect(logModel.entries.length).toEqual(1)
expect(logModel.entries[0]).toEqual({
id: logModel.entries[0].id,
type: 'debug',
summary: 'Test log',
details: undefined,
ts: logModel.entries[0].ts,
})
logModel.warn('Test log')
expect(logModel.entries.length).toEqual(2)
expect(logModel.entries[1]).toEqual({
id: logModel.entries[1].id,
type: 'warn',
summary: 'Test log',
details: undefined,
ts: logModel.entries[1].ts,
})
logModel.error('Test log')
expect(logModel.entries.length).toEqual(3)
expect(logModel.entries[2]).toEqual({
id: logModel.entries[2].id,
type: 'error',
summary: 'Test log',
details: undefined,
ts: logModel.entries[2].ts,
})
})
it('should call the console.debug after calling the debug method', () => {
logModel.debug('Test log')
expect(console.debug).toHaveBeenCalledWith('Test log', '')
})
it('should call the serialize method', () => {
logModel.debug('Test log')
expect(logModel.serialize()).toEqual({
entries: [
{
id: logModel.entries[0].id,
type: 'debug',
summary: 'Test log',
details: undefined,
ts: logModel.entries[0].ts,
},
],
})
})
it('should call the hydrate method with valid properties', () => {
logModel.hydrate({
entries: [
{
id: '123',
type: 'debug',
summary: 'Test log',
details: undefined,
ts: 123,
},
],
})
expect(logModel.entries).toEqual([
{
id: '123',
type: 'debug',
summary: 'Test log',
details: undefined,
ts: 123,
},
])
})
it('should call the hydrate method with invalid properties', () => {
logModel.hydrate({
entries: [
{
id: '123',
type: 'debug',
summary: 'Test log',
details: undefined,
ts: 123,
},
{
summary: 'Invalid entry',
},
],
})
expect(logModel.entries).toEqual([
{
id: '123',
type: 'debug',
summary: 'Test log',
details: undefined,
ts: 123,
},
])
})
it('should stringify the details if it is not a string', () => {
logModel.debug('Test log', {details: 'test'})
expect(logModel.entries[0].details).toEqual('{\n "details": "test"\n}')
})
it('should stringify the details object if it is of a specific error', () => {
class TestError extends Error {
constructor() {
super()
this.name = 'TestError'
}
}
const error = new TestError()
logModel.error('Test error log', error)
expect(logModel.entries[0].details).toEqual('TestError')
class XRPCInvalidResponseErrorMock {
validationError = {toString: () => 'validationError'}
lexiconNsid = 'test'
}
const xrpcInvalidResponseError = new XRPCInvalidResponseErrorMock()
logModel.error('Test error log', xrpcInvalidResponseError)
expect(logModel.entries[1].details).toEqual(
'{\n "validationError": {},\n "lexiconNsid": "test"\n}',
)
class XRPCErrorMock {
status = 'status'
error = 'error'
message = 'message'
}
const xrpcError = new XRPCErrorMock()
logModel.error('Test error log', xrpcError)
expect(logModel.entries[2].details).toEqual(
'{\n "status": "status",\n "error": "error",\n "message": "message"\n}',
)
})
})

View File

@ -0,0 +1,183 @@
import {RootStoreModel} from '../../../src/state/models/root-store'
import {MeModel} from '../../../src/state/models/me'
import {MembershipsViewModel} from './../../../src/state/models/memberships-view'
import {NotificationsViewModel} from './../../../src/state/models/notifications-view'
import {sessionClient, SessionServiceClient} from '@atproto/api'
import {DEFAULT_SERVICE} from './../../../src/state/index'
describe('MeModel', () => {
let rootStore: RootStoreModel
let meModel: MeModel
beforeEach(() => {
const api = sessionClient.service(DEFAULT_SERVICE) as SessionServiceClient
rootStore = new RootStoreModel(api)
meModel = new MeModel(rootStore)
})
afterAll(() => {
jest.clearAllMocks()
})
it('should clear() correctly', () => {
meModel.did = '123'
meModel.handle = 'handle'
meModel.displayName = 'John Doe'
meModel.description = 'description'
meModel.avatar = 'avatar'
meModel.notificationCount = 1
meModel.clear()
expect(meModel.did).toEqual('')
expect(meModel.handle).toEqual('')
expect(meModel.displayName).toEqual('')
expect(meModel.description).toEqual('')
expect(meModel.avatar).toEqual('')
expect(meModel.notificationCount).toEqual(0)
expect(meModel.memberships).toBeUndefined()
})
it('should hydrate() successfully with valid properties', () => {
meModel.hydrate({
did: '123',
handle: 'handle',
displayName: 'John Doe',
description: 'description',
avatar: 'avatar',
})
expect(meModel.did).toEqual('123')
expect(meModel.handle).toEqual('handle')
expect(meModel.displayName).toEqual('John Doe')
expect(meModel.description).toEqual('description')
expect(meModel.avatar).toEqual('avatar')
})
it('should not hydrate() with invalid properties', () => {
meModel.hydrate({
did: '',
handle: 'handle',
displayName: 'John Doe',
description: 'description',
avatar: 'avatar',
})
expect(meModel.did).toEqual('')
expect(meModel.handle).toEqual('')
expect(meModel.displayName).toEqual('')
expect(meModel.description).toEqual('')
expect(meModel.avatar).toEqual('')
meModel.hydrate({
did: '123',
displayName: 'John Doe',
description: 'description',
avatar: 'avatar',
})
expect(meModel.did).toEqual('')
expect(meModel.handle).toEqual('')
expect(meModel.displayName).toEqual('')
expect(meModel.description).toEqual('')
expect(meModel.avatar).toEqual('')
})
it('should load() successfully', async () => {
jest
.spyOn(rootStore.api.app.bsky.actor, 'getProfile')
.mockImplementationOnce((): Promise<any> => {
return Promise.resolve({
data: {
displayName: 'John Doe',
description: 'description',
avatar: 'avatar',
},
})
})
rootStore.session.data = {
did: '123',
handle: 'handle',
service: 'test service',
accessJwt: 'test token',
refreshJwt: 'test token',
}
await meModel.load()
expect(meModel.did).toEqual('123')
expect(meModel.handle).toEqual('handle')
expect(meModel.displayName).toEqual('John Doe')
expect(meModel.description).toEqual('description')
expect(meModel.avatar).toEqual('avatar')
})
it('should load() successfully without profile data', async () => {
jest
.spyOn(rootStore.api.app.bsky.actor, 'getProfile')
.mockImplementationOnce((): Promise<any> => {
return Promise.resolve({
data: null,
})
})
rootStore.session.data = {
did: '123',
handle: 'handle',
service: 'test service',
accessJwt: 'test token',
refreshJwt: 'test token',
}
await meModel.load()
expect(meModel.did).toEqual('123')
expect(meModel.handle).toEqual('handle')
expect(meModel.displayName).toEqual('')
expect(meModel.description).toEqual('')
expect(meModel.avatar).toEqual('')
})
it('should load() to nothing when no session', async () => {
rootStore.session.data = null
await meModel.load()
expect(meModel.did).toEqual('')
expect(meModel.handle).toEqual('')
expect(meModel.displayName).toEqual('')
expect(meModel.description).toEqual('')
expect(meModel.avatar).toEqual('')
expect(meModel.notificationCount).toEqual(0)
expect(meModel.memberships).toBeUndefined()
})
it('should serialize() key information', () => {
meModel.did = '123'
meModel.handle = 'handle'
meModel.displayName = 'John Doe'
meModel.description = 'description'
meModel.avatar = 'avatar'
expect(meModel.serialize()).toEqual({
did: '123',
handle: 'handle',
displayName: 'John Doe',
description: 'description',
avatar: 'avatar',
})
})
it('should clearNotificationCount() successfully', () => {
meModel.clearNotificationCount()
expect(meModel.notificationCount).toBe(0)
})
it('should update notifs count with fetchStateUpdate()', async () => {
meModel.notifications = {
refresh: jest.fn(),
} as unknown as NotificationsViewModel
jest
.spyOn(rootStore.api.app.bsky.notification, 'getCount')
.mockImplementationOnce((): Promise<any> => {
return Promise.resolve({
data: {
count: 1,
},
})
})
await meModel.fetchStateUpdate()
expect(meModel.notificationCount).toBe(1)
expect(meModel.notifications.refresh).toHaveBeenCalled()
})
})

View File

@ -0,0 +1,154 @@
import {
NavigationModel,
NavigationTabModel,
} from './../../../src/state/models/navigation'
import * as flags from '../../../src/build-flags'
describe('NavigationModel', () => {
let model: NavigationModel
beforeEach(() => {
model = new NavigationModel()
model.setTitle([0, 0], 'title')
})
afterAll(() => {
jest.clearAllMocks()
})
it('should clear() to the correct base state', async () => {
await model.clear()
expect(model.tabCount).toBe(2)
expect(model.tab).toEqual({
fixedTabPurpose: 0,
history: [
{
id: expect.anything(),
ts: expect.anything(),
url: '/',
},
],
id: expect.anything(),
index: 0,
isNewTab: false,
})
})
it('should call the navigate method', async () => {
const navigateSpy = jest.spyOn(model.tab, 'navigate')
await model.navigate('testurl', 'teststring')
expect(navigateSpy).toHaveBeenCalledWith('testurl', 'teststring')
})
it('should call the refresh method', async () => {
const refreshSpy = jest.spyOn(model.tab, 'refresh')
await model.refresh()
expect(refreshSpy).toHaveBeenCalled()
})
it('should call the isCurrentScreen method', () => {
expect(model.isCurrentScreen(11, 0)).toEqual(false)
})
it('should call the tab getter', () => {
expect(model.tab).toEqual({
fixedTabPurpose: 0,
history: [
{
id: expect.anything(),
ts: expect.anything(),
url: '/',
},
],
id: expect.anything(),
index: 0,
isNewTab: false,
})
})
it('should call the tabCount getter', () => {
expect(model.tabCount).toBe(2)
})
describe('tabs not enabled', () => {
jest.mock('../../../src/build-flags', () => ({
TABS_ENABLED: false,
}))
afterAll(() => {
jest.clearAllMocks()
})
it('should not create new tabs', () => {
// @ts-expect-error
flags.TABS_ENABLED = false
model.newTab('testurl')
expect(model.tab.isNewTab).toBe(false)
expect(model.tabIndex).toBe(0)
})
it('should not change the active tab', () => {
// @ts-expect-error
flags.TABS_ENABLED = false
model.setActiveTab(2)
expect(model.tabIndex).toBe(0)
})
it('should note close tabs', () => {
// @ts-expect-error
flags.TABS_ENABLED = false
model.closeTab(0)
expect(model.tabCount).toBe(2)
})
})
describe('tabs enabled', () => {
jest.mock('../../../src/build-flags', () => ({
TABS_ENABLED: true,
}))
afterAll(() => {
jest.clearAllMocks()
})
it('should create new tabs', () => {
// @ts-expect-error
flags.TABS_ENABLED = true
model.newTab('testurl', 'title')
expect(model.tab.isNewTab).toBe(true)
expect(model.tabIndex).toBe(2)
})
it('should change the current tab', () => {
// @ts-expect-error
flags.TABS_ENABLED = true
model.setActiveTab(0)
expect(model.tabIndex).toBe(0)
})
it('should close tabs', () => {
// @ts-expect-error
flags.TABS_ENABLED = true
model.closeTab(0)
expect(model.tabs).toEqual([
{
fixedTabPurpose: 1,
history: [
{
id: expect.anything(),
ts: expect.anything(),
url: '/notifications',
},
],
id: expect.anything(),
index: 0,
isNewTab: false,
},
])
expect(model.tabIndex).toBe(0)
})
})
})

View File

@ -0,0 +1,46 @@
import {
OnboardModel,
OnboardStageOrder,
} from '../../../src/state/models/onboard'
describe('OnboardModel', () => {
let onboardModel: OnboardModel
beforeEach(() => {
onboardModel = new OnboardModel()
})
afterAll(() => {
jest.clearAllMocks()
})
it('should start/stop correctly', () => {
onboardModel.start()
expect(onboardModel.isOnboarding).toBe(true)
onboardModel.stop()
expect(onboardModel.isOnboarding).toBe(false)
})
it('should call the next method until it has no more stages', () => {
onboardModel.start()
onboardModel.next()
expect(onboardModel.stage).toBe(OnboardStageOrder[1])
onboardModel.next()
expect(onboardModel.isOnboarding).toBe(false)
expect(onboardModel.stage).toBe(OnboardStageOrder[0])
})
it('serialize and hydrate', () => {
const serialized = onboardModel.serialize()
const newModel = new OnboardModel()
newModel.hydrate(serialized)
expect(newModel).toEqual(onboardModel)
onboardModel.start()
onboardModel.next()
const serialized2 = onboardModel.serialize()
newModel.hydrate(serialized2)
expect(newModel).toEqual(onboardModel)
})
})

View File

@ -0,0 +1,73 @@
import {RootStoreModel} from '../../../src/state/models/root-store'
import {setupState} from '../../../src/state'
describe('rootStore', () => {
let rootStore: RootStoreModel
beforeAll(() => {
jest.useFakeTimers()
})
beforeEach(async () => {
rootStore = await setupState()
})
afterAll(() => {
jest.clearAllMocks()
})
it('resolveName() handles inputs correctly', () => {
const spyMethod = jest
.spyOn(rootStore.api.com.atproto.handle, 'resolve')
.mockResolvedValue({success: true, headers: {}, data: {did: 'testdid'}})
rootStore.resolveName('teststring')
expect(spyMethod).toHaveBeenCalledWith({handle: 'teststring'})
expect(rootStore.resolveName('')).rejects.toThrow('Invalid handle: ""')
expect(rootStore.resolveName('did:123')).resolves.toReturnWith('did:123')
})
it('should call the clearAll() resets state correctly', () => {
rootStore.clearAll()
expect(rootStore.session.data).toEqual(null)
expect(rootStore.nav.tabs).toEqual([
{
fixedTabPurpose: 0,
history: [
{
id: expect.anything(),
ts: expect.anything(),
url: '/',
},
],
id: expect.anything(),
index: 0,
isNewTab: false,
},
{
fixedTabPurpose: 1,
history: [
{
id: expect.anything(),
ts: expect.anything(),
url: '/notifications',
},
],
id: expect.anything(),
index: 0,
isNewTab: false,
},
])
expect(rootStore.nav.tabIndex).toEqual(0)
expect(rootStore.me.did).toEqual('')
expect(rootStore.me.handle).toEqual('')
expect(rootStore.me.displayName).toEqual('')
expect(rootStore.me.description).toEqual('')
expect(rootStore.me.avatar).toEqual('')
expect(rootStore.me.notificationCount).toEqual(0)
expect(rootStore.me.memberships).toBeUndefined()
})
})

View File

@ -0,0 +1,59 @@
import {
ConfirmModal,
ImageLightbox,
ShellUiModel,
} from './../../../src/state/models/shell-ui'
describe('ShellUiModel', () => {
let model: ShellUiModel
beforeEach(() => {
model = new ShellUiModel()
})
afterAll(() => {
jest.clearAllMocks()
})
it('should call the openModal & closeModal method', () => {
model.openModal(ConfirmModal)
expect(model.isModalActive).toEqual(true)
expect(model.activeModal).toEqual(ConfirmModal)
model.closeModal()
expect(model.isModalActive).toEqual(false)
expect(model.activeModal).toBeUndefined()
})
it('should call the openLightbox & closeLightbox method', () => {
model.openLightbox(new ImageLightbox('uri'))
expect(model.isLightboxActive).toEqual(true)
expect(model.activeLightbox).toEqual(new ImageLightbox('uri'))
model.closeLightbox()
expect(model.isLightboxActive).toEqual(false)
expect(model.activeLightbox).toBeUndefined()
})
it('should call the openComposer & closeComposer method', () => {
const composer = {
replyTo: {
uri: 'uri',
cid: 'cid',
text: 'text',
author: {
handle: 'handle',
displayName: 'name',
},
},
onPost: jest.fn(),
}
model.openComposer(composer)
expect(model.isComposerActive).toEqual(true)
expect(model.composerOpts).toEqual(composer)
model.closeComposer()
expect(model.isComposerActive).toEqual(false)
expect(model.composerOpts).toBeUndefined()
})
})

View File

@ -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')
})
})

View File

@ -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()
})
})

View File

@ -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,
})
})
})

View File

@ -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'])
})
})

View File

@ -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()
})
})

View File

@ -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()
})
})

View File

@ -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()
})
})

View File

@ -0,0 +1,17 @@
import {renderHook} from '../../../jest/test-utils'
import {useAnimatedValue} from '../../../src/view/lib/hooks/useAnimatedValue'
describe('useAnimatedValue', () => {
it('creates an Animated.Value with the initial value passed to the hook', () => {
const {result} = renderHook(() => useAnimatedValue(10))
// @ts-expect-error
expect(result.current.__getValue()).toEqual(10)
})
it('returns the same Animated.Value instance on subsequent renders', () => {
const {result, rerender} = renderHook(() => useAnimatedValue(10))
const firstValue = result.current
rerender({})
expect(result.current).toBe(firstValue)
})
})

View File

@ -0,0 +1,49 @@
import React from 'react'
import {fireEvent, render} from '../../../jest/test-utils'
import {Home} from '../../../src/view/screens/Home'
import {mockedRootStore, mockedShellStore} from '../../../__mocks__/state-mock'
describe('useOnMainScroll', () => {
const mockedProps = {
navIdx: [0, 0] as [number, number],
params: {},
visible: true,
}
it('toggles minimalShellMode to true', () => {
jest.useFakeTimers()
const {getByTestId} = render(<Home {...mockedProps} />)
fireEvent.scroll(getByTestId('homeFeed'), {
nativeEvent: {
contentOffset: {y: 20},
contentSize: {height: 100},
layoutMeasurement: {height: 50},
},
})
expect(mockedRootStore.shell.setMinimalShellMode).toHaveBeenCalledWith(true)
})
it('toggles minimalShellMode to false', () => {
jest.useFakeTimers()
const {getByTestId} = render(<Home {...mockedProps} />, {
...mockedRootStore,
shell: {
...mockedShellStore,
minimalShellMode: true,
},
})
fireEvent.scroll(getByTestId('homeFeed'), {
nativeEvent: {
contentOffset: {y: 0},
contentSize: {height: 100},
layoutMeasurement: {height: 50},
},
})
expect(mockedRootStore.shell.setMinimalShellMode).toHaveBeenCalledWith(
false,
)
})
})

View File

@ -1,16 +0,0 @@
import React from 'react'
import {Contacts} from '../../../src/view/screens/Contacts'
import renderer from 'react-test-renderer'
// import {render} from '../../../../jest/test-utils'
describe('Contacts', () => {
const mockedProps = {
navIdx: [0, 0] as [number, number],
params: {},
visible: true,
}
it('renders correctly', () => {
const tree = renderer.create(<Contacts {...mockedProps} />).toJSON()
expect(tree).toMatchSnapshot()
})
})

View File

@ -1,16 +0,0 @@
import React from 'react'
import {Home} from '../../../src/view/screens/Home'
import renderer from 'react-test-renderer'
// import {render} from '../../../../jest/test-utils'
describe('Home', () => {
const mockedProps = {
navIdx: [0, 0] as [number, number],
params: {},
visible: true,
}
it('renders correctly', () => {
const tree = renderer.create(<Home {...mockedProps} />).toJSON()
expect(tree).toMatchSnapshot()
})
})

View File

@ -1,11 +1,37 @@
import React from 'react' import React from 'react'
import {Login} from '../../../src/view/screens/Login' import {Login} from '../../../src/view/screens/Login'
import renderer from 'react-test-renderer' import {cleanup, fireEvent, render} from '../../../jest/test-utils'
// import {render} from '../../../../jest/test-utils'
describe('Login', () => { describe('Login', () => {
it('renders correctly', () => { afterAll(() => {
const tree = renderer.create(<Login />).toJSON() jest.clearAllMocks()
expect(tree).toMatchSnapshot() cleanup()
})
it('renders initial screen', () => {
const {getByTestId} = render(<Login />)
const signUpScreen = getByTestId('signinOrCreateAccount')
expect(signUpScreen).toBeTruthy()
})
it('renders Signin screen', () => {
const {getByTestId} = render(<Login />)
const signInButton = getByTestId('signInButton')
fireEvent.press(signInButton)
const signInScreen = getByTestId('signIn')
expect(signInScreen).toBeTruthy()
})
it('renders CreateAccount screen', () => {
const {getByTestId} = render(<Login />)
const createAccountButton = getByTestId('createAccountButton')
fireEvent.press(createAccountButton)
const createAccountScreen = getByTestId('createAccount')
expect(createAccountScreen).toBeTruthy()
}) })
}) })

View File

@ -1,11 +1,21 @@
import React from 'react' import React from 'react'
import {NotFound} from '../../../src/view/screens/NotFound' import {NotFound} from '../../../src/view/screens/NotFound'
import renderer from 'react-test-renderer' import {cleanup, fireEvent, render} from '../../../jest/test-utils'
// import {render} from '../../../../jest/test-utils' import {mockedNavigationStore} from '../../../__mocks__/state-mock'
describe('NotFound', () => { describe('NotFound', () => {
it('renders correctly', () => { afterAll(() => {
const tree = renderer.create(<NotFound />).toJSON() jest.clearAllMocks()
expect(tree).toMatchSnapshot() cleanup()
})
it('navigates home', async () => {
const navigationSpy = jest.spyOn(mockedNavigationStore, 'navigate')
const {getByTestId} = render(<NotFound />)
const navigateHomeButton = getByTestId('navigateHomeButton')
fireEvent.press(navigateHomeButton)
expect(navigationSpy).toHaveBeenCalledWith('/')
}) })
}) })

View File

@ -1,16 +0,0 @@
import React from 'react'
import {Notifications} from '../../../src/view/screens/Notifications'
import renderer from 'react-test-renderer'
// import {render} from '../../../../jest/test-utils'
describe('Notifications', () => {
const mockedProps = {
navIdx: [0, 0] as [number, number],
params: {},
visible: true,
}
it('renders correctly', () => {
const tree = renderer.create(<Notifications {...mockedProps} />).toJSON()
expect(tree).toMatchSnapshot()
})
})

View File

@ -1,11 +0,0 @@
import React from 'react'
import {Onboard} from '../../../src/view/screens/Onboard'
import renderer from 'react-test-renderer'
// import {render} from '../../../../jest/test-utils'
describe('Onboard', () => {
it('renders correctly', () => {
const tree = renderer.create(<Onboard />).toJSON()
expect(tree).toMatchSnapshot()
})
})

View File

@ -1,19 +0,0 @@
import React from 'react'
import {PostDownvotedBy} from '../../../src/view/screens/PostDownvotedBy'
import renderer from 'react-test-renderer'
// import {render} from '../../../../jest/test-utils'
describe('PostDownvotedBy', () => {
const mockedProps = {
navIdx: [0, 0] as [number, number],
params: {
name: 'test name',
rkey: '123123123',
},
visible: true,
}
it('renders correctly', () => {
const tree = renderer.create(<PostDownvotedBy {...mockedProps} />).toJSON()
expect(tree).toMatchSnapshot()
})
})

View File

@ -1,19 +0,0 @@
import React from 'react'
import {PostRepostedBy} from '../../../src/view/screens/PostRepostedBy'
import renderer from 'react-test-renderer'
// import {render} from '../../../../jest/test-utils'
describe('PostRepostedBy', () => {
const mockedProps = {
navIdx: [0, 0] as [number, number],
params: {
name: 'test name',
rkey: '123123123',
},
visible: true,
}
it('renders correctly', () => {
const tree = renderer.create(<PostRepostedBy {...mockedProps} />).toJSON()
expect(tree).toMatchSnapshot()
})
})

View File

@ -1,19 +0,0 @@
import React from 'react'
import {PostThread} from '../../../src/view/screens/PostThread'
import renderer from 'react-test-renderer'
// import {render} from '../../../../jest/test-utils'
describe('PostThread', () => {
const mockedProps = {
navIdx: [0, 0] as [number, number],
params: {
name: 'test name',
rkey: '123123123',
},
visible: true,
}
it('renders correctly', () => {
const tree = renderer.create(<PostThread {...mockedProps} />).toJSON()
expect(tree).toMatchSnapshot()
})
})

View File

@ -1,19 +0,0 @@
import React from 'react'
import {PostUpvotedBy} from '../../../src/view/screens/PostUpvotedBy'
import renderer from 'react-test-renderer'
// import {render} from '../../../../jest/test-utils'
describe('PostUpvotedBy', () => {
const mockedProps = {
navIdx: [0, 0] as [number, number],
params: {
name: 'test name',
rkey: '123123123',
},
visible: true,
}
it('renders correctly', () => {
const tree = renderer.create(<PostUpvotedBy {...mockedProps} />).toJSON()
expect(tree).toMatchSnapshot()
})
})

View File

@ -1,19 +0,0 @@
import React from 'react'
import {Profile} from '../../../src/view/screens/Profile'
import renderer from 'react-test-renderer'
// import {render} from '../../../../jest/test-utils'
describe('Profile', () => {
const mockedProps = {
navIdx: [0, 0] as [number, number],
params: {
name: 'test name',
user: 'test.user',
},
visible: true,
}
it('renders correctly', () => {
const tree = renderer.create(<Profile {...mockedProps} />).toJSON()
expect(tree).toMatchSnapshot()
})
})

View File

@ -1,18 +0,0 @@
import React from 'react'
import {ProfileFollowers} from '../../../src/view/screens/ProfileFollowers'
import renderer from 'react-test-renderer'
// import {render} from '../../../../jest/test-utils'
describe('ProfileFollowers', () => {
const mockedProps = {
navIdx: [0, 0] as [number, number],
params: {
name: 'test name',
},
visible: true,
}
it('renders correctly', () => {
const tree = renderer.create(<ProfileFollowers {...mockedProps} />).toJSON()
expect(tree).toMatchSnapshot()
})
})

View File

@ -1,18 +0,0 @@
import React from 'react'
import {ProfileFollows} from '../../../src/view/screens/ProfileFollows'
import renderer from 'react-test-renderer'
// import {render} from '../../../../jest/test-utils'
describe('ProfileFollows', () => {
const mockedProps = {
navIdx: [0, 0] as [number, number],
params: {
name: 'test name',
},
visible: true,
}
it('renders correctly', () => {
const tree = renderer.create(<ProfileFollows {...mockedProps} />).toJSON()
expect(tree).toMatchSnapshot()
})
})

View File

@ -1,18 +0,0 @@
import React from 'react'
import {ProfileMembers} from '../../../src/view/screens/ProfileMembers'
import renderer from 'react-test-renderer'
// import {render} from '../../../../jest/test-utils'
describe('ProfileMembers', () => {
const mockedProps = {
navIdx: [0, 0] as [number, number],
params: {
name: 'test name',
},
visible: true,
}
it('renders correctly', () => {
const tree = renderer.create(<ProfileMembers {...mockedProps} />).toJSON()
expect(tree).toMatchSnapshot()
})
})

View File

@ -1,9 +1,9 @@
import React from 'react' import React from 'react'
import {Search} from '../../../src/view/screens/Search' import {Search} from '../../../src/view/screens/Search'
import renderer from 'react-test-renderer' import {cleanup, fireEvent, render} from '../../../jest/test-utils'
// import {render} from '../../../../jest/test-utils'
describe('Search', () => { describe('Search', () => {
jest.useFakeTimers()
const mockedProps = { const mockedProps = {
navIdx: [0, 0] as [number, number], navIdx: [0, 0] as [number, number],
params: { params: {
@ -11,8 +11,20 @@ describe('Search', () => {
}, },
visible: true, visible: true,
} }
it('renders correctly', () => {
const tree = renderer.create(<Search {...mockedProps} />).toJSON() afterAll(() => {
expect(tree).toMatchSnapshot() jest.clearAllMocks()
cleanup()
})
it('renders with query', async () => {
const {findByTestId} = render(<Search {...mockedProps} />)
const searchTextInput = await findByTestId('searchTextInput')
expect(searchTextInput).toBeTruthy()
fireEvent.changeText(searchTextInput, 'test')
const searchScrollView = await findByTestId('searchScrollView')
expect(searchScrollView).toBeTruthy()
}) })
}) })

View File

@ -1,16 +0,0 @@
import React from 'react'
import {Settings} from '../../../src/view/screens/Settings'
import renderer from 'react-test-renderer'
// import {render} from '../../../../jest/test-utils'
describe('Settings', () => {
const mockedProps = {
navIdx: [0, 0] as [number, number],
params: {},
visible: true,
}
it('renders correctly', () => {
const tree = renderer.create(<Settings {...mockedProps} />).toJSON()
expect(tree).toMatchSnapshot()
})
})

View File

@ -1,205 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Contacts renders correctly 1`] = `
<View>
<View
style={
Object {
"backgroundColor": "#ffffff",
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"fontSize": 30,
"fontWeight": "bold",
"paddingHorizontal": 12,
"paddingVertical": 6,
},
]
}
>
Contacts
</Text>
</View>
<View
style={
Object {
"backgroundColor": "#ffffff",
}
}
>
<View
style={
Object {
"backgroundColor": "#f8f3f3",
"borderRadius": 4,
"flexDirection": "row",
"marginBottom": 6,
"marginHorizontal": 10,
"paddingHorizontal": 8,
"paddingVertical": 8,
}
}
>
<
icon="magnifying-glass"
size={16}
style={
Object {
"color": "#645454",
"marginRight": 8,
}
}
/>
<TextInput
onChangeText={[Function]}
placeholder="Search"
placeholderTextColor="#968d8d"
style={
Object {
"color": "#000000",
"flex": 1,
}
}
value=""
/>
</View>
</View>
<View
onLayout={[Function]}
style={
Array [
Object {
"backgroundColor": "#ffffff",
"flexDirection": "row",
"paddingBottom": 12,
"paddingHorizontal": 14,
"paddingTop": 8,
},
]
}
>
<View
collapsable={false}
style={
Object {
"backgroundColor": "#000000",
"bottom": 0,
"height": 4,
"left": 0,
"position": "absolute",
"width": 0,
}
}
/>
<View
accessible={true}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"marginRight": 14,
"paddingHorizontal": 10,
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#000000",
"fontSize": 16,
"fontWeight": "600",
},
]
}
>
All
</Text>
</View>
<View
accessible={true}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"marginRight": 14,
"paddingHorizontal": 10,
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#645454",
"fontSize": 16,
"fontWeight": "600",
},
]
}
>
Following
</Text>
</View>
<View
accessible={true}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"marginRight": 14,
"paddingHorizontal": 10,
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#645454",
"fontSize": 16,
"fontWeight": "600",
},
]
}
>
Scenes
</Text>
</View>
</View>
</View>
`;

View File

@ -1,594 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Home renders correctly 1`] = `
<View
style={
Object {
"flex": 1,
}
}
>
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderBottomColor": "#f8f3f3",
"borderBottomWidth": 1,
"flexDirection": "row",
"paddingBottom": 6,
"paddingHorizontal": 12,
"paddingTop": 6,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 30,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"height": 30,
"opacity": 1,
"width": 40,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={30}
bbWidth={30}
focusable={false}
height={30}
meetOrSlice={0}
minX={0}
minY={0}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"flex": 0,
"height": 30,
"width": 30,
},
]
}
vbHeight={100}
vbWidth={100}
width={30}
>
<RNSVGGroup>
<RNSVGDefs>
<RNSVGLinearGradient
gradient={
Array [
0,
-1292135,
1,
-2424577,
]
}
gradientTransform={null}
gradientUnits={0}
name="grad"
x1="0"
x2="1"
y1="0"
y2="1"
/>
</RNSVGDefs>
<RNSVGCircle
cx="50"
cy="50"
fill={
Array [
1,
"grad",
]
}
propList={
Array [
"fill",
]
}
r="50"
/>
<RNSVGText
content={null}
dx={Array []}
dy={Array []}
fill={4294967295}
font={
Object {
"fontSize": "50",
"fontWeight": "bold",
"textAnchor": "middle",
}
}
propList={
Array [
"fill",
]
}
rotate={Array []}
x={
Array [
"50",
]
}
y={
Array [
"67",
]
}
>
<RNSVGTSpan
content="X"
dx={Array []}
dy={Array []}
font={Object {}}
rotate={Array []}
x={Array []}
y={Array []}
/>
</RNSVGText>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
pointerEvents="none"
style={
Object {
"alignItems": "baseline",
"flexDirection": "row",
"marginRight": "auto",
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#000000",
"fontSize": 21,
"fontWeight": "600",
},
]
}
>
Bluesky
</Text>
<Text
numberOfLines={1}
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#968d8d",
"fontSize": 18,
"marginLeft": 6,
"maxWidth": 200,
},
]
}
>
Private Beta
</Text>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"opacity": 1,
"width": 36,
}
}
>
<
icon="plus"
size={18}
/>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={18}
bbWidth={18}
color={4278190080}
fill="none"
focusable={false}
height={18}
meetOrSlice={0}
minX={0}
minY={0}
stroke="currentColor"
strokeWidth={3}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"color": "#000000",
"position": "relative",
"top": -1,
},
Object {
"flex": 0,
"height": 18,
"width": 18,
},
]
}
tintColor={4278190080}
vbHeight={24}
vbWidth={24}
width={18}
>
<RNSVGGroup
fill={null}
propList={
Array [
"fill",
"stroke",
"strokeWidth",
]
}
stroke={
Array [
2,
]
}
strokeWidth={3}
>
<RNSVGPath
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"
propList={
Array [
"strokeLinecap",
"strokeLinejoin",
]
}
strokeLinecap={1}
strokeLinejoin={1}
/>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<
icon="signal"
size={18}
style={
Array [
Object {
"color": "#000000",
},
]
}
/>
<
icon="x"
size={12}
style={
Object {
"backgroundColor": "#ffffff",
"color": "#d1106f",
"left": -4,
"position": "relative",
"top": 6,
}
}
/>
</View>
</View>
<View
style={
Object {
"flex": 1,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderRadius": 6,
"flexDirection": "row",
"margin": 2,
"marginBottom": 0,
"opacity": 1,
"paddingHorizontal": 10,
"paddingVertical": 10,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"opacity": 1,
"width": 50,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={50}
bbWidth={50}
focusable={false}
height={50}
meetOrSlice={0}
minX={0}
minY={0}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"flex": 0,
"height": 50,
"width": 50,
},
]
}
vbHeight={100}
vbWidth={100}
width={50}
>
<RNSVGGroup>
<RNSVGDefs>
<RNSVGLinearGradient
gradient={
Array [
0,
-1292135,
1,
-2424577,
]
}
gradientTransform={null}
gradientUnits={0}
name="grad"
x1="0"
x2="1"
y1="0"
y2="1"
/>
</RNSVGDefs>
<RNSVGCircle
cx="50"
cy="50"
fill={
Array [
1,
"grad",
]
}
propList={
Array [
"fill",
]
}
r="50"
/>
<RNSVGText
content={null}
dx={Array []}
dy={Array []}
fill={4294967295}
font={
Object {
"fontSize": "50",
"fontWeight": "bold",
"textAnchor": "middle",
}
}
propList={
Array [
"fill",
]
}
rotate={Array []}
x={
Array [
"50",
]
}
y={
Array [
"67",
]
}
>
<RNSVGTSpan
content="X"
dx={Array []}
dy={Array []}
font={Object {}}
rotate={Array []}
x={Array []}
y={Array []}
/>
</RNSVGText>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
style={
Object {
"flex": 1,
"marginLeft": 10,
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#968d8d",
"fontSize": 17,
},
]
}
>
What's up?
</Text>
</View>
<View
style={
Object {
"backgroundColor": "#f8f3f3",
"borderRadius": 30,
"paddingHorizontal": 14,
"paddingVertical": 6,
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#645454",
},
]
}
>
Post
</Text>
</View>
</View>
</View>
</View>
`;

View File

@ -1,371 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Login renders correctly 1`] = `
<View
style={
Object {
"flex": 1,
}
}
>
<View
style={
Object {
"flex": 2,
"justifyContent": "center",
}
}
>
<View
style={
Object {
"flexDirection": "row",
"justifyContent": "center",
}
}
>
<RNSVGSvgView
bbHeight="100"
bbWidth="100"
focusable={false}
height="100"
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"flex": 0,
"height": 100,
"width": 100,
},
]
}
width="100"
>
<RNSVGGroup>
<RNSVGCircle
cx="50"
cy="50"
fill={null}
propList={
Array [
"fill",
"stroke",
"strokeWidth",
]
}
r="46"
stroke={4294967295}
strokeWidth={2}
/>
<RNSVGLine
propList={
Array [
"stroke",
"strokeWidth",
]
}
stroke={4294967295}
strokeWidth={1}
x1="30"
x2="30"
y1="0"
y2="100"
/>
<RNSVGLine
propList={
Array [
"stroke",
"strokeWidth",
]
}
stroke={4294967295}
strokeWidth={1}
x1="74"
x2="74"
y1="0"
y2="100"
/>
<RNSVGLine
propList={
Array [
"stroke",
"strokeWidth",
]
}
stroke={4294967295}
strokeWidth={1}
x1="0"
x2="100"
y1="22"
y2="22"
/>
<RNSVGLine
propList={
Array [
"stroke",
"strokeWidth",
]
}
stroke={4294967295}
strokeWidth={1}
x1="0"
x2="100"
y1="74"
y2="74"
/>
<RNSVGText
content={null}
dx={Array []}
dy={Array []}
fill={null}
font={
Object {
"fontSize": "60",
"fontWeight": "bold",
"textAnchor": "middle",
}
}
propList={
Array [
"fill",
"stroke",
"strokeWidth",
]
}
rotate={Array []}
stroke={4294967295}
strokeWidth={2}
x={
Array [
"52",
]
}
y={
Array [
"70",
]
}
>
<RNSVGTSpan
content="B"
dx={Array []}
dy={Array []}
font={Object {}}
rotate={Array []}
x={Array []}
y={Array []}
/>
</RNSVGText>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#ffffff",
"fontSize": 68,
"fontWeight": "bold",
"textAlign": "center",
},
]
}
>
Bluesky
</Text>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#ffffff",
"fontSize": 18,
"textAlign": "center",
},
]
}
>
[ private beta ]
</Text>
</View>
<View
style={
Object {
"flex": 1,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"backgroundColor": "#0085ff",
"borderColor": "#ffffff",
"borderRadius": 10,
"borderWidth": 1,
"marginBottom": 20,
"marginHorizontal": 20,
"opacity": 1,
"paddingVertical": 16,
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#ffffff",
"fontSize": 18,
"fontWeight": "bold",
"textAlign": "center",
},
]
}
>
Create a new account
</Text>
</View>
<View
style={
Object {
"marginBottom": 20,
}
}
>
<RNSVGSvgView
bbHeight="1"
bbWidth={750}
focusable={false}
height="1"
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"position": "absolute",
"top": 10,
},
Object {
"flex": 0,
"height": 1,
"width": 750,
},
]
}
width={750}
>
<RNSVGGroup>
<RNSVGLine
propList={
Array [
"stroke",
"strokeWidth",
]
}
stroke={4294967295}
strokeWidth="1"
x1="30"
x2={355}
y1="0"
y2="0"
/>
<RNSVGLine
propList={
Array [
"stroke",
"strokeWidth",
]
}
stroke={4294967295}
strokeWidth="1"
x1={395}
x2={720}
y1="0"
y2="0"
/>
</RNSVGGroup>
</RNSVGSvgView>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#ffffff",
"fontSize": 16,
"textAlign": "center",
},
]
}
>
or
</Text>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"backgroundColor": "#0085ff",
"borderColor": "#ffffff",
"borderRadius": 10,
"borderWidth": 1,
"marginBottom": 20,
"marginHorizontal": 20,
"opacity": 1,
"paddingVertical": 16,
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#ffffff",
"fontSize": 18,
"fontWeight": "bold",
"textAlign": "center",
},
]
}
>
Sign in
</Text>
</View>
</View>
</View>
`;

View File

@ -1,431 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`NotFound renders correctly 1`] = `
<View>
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderBottomColor": "#f8f3f3",
"borderBottomWidth": 1,
"flexDirection": "row",
"paddingBottom": 6,
"paddingHorizontal": 12,
"paddingTop": 6,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 30,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"height": 30,
"opacity": 1,
"width": 40,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={30}
bbWidth={30}
focusable={false}
height={30}
meetOrSlice={0}
minX={0}
minY={0}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"flex": 0,
"height": 30,
"width": 30,
},
]
}
vbHeight={100}
vbWidth={100}
width={30}
>
<RNSVGGroup>
<RNSVGDefs>
<RNSVGLinearGradient
gradient={
Array [
0,
-1292135,
1,
-2424577,
]
}
gradientTransform={null}
gradientUnits={0}
name="grad"
x1="0"
x2="1"
y1="0"
y2="1"
/>
</RNSVGDefs>
<RNSVGCircle
cx="50"
cy="50"
fill={
Array [
1,
"grad",
]
}
propList={
Array [
"fill",
]
}
r="50"
/>
<RNSVGText
content={null}
dx={Array []}
dy={Array []}
fill={4294967295}
font={
Object {
"fontSize": "50",
"fontWeight": "bold",
"textAnchor": "middle",
}
}
propList={
Array [
"fill",
]
}
rotate={Array []}
x={
Array [
"50",
]
}
y={
Array [
"67",
]
}
>
<RNSVGTSpan
content="X"
dx={Array []}
dy={Array []}
font={Object {}}
rotate={Array []}
x={Array []}
y={Array []}
/>
</RNSVGText>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
pointerEvents="none"
style={
Object {
"alignItems": "baseline",
"flexDirection": "row",
"marginRight": "auto",
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#000000",
"fontSize": 21,
"fontWeight": "600",
},
]
}
>
Page not found
</Text>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"opacity": 1,
"width": 36,
}
}
>
<
icon="plus"
size={18}
/>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={18}
bbWidth={18}
color={4278190080}
fill="none"
focusable={false}
height={18}
meetOrSlice={0}
minX={0}
minY={0}
stroke="currentColor"
strokeWidth={3}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"color": "#000000",
"position": "relative",
"top": -1,
},
Object {
"flex": 0,
"height": 18,
"width": 18,
},
]
}
tintColor={4278190080}
vbHeight={24}
vbWidth={24}
width={18}
>
<RNSVGGroup
fill={null}
propList={
Array [
"fill",
"stroke",
"strokeWidth",
]
}
stroke={
Array [
2,
]
}
strokeWidth={3}
>
<RNSVGPath
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"
propList={
Array [
"strokeLinecap",
"strokeLinejoin",
]
}
strokeLinecap={1}
strokeLinejoin={1}
/>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<
icon="signal"
size={18}
style={
Array [
Object {
"color": "#000000",
},
]
}
/>
<
icon="x"
size={12}
style={
Object {
"backgroundColor": "#ffffff",
"color": "#d1106f",
"left": -4,
"position": "relative",
"top": 6,
}
}
/>
</View>
</View>
<View
style={
Object {
"alignItems": "center",
"justifyContent": "center",
"paddingTop": 100,
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"fontSize": 40,
"fontWeight": "bold",
},
]
}
>
Page not found
</Text>
<View
accessibilityRole="button"
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"opacity": 1,
}
}
>
<View
style={
Array [
Object {},
]
}
>
<Text
style={
Array [
Object {
"color": "#007AFF",
"fontSize": 18,
"margin": 8,
"textAlign": "center",
},
]
}
>
Home
</Text>
</View>
</View>
</View>
</View>
`;

View File

@ -1,378 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Notifications renders correctly 1`] = `
<View
style={
Object {
"flex": 1,
}
}
>
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderBottomColor": "#f8f3f3",
"borderBottomWidth": 1,
"flexDirection": "row",
"paddingBottom": 6,
"paddingHorizontal": 12,
"paddingTop": 6,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 30,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"height": 30,
"opacity": 1,
"width": 40,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={30}
bbWidth={30}
focusable={false}
height={30}
meetOrSlice={0}
minX={0}
minY={0}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"flex": 0,
"height": 30,
"width": 30,
},
]
}
vbHeight={100}
vbWidth={100}
width={30}
>
<RNSVGGroup>
<RNSVGDefs>
<RNSVGLinearGradient
gradient={
Array [
0,
-1292135,
1,
-2424577,
]
}
gradientTransform={null}
gradientUnits={0}
name="grad"
x1="0"
x2="1"
y1="0"
y2="1"
/>
</RNSVGDefs>
<RNSVGCircle
cx="50"
cy="50"
fill={
Array [
1,
"grad",
]
}
propList={
Array [
"fill",
]
}
r="50"
/>
<RNSVGText
content={null}
dx={Array []}
dy={Array []}
fill={4294967295}
font={
Object {
"fontSize": "50",
"fontWeight": "bold",
"textAnchor": "middle",
}
}
propList={
Array [
"fill",
]
}
rotate={Array []}
x={
Array [
"50",
]
}
y={
Array [
"67",
]
}
>
<RNSVGTSpan
content="X"
dx={Array []}
dy={Array []}
font={Object {}}
rotate={Array []}
x={Array []}
y={Array []}
/>
</RNSVGText>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
pointerEvents="none"
style={
Object {
"alignItems": "baseline",
"flexDirection": "row",
"marginRight": "auto",
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#000000",
"fontSize": 21,
"fontWeight": "600",
},
]
}
>
Notifications
</Text>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"opacity": 1,
"width": 36,
}
}
>
<
icon="plus"
size={18}
/>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={18}
bbWidth={18}
color={4278190080}
fill="none"
focusable={false}
height={18}
meetOrSlice={0}
minX={0}
minY={0}
stroke="currentColor"
strokeWidth={3}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"color": "#000000",
"position": "relative",
"top": -1,
},
Object {
"flex": 0,
"height": 18,
"width": 18,
},
]
}
tintColor={4278190080}
vbHeight={24}
vbWidth={24}
width={18}
>
<RNSVGGroup
fill={null}
propList={
Array [
"fill",
"stroke",
"strokeWidth",
]
}
stroke={
Array [
2,
]
}
strokeWidth={3}
>
<RNSVGPath
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"
propList={
Array [
"strokeLinecap",
"strokeLinejoin",
]
}
strokeLinecap={1}
strokeLinejoin={1}
/>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<
icon="signal"
size={18}
style={
Array [
Object {
"color": "#000000",
},
]
}
/>
<
icon="x"
size={12}
style={
Object {
"backgroundColor": "#ffffff",
"color": "#d1106f",
"left": -4,
"position": "relative",
"top": 6,
}
}
/>
</View>
</View>
<View
style={
Object {
"flex": 1,
}
}
/>
</View>
`;

View File

@ -1,388 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Onboard renders correctly 1`] = `
<View
style={
Object {
"backgroundColor": "#fff",
"flex": 1,
}
}
>
<RCTSafeAreaView
emulateUnlessSupported={true}
style={
Object {
"flex": 1,
}
}
>
<View
onLayout={[Function]}
style={
Array [
Object {
"flex": 1,
"overflow": "hidden",
},
undefined,
]
}
>
<RNCViewPager
collapsable={false}
initialPage={0}
keyboardDismissMode="on-drag"
layout={
Object {
"height": 0,
"width": 750,
}
}
layoutDirection="ltr"
onMoveShouldSetResponderCapture={[Function]}
onPageScroll={[Function]}
onPageScrollStateChanged={[Function]}
onPageSelected={[Function]}
scrollEnabled={true}
style={
Object {
"flex": 1,
}
}
>
<View
collapsable={false}
style={
Object {
"bottom": 0,
"left": 0,
"position": "absolute",
"right": 0,
"top": 0,
}
}
>
<View
accessibilityElementsHidden={false}
importantForAccessibility="auto"
style={
Array [
Object {
"flex": 1,
"overflow": "hidden",
},
Object {
"width": 750,
},
Array [
undefined,
Object {
"bottom": 0,
"left": 0,
"position": "absolute",
"right": 0,
"top": 0,
},
],
]
}
>
<View
style={
Object {
"flex": 1,
"paddingHorizontal": 16,
"paddingTop": 80,
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Array [
Object {
"fontSize": 42,
"fontWeight": "bold",
"marginBottom": 16,
"textAlign": "center",
},
Object {
"fontWeight": "400",
},
Object {
"lineHeight": 60,
"paddingBottom": 50,
"paddingTop": 50,
},
],
]
}
>
Welcome to
<Text
style={
Array [
Object {
"color": "#000000",
},
Array [
Object {
"fontWeight": "bold",
},
Object {
"color": "#0085ff",
},
Object {
"fontSize": 56,
},
],
]
}
>
Bluesky
</Text>
</Text>
<Text
style={
Array [
Object {
"color": "#000000",
},
Array [
Object {
"fontSize": 18,
"marginBottom": 16,
"textAlign": "center",
},
Object {
"fontSize": 24,
},
],
]
}
>
Let's do a quick tour through the new features.
</Text>
</View>
</View>
</View>
<View
collapsable={false}
style={
Object {
"bottom": 0,
"left": 0,
"position": "absolute",
"right": 0,
"top": 0,
}
}
>
<View
accessibilityElementsHidden={true}
importantForAccessibility="no-hide-descendants"
style={
Array [
Object {
"flex": 1,
"overflow": "hidden",
},
Object {
"width": 750,
},
Array [
undefined,
Object {
"bottom": 0,
"left": 0,
"position": "absolute",
"right": 0,
"top": 0,
},
],
]
}
/>
</View>
</RNCViewPager>
<View
style={
Object {
"flexDirection": "row",
}
}
>
<View
style={
Object {
"flex": 1,
}
}
/>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"opacity": 1,
"padding": 16,
}
}
>
<Text
collapsable={false}
style={
Object {
"opacity": 1,
}
}
>
°
</Text>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"opacity": 1,
"padding": 16,
}
}
>
<Text
collapsable={false}
style={
Object {
"opacity": 0.5,
}
}
>
°
</Text>
</View>
<View
style={
Object {
"flex": 1,
}
}
/>
</View>
</View>
<View
style={
Object {
"flexDirection": "row",
"paddingBottom": 24,
"paddingHorizontal": 32,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"opacity": 1,
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Array [
Object {
"color": "#0085ff",
},
Object {
"fontSize": 18,
},
],
]
}
>
Skip
</Text>
</View>
<View
style={
Object {
"flex": 1,
}
}
/>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"opacity": 1,
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Array [
Object {
"color": "#0085ff",
},
Object {
"fontSize": 18,
},
],
]
}
>
Next
</Text>
</View>
</View>
</RCTSafeAreaView>
</View>
`;

View File

@ -1,368 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`PostDownvotedBy renders correctly 1`] = `
<View>
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderBottomColor": "#f8f3f3",
"borderBottomWidth": 1,
"flexDirection": "row",
"paddingBottom": 6,
"paddingHorizontal": 12,
"paddingTop": 6,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 30,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"height": 30,
"opacity": 1,
"width": 40,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={30}
bbWidth={30}
focusable={false}
height={30}
meetOrSlice={0}
minX={0}
minY={0}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"flex": 0,
"height": 30,
"width": 30,
},
]
}
vbHeight={100}
vbWidth={100}
width={30}
>
<RNSVGGroup>
<RNSVGDefs>
<RNSVGLinearGradient
gradient={
Array [
0,
-1292135,
1,
-2424577,
]
}
gradientTransform={null}
gradientUnits={0}
name="grad"
x1="0"
x2="1"
y1="0"
y2="1"
/>
</RNSVGDefs>
<RNSVGCircle
cx="50"
cy="50"
fill={
Array [
1,
"grad",
]
}
propList={
Array [
"fill",
]
}
r="50"
/>
<RNSVGText
content={null}
dx={Array []}
dy={Array []}
fill={4294967295}
font={
Object {
"fontSize": "50",
"fontWeight": "bold",
"textAnchor": "middle",
}
}
propList={
Array [
"fill",
]
}
rotate={Array []}
x={
Array [
"50",
]
}
y={
Array [
"67",
]
}
>
<RNSVGTSpan
content="X"
dx={Array []}
dy={Array []}
font={Object {}}
rotate={Array []}
x={Array []}
y={Array []}
/>
</RNSVGText>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
pointerEvents="none"
style={
Object {
"alignItems": "baseline",
"flexDirection": "row",
"marginRight": "auto",
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#000000",
"fontSize": 21,
"fontWeight": "600",
},
]
}
>
Downvoted by
</Text>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"opacity": 1,
"width": 36,
}
}
>
<
icon="plus"
size={18}
/>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={18}
bbWidth={18}
color={4278190080}
fill="none"
focusable={false}
height={18}
meetOrSlice={0}
minX={0}
minY={0}
stroke="currentColor"
strokeWidth={3}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"color": "#000000",
"position": "relative",
"top": -1,
},
Object {
"flex": 0,
"height": 18,
"width": 18,
},
]
}
tintColor={4278190080}
vbHeight={24}
vbWidth={24}
width={18}
>
<RNSVGGroup
fill={null}
propList={
Array [
"fill",
"stroke",
"strokeWidth",
]
}
stroke={
Array [
2,
]
}
strokeWidth={3}
>
<RNSVGPath
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"
propList={
Array [
"strokeLinecap",
"strokeLinejoin",
]
}
strokeLinecap={1}
strokeLinejoin={1}
/>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<
icon="signal"
size={18}
style={
Array [
Object {
"color": "#000000",
},
]
}
/>
<
icon="x"
size={12}
style={
Object {
"backgroundColor": "#ffffff",
"color": "#d1106f",
"left": -4,
"position": "relative",
"top": 6,
}
}
/>
</View>
</View>
<View>
<ActivityIndicator />
</View>
</View>
`;

View File

@ -1,368 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`PostRepostedBy renders correctly 1`] = `
<View>
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderBottomColor": "#f8f3f3",
"borderBottomWidth": 1,
"flexDirection": "row",
"paddingBottom": 6,
"paddingHorizontal": 12,
"paddingTop": 6,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 30,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"height": 30,
"opacity": 1,
"width": 40,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={30}
bbWidth={30}
focusable={false}
height={30}
meetOrSlice={0}
minX={0}
minY={0}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"flex": 0,
"height": 30,
"width": 30,
},
]
}
vbHeight={100}
vbWidth={100}
width={30}
>
<RNSVGGroup>
<RNSVGDefs>
<RNSVGLinearGradient
gradient={
Array [
0,
-1292135,
1,
-2424577,
]
}
gradientTransform={null}
gradientUnits={0}
name="grad"
x1="0"
x2="1"
y1="0"
y2="1"
/>
</RNSVGDefs>
<RNSVGCircle
cx="50"
cy="50"
fill={
Array [
1,
"grad",
]
}
propList={
Array [
"fill",
]
}
r="50"
/>
<RNSVGText
content={null}
dx={Array []}
dy={Array []}
fill={4294967295}
font={
Object {
"fontSize": "50",
"fontWeight": "bold",
"textAnchor": "middle",
}
}
propList={
Array [
"fill",
]
}
rotate={Array []}
x={
Array [
"50",
]
}
y={
Array [
"67",
]
}
>
<RNSVGTSpan
content="X"
dx={Array []}
dy={Array []}
font={Object {}}
rotate={Array []}
x={Array []}
y={Array []}
/>
</RNSVGText>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
pointerEvents="none"
style={
Object {
"alignItems": "baseline",
"flexDirection": "row",
"marginRight": "auto",
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#000000",
"fontSize": 21,
"fontWeight": "600",
},
]
}
>
Reposted by
</Text>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"opacity": 1,
"width": 36,
}
}
>
<
icon="plus"
size={18}
/>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={18}
bbWidth={18}
color={4278190080}
fill="none"
focusable={false}
height={18}
meetOrSlice={0}
minX={0}
minY={0}
stroke="currentColor"
strokeWidth={3}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"color": "#000000",
"position": "relative",
"top": -1,
},
Object {
"flex": 0,
"height": 18,
"width": 18,
},
]
}
tintColor={4278190080}
vbHeight={24}
vbWidth={24}
width={18}
>
<RNSVGGroup
fill={null}
propList={
Array [
"fill",
"stroke",
"strokeWidth",
]
}
stroke={
Array [
2,
]
}
strokeWidth={3}
>
<RNSVGPath
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"
propList={
Array [
"strokeLinecap",
"strokeLinejoin",
]
}
strokeLinecap={1}
strokeLinejoin={1}
/>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<
icon="signal"
size={18}
style={
Array [
Object {
"color": "#000000",
},
]
}
/>
<
icon="x"
size={12}
style={
Object {
"backgroundColor": "#ffffff",
"color": "#d1106f",
"left": -4,
"position": "relative",
"top": 6,
}
}
/>
</View>
</View>
<View>
<ActivityIndicator />
</View>
</View>
`;

View File

@ -1,437 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`PostThread renders correctly 1`] = `
<View
style={
Object {
"flex": 1,
}
}
>
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderBottomColor": "#f8f3f3",
"borderBottomWidth": 1,
"flexDirection": "row",
"paddingBottom": 6,
"paddingHorizontal": 12,
"paddingTop": 6,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 30,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"height": 30,
"opacity": 1,
"width": 40,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={30}
bbWidth={30}
focusable={false}
height={30}
meetOrSlice={0}
minX={0}
minY={0}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"flex": 0,
"height": 30,
"width": 30,
},
]
}
vbHeight={100}
vbWidth={100}
width={30}
>
<RNSVGGroup>
<RNSVGDefs>
<RNSVGLinearGradient
gradient={
Array [
0,
-1292135,
1,
-2424577,
]
}
gradientTransform={null}
gradientUnits={0}
name="grad"
x1="0"
x2="1"
y1="0"
y2="1"
/>
</RNSVGDefs>
<RNSVGCircle
cx="50"
cy="50"
fill={
Array [
1,
"grad",
]
}
propList={
Array [
"fill",
]
}
r="50"
/>
<RNSVGText
content={null}
dx={Array []}
dy={Array []}
fill={4294967295}
font={
Object {
"fontSize": "50",
"fontWeight": "bold",
"textAnchor": "middle",
}
}
propList={
Array [
"fill",
]
}
rotate={Array []}
x={
Array [
"50",
]
}
y={
Array [
"67",
]
}
>
<RNSVGTSpan
content="X"
dx={Array []}
dy={Array []}
font={Object {}}
rotate={Array []}
x={Array []}
y={Array []}
/>
</RNSVGText>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
pointerEvents="none"
style={
Object {
"alignItems": "baseline",
"flexDirection": "row",
"marginRight": "auto",
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#000000",
"fontSize": 21,
"fontWeight": "600",
},
]
}
>
Post
</Text>
<Text
numberOfLines={1}
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#968d8d",
"fontSize": 18,
"marginLeft": 6,
"maxWidth": 200,
},
]
}
>
by test name
</Text>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"opacity": 1,
"width": 36,
}
}
>
<
icon="plus"
size={18}
/>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={18}
bbWidth={18}
color={4278190080}
fill="none"
focusable={false}
height={18}
meetOrSlice={0}
minX={0}
minY={0}
stroke="currentColor"
strokeWidth={3}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"color": "#000000",
"position": "relative",
"top": -1,
},
Object {
"flex": 0,
"height": 18,
"width": 18,
},
]
}
tintColor={4278190080}
vbHeight={24}
vbWidth={24}
width={18}
>
<RNSVGGroup
fill={null}
propList={
Array [
"fill",
"stroke",
"strokeWidth",
]
}
stroke={
Array [
2,
]
}
strokeWidth={3}
>
<RNSVGPath
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"
propList={
Array [
"strokeLinecap",
"strokeLinejoin",
]
}
strokeLinecap={1}
strokeLinejoin={1}
/>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<
icon="signal"
size={18}
style={
Array [
Object {
"color": "#000000",
},
]
}
/>
<
icon="x"
size={12}
style={
Object {
"backgroundColor": "#ffffff",
"color": "#d1106f",
"left": -4,
"position": "relative",
"top": 6,
}
}
/>
</View>
</View>
<View
style={
Object {
"flex": 1,
}
}
>
<RCTScrollView
contentContainerStyle={
Object {
"paddingBottom": 200,
}
}
data={Array []}
getItem={[Function]}
getItemCount={[Function]}
keyExtractor={[Function]}
onContentSizeChange={[Function]}
onLayout={[Function]}
onMomentumScrollBegin={[Function]}
onMomentumScrollEnd={[Function]}
onRefresh={[Function]}
onScroll={[Function]}
onScrollBeginDrag={[Function]}
onScrollEndDrag={[Function]}
onScrollToIndexFailed={[Function]}
refreshControl={
<RefreshControlMock
onRefresh={[Function]}
refreshing={false}
/>
}
refreshing={false}
removeClippedSubviews={false}
renderItem={[Function]}
scrollEventThrottle={50}
stickyHeaderIndices={Array []}
style={
Object {
"flex": 1,
}
}
viewabilityConfigCallbackPairs={Array []}
>
<RCTRefreshControl />
<View />
</RCTScrollView>
</View>
</View>
`;

View File

@ -1,368 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`PostUpvotedBy renders correctly 1`] = `
<View>
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderBottomColor": "#f8f3f3",
"borderBottomWidth": 1,
"flexDirection": "row",
"paddingBottom": 6,
"paddingHorizontal": 12,
"paddingTop": 6,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 30,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"height": 30,
"opacity": 1,
"width": 40,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={30}
bbWidth={30}
focusable={false}
height={30}
meetOrSlice={0}
minX={0}
minY={0}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"flex": 0,
"height": 30,
"width": 30,
},
]
}
vbHeight={100}
vbWidth={100}
width={30}
>
<RNSVGGroup>
<RNSVGDefs>
<RNSVGLinearGradient
gradient={
Array [
0,
-1292135,
1,
-2424577,
]
}
gradientTransform={null}
gradientUnits={0}
name="grad"
x1="0"
x2="1"
y1="0"
y2="1"
/>
</RNSVGDefs>
<RNSVGCircle
cx="50"
cy="50"
fill={
Array [
1,
"grad",
]
}
propList={
Array [
"fill",
]
}
r="50"
/>
<RNSVGText
content={null}
dx={Array []}
dy={Array []}
fill={4294967295}
font={
Object {
"fontSize": "50",
"fontWeight": "bold",
"textAnchor": "middle",
}
}
propList={
Array [
"fill",
]
}
rotate={Array []}
x={
Array [
"50",
]
}
y={
Array [
"67",
]
}
>
<RNSVGTSpan
content="X"
dx={Array []}
dy={Array []}
font={Object {}}
rotate={Array []}
x={Array []}
y={Array []}
/>
</RNSVGText>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
pointerEvents="none"
style={
Object {
"alignItems": "baseline",
"flexDirection": "row",
"marginRight": "auto",
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#000000",
"fontSize": 21,
"fontWeight": "600",
},
]
}
>
Upvoted by
</Text>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"opacity": 1,
"width": 36,
}
}
>
<
icon="plus"
size={18}
/>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={18}
bbWidth={18}
color={4278190080}
fill="none"
focusable={false}
height={18}
meetOrSlice={0}
minX={0}
minY={0}
stroke="currentColor"
strokeWidth={3}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"color": "#000000",
"position": "relative",
"top": -1,
},
Object {
"flex": 0,
"height": 18,
"width": 18,
},
]
}
tintColor={4278190080}
vbHeight={24}
vbWidth={24}
width={18}
>
<RNSVGGroup
fill={null}
propList={
Array [
"fill",
"stroke",
"strokeWidth",
]
}
stroke={
Array [
2,
]
}
strokeWidth={3}
>
<RNSVGPath
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"
propList={
Array [
"strokeLinecap",
"strokeLinejoin",
]
}
strokeLinecap={1}
strokeLinejoin={1}
/>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<
icon="signal"
size={18}
style={
Array [
Object {
"color": "#000000",
},
]
}
/>
<
icon="x"
size={12}
style={
Object {
"backgroundColor": "#ffffff",
"color": "#d1106f",
"left": -4,
"position": "relative",
"top": 6,
}
}
/>
</View>
</View>
<View>
<ActivityIndicator />
</View>
</View>
`;

View File

@ -1,513 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Profile renders correctly 1`] = `
<View
style={
Object {
"flexDirection": "column",
"height": "100%",
}
}
>
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderBottomColor": "#f8f3f3",
"borderBottomWidth": 1,
"flexDirection": "row",
"paddingBottom": 6,
"paddingHorizontal": 12,
"paddingTop": 6,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 30,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"height": 30,
"opacity": 1,
"width": 40,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={30}
bbWidth={30}
focusable={false}
height={30}
meetOrSlice={0}
minX={0}
minY={0}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"flex": 0,
"height": 30,
"width": 30,
},
]
}
vbHeight={100}
vbWidth={100}
width={30}
>
<RNSVGGroup>
<RNSVGDefs>
<RNSVGLinearGradient
gradient={
Array [
0,
-1292135,
1,
-2424577,
]
}
gradientTransform={null}
gradientUnits={0}
name="grad"
x1="0"
x2="1"
y1="0"
y2="1"
/>
</RNSVGDefs>
<RNSVGCircle
cx="50"
cy="50"
fill={
Array [
1,
"grad",
]
}
propList={
Array [
"fill",
]
}
r="50"
/>
<RNSVGText
content={null}
dx={Array []}
dy={Array []}
fill={4294967295}
font={
Object {
"fontSize": "50",
"fontWeight": "bold",
"textAnchor": "middle",
}
}
propList={
Array [
"fill",
]
}
rotate={Array []}
x={
Array [
"50",
]
}
y={
Array [
"67",
]
}
>
<RNSVGTSpan
content="X"
dx={Array []}
dy={Array []}
font={Object {}}
rotate={Array []}
x={Array []}
y={Array []}
/>
</RNSVGText>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
pointerEvents="none"
style={
Object {
"alignItems": "baseline",
"flexDirection": "row",
"marginRight": "auto",
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#000000",
"fontSize": 21,
"fontWeight": "600",
},
]
}
>
test name
</Text>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"opacity": 1,
"width": 36,
}
}
>
<
icon="plus"
size={18}
/>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={18}
bbWidth={18}
color={4278190080}
fill="none"
focusable={false}
height={18}
meetOrSlice={0}
minX={0}
minY={0}
stroke="currentColor"
strokeWidth={3}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"color": "#000000",
"position": "relative",
"top": -1,
},
Object {
"flex": 0,
"height": 18,
"width": 18,
},
]
}
tintColor={4278190080}
vbHeight={24}
vbWidth={24}
width={18}
>
<RNSVGGroup
fill={null}
propList={
Array [
"fill",
"stroke",
"strokeWidth",
]
}
stroke={
Array [
2,
]
}
strokeWidth={3}
>
<RNSVGPath
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"
propList={
Array [
"strokeLinecap",
"strokeLinejoin",
]
}
strokeLinecap={1}
strokeLinejoin={1}
/>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<
icon="signal"
size={18}
style={
Array [
Object {
"color": "#000000",
},
]
}
/>
<
icon="x"
size={12}
style={
Object {
"backgroundColor": "#ffffff",
"color": "#d1106f",
"left": -4,
"position": "relative",
"top": 6,
}
}
/>
</View>
</View>
<View
style={
Object {
"backgroundColor": "#ffffff",
}
}
>
<View
style={
Array [
Object {
"backgroundColor": "#e7e9ea",
"borderRadius": 6,
"height": 120,
"overflow": "hidden",
"width": "100%",
},
undefined,
]
}
>
<View
style={
Object {
"backgroundColor": "#e7e9ea",
"height": 120,
"width": "100%",
}
}
/>
</View>
<View
style={
Object {
"backgroundColor": "#ffffff",
"borderColor": "#ffffff",
"borderRadius": 42,
"borderWidth": 2,
"height": 84,
"left": 10,
"position": "absolute",
"top": 80,
"width": 84,
}
}
>
<View
style={
Array [
Object {
"backgroundColor": "#e7e9ea",
"borderRadius": 6,
"height": 80,
"overflow": "hidden",
"width": 80,
},
Object {
"borderRadius": 40,
},
]
}
>
<View
style={
Object {
"backgroundColor": "#e7e9ea",
"height": 80,
"width": 80,
}
}
/>
</View>
</View>
<View
style={
Object {
"paddingBottom": 4,
"paddingHorizontal": 14,
"paddingTop": 8,
}
}
>
<View
style={
Array [
Object {
"flexDirection": "row",
"marginBottom": 12,
"marginLeft": "auto",
},
]
}
>
<View
style={
Array [
Object {
"backgroundColor": "#e7e9ea",
"borderRadius": 6,
"height": 31,
"overflow": "hidden",
"width": 100,
},
Object {
"borderRadius": 50,
},
]
}
>
<View
style={
Object {
"backgroundColor": "#e7e9ea",
"height": 31,
"width": 100,
}
}
/>
</View>
</View>
<View
style={Object {}}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"fontSize": 28,
"fontWeight": "bold",
},
]
}
>
</Text>
</View>
</View>
</View>
</View>
`;

View File

@ -1,386 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ProfileFollowers renders correctly 1`] = `
<View>
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderBottomColor": "#f8f3f3",
"borderBottomWidth": 1,
"flexDirection": "row",
"paddingBottom": 6,
"paddingHorizontal": 12,
"paddingTop": 6,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 30,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"height": 30,
"opacity": 1,
"width": 40,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={30}
bbWidth={30}
focusable={false}
height={30}
meetOrSlice={0}
minX={0}
minY={0}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"flex": 0,
"height": 30,
"width": 30,
},
]
}
vbHeight={100}
vbWidth={100}
width={30}
>
<RNSVGGroup>
<RNSVGDefs>
<RNSVGLinearGradient
gradient={
Array [
0,
-1292135,
1,
-2424577,
]
}
gradientTransform={null}
gradientUnits={0}
name="grad"
x1="0"
x2="1"
y1="0"
y2="1"
/>
</RNSVGDefs>
<RNSVGCircle
cx="50"
cy="50"
fill={
Array [
1,
"grad",
]
}
propList={
Array [
"fill",
]
}
r="50"
/>
<RNSVGText
content={null}
dx={Array []}
dy={Array []}
fill={4294967295}
font={
Object {
"fontSize": "50",
"fontWeight": "bold",
"textAnchor": "middle",
}
}
propList={
Array [
"fill",
]
}
rotate={Array []}
x={
Array [
"50",
]
}
y={
Array [
"67",
]
}
>
<RNSVGTSpan
content="X"
dx={Array []}
dy={Array []}
font={Object {}}
rotate={Array []}
x={Array []}
y={Array []}
/>
</RNSVGText>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
pointerEvents="none"
style={
Object {
"alignItems": "baseline",
"flexDirection": "row",
"marginRight": "auto",
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#000000",
"fontSize": 21,
"fontWeight": "600",
},
]
}
>
Followers
</Text>
<Text
numberOfLines={1}
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#968d8d",
"fontSize": 18,
"marginLeft": 6,
"maxWidth": 200,
},
]
}
>
of test name
</Text>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"opacity": 1,
"width": 36,
}
}
>
<
icon="plus"
size={18}
/>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={18}
bbWidth={18}
color={4278190080}
fill="none"
focusable={false}
height={18}
meetOrSlice={0}
minX={0}
minY={0}
stroke="currentColor"
strokeWidth={3}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"color": "#000000",
"position": "relative",
"top": -1,
},
Object {
"flex": 0,
"height": 18,
"width": 18,
},
]
}
tintColor={4278190080}
vbHeight={24}
vbWidth={24}
width={18}
>
<RNSVGGroup
fill={null}
propList={
Array [
"fill",
"stroke",
"strokeWidth",
]
}
stroke={
Array [
2,
]
}
strokeWidth={3}
>
<RNSVGPath
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"
propList={
Array [
"strokeLinecap",
"strokeLinejoin",
]
}
strokeLinecap={1}
strokeLinejoin={1}
/>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<
icon="signal"
size={18}
style={
Array [
Object {
"color": "#000000",
},
]
}
/>
<
icon="x"
size={12}
style={
Object {
"backgroundColor": "#ffffff",
"color": "#d1106f",
"left": -4,
"position": "relative",
"top": 6,
}
}
/>
</View>
</View>
<View>
<ActivityIndicator />
</View>
</View>
`;

View File

@ -1,386 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ProfileFollows renders correctly 1`] = `
<View>
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderBottomColor": "#f8f3f3",
"borderBottomWidth": 1,
"flexDirection": "row",
"paddingBottom": 6,
"paddingHorizontal": 12,
"paddingTop": 6,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 30,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"height": 30,
"opacity": 1,
"width": 40,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={30}
bbWidth={30}
focusable={false}
height={30}
meetOrSlice={0}
minX={0}
minY={0}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"flex": 0,
"height": 30,
"width": 30,
},
]
}
vbHeight={100}
vbWidth={100}
width={30}
>
<RNSVGGroup>
<RNSVGDefs>
<RNSVGLinearGradient
gradient={
Array [
0,
-1292135,
1,
-2424577,
]
}
gradientTransform={null}
gradientUnits={0}
name="grad"
x1="0"
x2="1"
y1="0"
y2="1"
/>
</RNSVGDefs>
<RNSVGCircle
cx="50"
cy="50"
fill={
Array [
1,
"grad",
]
}
propList={
Array [
"fill",
]
}
r="50"
/>
<RNSVGText
content={null}
dx={Array []}
dy={Array []}
fill={4294967295}
font={
Object {
"fontSize": "50",
"fontWeight": "bold",
"textAnchor": "middle",
}
}
propList={
Array [
"fill",
]
}
rotate={Array []}
x={
Array [
"50",
]
}
y={
Array [
"67",
]
}
>
<RNSVGTSpan
content="X"
dx={Array []}
dy={Array []}
font={Object {}}
rotate={Array []}
x={Array []}
y={Array []}
/>
</RNSVGText>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
pointerEvents="none"
style={
Object {
"alignItems": "baseline",
"flexDirection": "row",
"marginRight": "auto",
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#000000",
"fontSize": 21,
"fontWeight": "600",
},
]
}
>
Followed
</Text>
<Text
numberOfLines={1}
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#968d8d",
"fontSize": 18,
"marginLeft": 6,
"maxWidth": 200,
},
]
}
>
by test name
</Text>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"opacity": 1,
"width": 36,
}
}
>
<
icon="plus"
size={18}
/>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={18}
bbWidth={18}
color={4278190080}
fill="none"
focusable={false}
height={18}
meetOrSlice={0}
minX={0}
minY={0}
stroke="currentColor"
strokeWidth={3}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"color": "#000000",
"position": "relative",
"top": -1,
},
Object {
"flex": 0,
"height": 18,
"width": 18,
},
]
}
tintColor={4278190080}
vbHeight={24}
vbWidth={24}
width={18}
>
<RNSVGGroup
fill={null}
propList={
Array [
"fill",
"stroke",
"strokeWidth",
]
}
stroke={
Array [
2,
]
}
strokeWidth={3}
>
<RNSVGPath
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"
propList={
Array [
"strokeLinecap",
"strokeLinejoin",
]
}
strokeLinecap={1}
strokeLinejoin={1}
/>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<
icon="signal"
size={18}
style={
Array [
Object {
"color": "#000000",
},
]
}
/>
<
icon="x"
size={12}
style={
Object {
"backgroundColor": "#ffffff",
"color": "#d1106f",
"left": -4,
"position": "relative",
"top": 6,
}
}
/>
</View>
</View>
<View>
<ActivityIndicator />
</View>
</View>
`;

View File

@ -1,386 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ProfileMembers renders correctly 1`] = `
<View>
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderBottomColor": "#f8f3f3",
"borderBottomWidth": 1,
"flexDirection": "row",
"paddingBottom": 6,
"paddingHorizontal": 12,
"paddingTop": 6,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 30,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"height": 30,
"opacity": 1,
"width": 40,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={30}
bbWidth={30}
focusable={false}
height={30}
meetOrSlice={0}
minX={0}
minY={0}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"flex": 0,
"height": 30,
"width": 30,
},
]
}
vbHeight={100}
vbWidth={100}
width={30}
>
<RNSVGGroup>
<RNSVGDefs>
<RNSVGLinearGradient
gradient={
Array [
0,
-1292135,
1,
-2424577,
]
}
gradientTransform={null}
gradientUnits={0}
name="grad"
x1="0"
x2="1"
y1="0"
y2="1"
/>
</RNSVGDefs>
<RNSVGCircle
cx="50"
cy="50"
fill={
Array [
1,
"grad",
]
}
propList={
Array [
"fill",
]
}
r="50"
/>
<RNSVGText
content={null}
dx={Array []}
dy={Array []}
fill={4294967295}
font={
Object {
"fontSize": "50",
"fontWeight": "bold",
"textAnchor": "middle",
}
}
propList={
Array [
"fill",
]
}
rotate={Array []}
x={
Array [
"50",
]
}
y={
Array [
"67",
]
}
>
<RNSVGTSpan
content="X"
dx={Array []}
dy={Array []}
font={Object {}}
rotate={Array []}
x={Array []}
y={Array []}
/>
</RNSVGText>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
pointerEvents="none"
style={
Object {
"alignItems": "baseline",
"flexDirection": "row",
"marginRight": "auto",
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#000000",
"fontSize": 21,
"fontWeight": "600",
},
]
}
>
Members
</Text>
<Text
numberOfLines={1}
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#968d8d",
"fontSize": 18,
"marginLeft": 6,
"maxWidth": 200,
},
]
}
>
of test name
</Text>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"opacity": 1,
"width": 36,
}
}
>
<
icon="plus"
size={18}
/>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={18}
bbWidth={18}
color={4278190080}
fill="none"
focusable={false}
height={18}
meetOrSlice={0}
minX={0}
minY={0}
stroke="currentColor"
strokeWidth={3}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"color": "#000000",
"position": "relative",
"top": -1,
},
Object {
"flex": 0,
"height": 18,
"width": 18,
},
]
}
tintColor={4278190080}
vbHeight={24}
vbWidth={24}
width={18}
>
<RNSVGGroup
fill={null}
propList={
Array [
"fill",
"stroke",
"strokeWidth",
]
}
stroke={
Array [
2,
]
}
strokeWidth={3}
>
<RNSVGPath
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"
propList={
Array [
"strokeLinecap",
"strokeLinejoin",
]
}
strokeLinecap={1}
strokeLinejoin={1}
/>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<
icon="signal"
size={18}
style={
Array [
Object {
"color": "#000000",
},
]
}
/>
<
icon="x"
size={12}
style={
Object {
"backgroundColor": "#ffffff",
"color": "#d1106f",
"left": -4,
"position": "relative",
"top": 6,
}
}
/>
</View>
</View>
<View>
<ActivityIndicator />
</View>
</View>
`;

View File

@ -1,514 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Search renders correctly 1`] = `
<View
style={
Object {
"backgroundColor": "#ffffff",
"flex": 1,
}
}
>
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderBottomColor": "#f8f3f3",
"borderBottomWidth": 1,
"flexDirection": "row",
"paddingBottom": 6,
"paddingHorizontal": 12,
"paddingTop": 6,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 30,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"height": 30,
"opacity": 1,
"width": 40,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={30}
bbWidth={30}
focusable={false}
height={30}
meetOrSlice={0}
minX={0}
minY={0}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"flex": 0,
"height": 30,
"width": 30,
},
]
}
vbHeight={100}
vbWidth={100}
width={30}
>
<RNSVGGroup>
<RNSVGDefs>
<RNSVGLinearGradient
gradient={
Array [
0,
-1292135,
1,
-2424577,
]
}
gradientTransform={null}
gradientUnits={0}
name="grad"
x1="0"
x2="1"
y1="0"
y2="1"
/>
</RNSVGDefs>
<RNSVGCircle
cx="50"
cy="50"
fill={
Array [
1,
"grad",
]
}
propList={
Array [
"fill",
]
}
r="50"
/>
<RNSVGText
content={null}
dx={Array []}
dy={Array []}
fill={4294967295}
font={
Object {
"fontSize": "50",
"fontWeight": "bold",
"textAnchor": "middle",
}
}
propList={
Array [
"fill",
]
}
rotate={Array []}
x={
Array [
"50",
]
}
y={
Array [
"67",
]
}
>
<RNSVGTSpan
content="X"
dx={Array []}
dy={Array []}
font={Object {}}
rotate={Array []}
x={Array []}
y={Array []}
/>
</RNSVGText>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
pointerEvents="none"
style={
Object {
"alignItems": "baseline",
"flexDirection": "row",
"marginRight": "auto",
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#000000",
"fontSize": 21,
"fontWeight": "600",
},
]
}
>
Search
</Text>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"opacity": 1,
"width": 36,
}
}
>
<
icon="plus"
size={18}
/>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={18}
bbWidth={18}
color={4278190080}
fill="none"
focusable={false}
height={18}
meetOrSlice={0}
minX={0}
minY={0}
stroke="currentColor"
strokeWidth={3}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"color": "#000000",
"position": "relative",
"top": -1,
},
Object {
"flex": 0,
"height": 18,
"width": 18,
},
]
}
tintColor={4278190080}
vbHeight={24}
vbWidth={24}
width={18}
>
<RNSVGGroup
fill={null}
propList={
Array [
"fill",
"stroke",
"strokeWidth",
]
}
stroke={
Array [
2,
]
}
strokeWidth={3}
>
<RNSVGPath
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"
propList={
Array [
"strokeLinecap",
"strokeLinejoin",
]
}
strokeLinecap={1}
strokeLinejoin={1}
/>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<
icon="signal"
size={18}
style={
Array [
Object {
"color": "#000000",
},
]
}
/>
<
icon="x"
size={12}
style={
Object {
"backgroundColor": "#ffffff",
"color": "#d1106f",
"left": -4,
"position": "relative",
"top": 6,
}
}
/>
</View>
</View>
<View
style={
Object {
"borderBottomColor": "#f8f3f3",
"borderBottomWidth": 1,
"flexDirection": "row",
"paddingHorizontal": 16,
"paddingVertical": 16,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={24}
bbWidth={24}
color={4290886073}
fill="none"
focusable={false}
height={24}
meetOrSlice={0}
minX={0}
minY={0}
stroke="currentColor"
strokeWidth={2}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"alignSelf": "center",
"color": "#c1b9b9",
"marginRight": 10,
},
Object {
"flex": 0,
"height": 24,
"width": 24,
},
]
}
tintColor={4290886073}
vbHeight={24}
vbWidth={24}
width={24}
>
<RNSVGGroup
fill={null}
propList={
Array [
"fill",
"stroke",
"strokeWidth",
]
}
stroke={
Array [
2,
]
}
strokeWidth={2}
>
<RNSVGPath
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"
propList={
Array [
"strokeLinecap",
"strokeLinejoin",
]
}
strokeLinecap={1}
strokeLinejoin={1}
/>
</RNSVGGroup>
</RNSVGSvgView>
<TextInput
onChangeText={[Function]}
placeholder="Type your query here..."
placeholderTextColor="#968d8d"
returnKeyType="search"
selectTextOnFocus={true}
style={
Object {
"color": "#000000",
"flex": 1,
"fontSize": 16,
}
}
/>
</View>
<View
style={
Object {
"backgroundColor": "#f8f3f3",
"flex": 1,
}
}
>
<View
style={
Object {
"flex": 1,
}
}
>
<View
style={
Object {
"backgroundColor": "#f8f3f3",
"flex": 1,
}
}
>
<RCTScrollView
data={Array []}
getItem={[Function]}
getItemCount={[Function]}
keyExtractor={[Function]}
onContentSizeChange={[Function]}
onLayout={[Function]}
onMomentumScrollBegin={[Function]}
onMomentumScrollEnd={[Function]}
onScroll={[Function]}
onScrollBeginDrag={[Function]}
onScrollEndDrag={[Function]}
removeClippedSubviews={false}
renderItem={[Function]}
scrollEventThrottle={50}
stickyHeaderIndices={Array []}
style={
Object {
"flex": 1,
}
}
viewabilityConfigCallbackPairs={Array []}
>
<View />
</RCTScrollView>
</View>
</View>
</View>
</View>
`;

View File

@ -1,631 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Settings renders correctly 1`] = `
<View
style={
Array [
Object {
"flex": 1,
},
]
}
>
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderBottomColor": "#f8f3f3",
"borderBottomWidth": 1,
"flexDirection": "row",
"paddingBottom": 6,
"paddingHorizontal": 12,
"paddingTop": 6,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 30,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"height": 30,
"opacity": 1,
"width": 40,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={30}
bbWidth={30}
focusable={false}
height={30}
meetOrSlice={0}
minX={0}
minY={0}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"flex": 0,
"height": 30,
"width": 30,
},
]
}
vbHeight={100}
vbWidth={100}
width={30}
>
<RNSVGGroup>
<RNSVGDefs>
<RNSVGLinearGradient
gradient={
Array [
0,
-1292135,
1,
-2424577,
]
}
gradientTransform={null}
gradientUnits={0}
name="grad"
x1="0"
x2="1"
y1="0"
y2="1"
/>
</RNSVGDefs>
<RNSVGCircle
cx="50"
cy="50"
fill={
Array [
1,
"grad",
]
}
propList={
Array [
"fill",
]
}
r="50"
/>
<RNSVGText
content={null}
dx={Array []}
dy={Array []}
fill={4294967295}
font={
Object {
"fontSize": "50",
"fontWeight": "bold",
"textAnchor": "middle",
}
}
propList={
Array [
"fill",
]
}
rotate={Array []}
x={
Array [
"50",
]
}
y={
Array [
"67",
]
}
>
<RNSVGTSpan
content="X"
dx={Array []}
dy={Array []}
font={Object {}}
rotate={Array []}
x={Array []}
y={Array []}
/>
</RNSVGText>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
pointerEvents="none"
style={
Object {
"alignItems": "baseline",
"flexDirection": "row",
"marginRight": "auto",
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#000000",
"fontSize": 21,
"fontWeight": "600",
},
]
}
>
Settings
</Text>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"opacity": 1,
"width": 36,
}
}
>
<
icon="plus"
size={18}
/>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={18}
bbWidth={18}
color={4278190080}
fill="none"
focusable={false}
height={18}
meetOrSlice={0}
minX={0}
minY={0}
stroke="currentColor"
strokeWidth={3}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"color": "#000000",
"position": "relative",
"top": -1,
},
Object {
"flex": 0,
"height": 18,
"width": 18,
},
]
}
tintColor={4278190080}
vbHeight={24}
vbWidth={24}
width={18}
>
<RNSVGGroup
fill={null}
propList={
Array [
"fill",
"stroke",
"strokeWidth",
]
}
stroke={
Array [
2,
]
}
strokeWidth={3}
>
<RNSVGPath
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"
propList={
Array [
"strokeLinecap",
"strokeLinejoin",
]
}
strokeLinecap={1}
strokeLinejoin={1}
/>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderRadius": 20,
"flexDirection": "row",
"height": 36,
"justifyContent": "center",
"marginLeft": 8,
"opacity": 1,
"width": 36,
}
}
>
<
icon="signal"
size={18}
style={
Array [
Object {
"color": "#000000",
},
]
}
/>
<
icon="x"
size={12}
style={
Object {
"backgroundColor": "#ffffff",
"color": "#d1106f",
"left": -4,
"position": "relative",
"top": 6,
}
}
/>
</View>
</View>
<View
style={
Array [
Object {
"marginTop": 10,
},
Object {
"paddingLeft": 10,
},
Object {
"paddingRight": 10,
},
]
}
>
<View
style={
Array [
Object {
"flexDirection": "row",
},
]
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#000000",
},
]
}
>
Signed in as
</Text>
<View
style={
Object {
"flex": 1,
}
}
/>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"opacity": 1,
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Array [
Object {
"color": "#0085ff",
},
Object {
"fontWeight": "bold",
},
],
]
}
>
Sign out
</Text>
</View>
</View>
<View
accessible={true}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
>
<View
style={
Object {
"backgroundColor": "#ffffff",
"borderRadius": 4,
"flexDirection": "row",
"marginVertical": 6,
"paddingHorizontal": 10,
"paddingVertical": 10,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={40}
bbWidth={40}
focusable={false}
height={40}
meetOrSlice={0}
minX={0}
minY={0}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"flex": 0,
"height": 40,
"width": 40,
},
]
}
vbHeight={100}
vbWidth={100}
width={40}
>
<RNSVGGroup>
<RNSVGDefs>
<RNSVGLinearGradient
gradient={
Array [
0,
-1292135,
1,
-2424577,
]
}
gradientTransform={null}
gradientUnits={0}
name="grad"
x1="0"
x2="1"
y1="0"
y2="1"
/>
</RNSVGDefs>
<RNSVGCircle
cx="50"
cy="50"
fill={
Array [
1,
"grad",
]
}
propList={
Array [
"fill",
]
}
r="50"
/>
<RNSVGText
content={null}
dx={Array []}
dy={Array []}
fill={4294967295}
font={
Object {
"fontSize": "50",
"fontWeight": "bold",
"textAnchor": "middle",
}
}
propList={
Array [
"fill",
]
}
rotate={Array []}
x={
Array [
"50",
]
}
y={
Array [
"67",
]
}
>
<RNSVGTSpan
content="X"
dx={Array []}
dy={Array []}
font={Object {}}
rotate={Array []}
x={Array []}
y={Array []}
/>
</RNSVGText>
</RNSVGGroup>
</RNSVGSvgView>
<View
style={
Array [
Object {
"marginLeft": 10,
},
]
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Array [
Object {
"fontSize": 18,
},
Object {
"color": "#000000",
},
],
]
}
>
</Text>
<Text
style={
Array [
Object {
"color": "#000000",
},
Array [
Object {
"color": "#645454",
},
],
]
}
>
@
</Text>
</View>
</View>
</View>
</View>
</View>
`;

View File

@ -1,23 +0,0 @@
import React from 'react'
import {Composer} from '../../../../src/view/shell/mobile/Composer'
import renderer from 'react-test-renderer'
// import {render} from '../../../../jest/test-utils'
describe('Composer', () => {
const mockedProps = {
active: true,
winHeight: 844,
replyTo: {
author: {avatar: undefined, displayName: 'Alice', handle: 'alice.test'},
cid: 'bafyreieucrv36ylxrut4dr4jj264q2jj2vt2vfvhjfchgw3vua4gksvzia',
text: 'Captain, maybe we ought to turn on the searchlights now. No… thats just what theyll be expecting us to do.',
uri: 'at://did:plc:v3xz273ea2dzjpu2szsjzfue/app.bsky.feed.post/3jkcir3fhqv2u',
},
onPost: jest.fn(),
onClose: jest.fn(),
}
it('renders correctly', () => {
const tree = renderer.create(<Composer {...mockedProps} />).toJSON()
expect(tree).toMatchSnapshot()
})
})

View File

@ -1,15 +1,70 @@
import React from 'react' import React from 'react'
import {Menu} from '../../../../src/view/shell/mobile/Menu' import {Menu} from '../../../../src/view/shell/mobile/Menu'
import renderer from 'react-test-renderer' import {cleanup, fireEvent, render} from '../../../../jest/test-utils'
// import {render} from '../../../../jest/test-utils' import {
mockedNavigationStore,
mockedShellStore,
} from '../../../../__mocks__/state-mock'
describe('Menu', () => { describe('Menu', () => {
const onCloseMock = jest.fn()
const mockedProps = { const mockedProps = {
visible: true, visible: true,
onClose: jest.fn(), onClose: onCloseMock,
} }
it('renders correctly', () => {
const tree = renderer.create(<Menu {...mockedProps} />).toJSON() afterAll(() => {
expect(tree).toMatchSnapshot() jest.clearAllMocks()
cleanup()
})
it('renders menu', () => {
const {getByTestId} = render(<Menu {...mockedProps} />)
const menuView = getByTestId('menuView')
expect(menuView).toBeTruthy()
})
it('presses profile card button', () => {
const {getByTestId} = render(<Menu {...mockedProps} />)
const profileCardButton = getByTestId('profileCardButton')
fireEvent.press(profileCardButton)
expect(onCloseMock).toHaveBeenCalled()
expect(mockedNavigationStore.switchTo).toHaveBeenCalledWith(0, true)
})
it('presses search button', () => {
const {getByTestId} = render(<Menu {...mockedProps} />)
const searchBtn = getByTestId('searchBtn')
fireEvent.press(searchBtn)
expect(onCloseMock).toHaveBeenCalled()
expect(mockedNavigationStore.switchTo).toHaveBeenCalledWith(0, true)
expect(mockedNavigationStore.navigate).toHaveBeenCalledWith('/search')
})
it("presses notifications menu item' button", () => {
const {getAllByTestId} = render(<Menu {...mockedProps} />)
const menuItemButton = getAllByTestId('menuItemButton')
fireEvent.press(menuItemButton[1])
expect(onCloseMock).toHaveBeenCalled()
expect(mockedNavigationStore.switchTo).toHaveBeenCalledWith(1, true)
})
it('presses new scene button', () => {
const {getAllByTestId} = render(<Menu {...mockedProps} />)
const menuItemButton = getAllByTestId('menuItemButton')
fireEvent.press(menuItemButton[3])
expect(onCloseMock).toHaveBeenCalled()
expect(mockedShellStore.openModal).toHaveBeenCalled()
}) })
}) })

View File

@ -1,17 +1,99 @@
import React from 'react' import React from 'react'
import {Animated} from 'react-native' import {Animated, Share} from 'react-native'
import renderer from 'react-test-renderer'
import {TabsSelector} from '../../../../src/view/shell/mobile/TabsSelector' import {TabsSelector} from '../../../../src/view/shell/mobile/TabsSelector'
// import {render} from '../../../../jest/test-utils' import {cleanup, fireEvent, render} from '../../../../jest/test-utils'
import {mockedNavigationStore} from '../../../../__mocks__/state-mock'
describe('TabsSelector', () => { describe('TabsSelector', () => {
const onCloseMock = jest.fn()
const mockedProps = { const mockedProps = {
active: true, active: true,
tabMenuInterp: new Animated.Value(0), tabMenuInterp: new Animated.Value(0),
onClose: jest.fn(), onClose: onCloseMock,
} }
it('renders correctly', () => {
const tree = renderer.create(<TabsSelector {...mockedProps} />).toJSON() afterAll(() => {
expect(tree).toMatchSnapshot() jest.clearAllMocks()
cleanup()
})
it('renders tabs selector', () => {
const {getByTestId} = render(<TabsSelector {...mockedProps} />)
const tabsSelectorView = getByTestId('tabsSelectorView')
expect(tabsSelectorView).toBeTruthy()
})
it('renders nothing if inactive', () => {
const {getByTestId} = render(
<TabsSelector {...{...mockedProps, active: false}} />,
)
const emptyView = getByTestId('emptyView')
expect(emptyView).toBeTruthy()
})
it('presses share button', () => {
const shareSpy = jest.spyOn(Share, 'share')
const {getByTestId} = render(<TabsSelector {...mockedProps} />)
const shareButton = getByTestId('shareButton')
fireEvent.press(shareButton)
expect(onCloseMock).toHaveBeenCalled()
expect(shareSpy).toHaveBeenCalledWith({url: 'https://bsky.app/'})
})
it('presses clone button', () => {
const {getByTestId} = render(<TabsSelector {...mockedProps} />)
const cloneButton = getByTestId('cloneButton')
fireEvent.press(cloneButton)
expect(onCloseMock).toHaveBeenCalled()
expect(mockedNavigationStore.newTab).toHaveBeenCalled()
})
it('presses new tab button', () => {
const {getByTestId} = render(<TabsSelector {...mockedProps} />)
const newTabButton = getByTestId('newTabButton')
fireEvent.press(newTabButton)
expect(onCloseMock).toHaveBeenCalled()
expect(mockedNavigationStore.newTab).toHaveBeenCalledWith('/')
})
it('presses change tab button', () => {
const {getAllByTestId} = render(<TabsSelector {...mockedProps} />)
const changeTabButton = getAllByTestId('changeTabButton')
fireEvent.press(changeTabButton[0])
expect(onCloseMock).toHaveBeenCalled()
expect(mockedNavigationStore.newTab).toHaveBeenCalledWith('/')
})
it('presses close tab button', () => {
const {getAllByTestId} = render(<TabsSelector {...mockedProps} />)
const closeTabButton = getAllByTestId('closeTabButton')
fireEvent.press(closeTabButton[0])
expect(onCloseMock).toHaveBeenCalled()
expect(mockedNavigationStore.setActiveTab).toHaveBeenCalledWith(0)
})
it('presses swipes to close the tab', () => {
const {getByTestId} = render(<TabsSelector {...mockedProps} />)
const tabsSwipable = getByTestId('tabsSwipable')
fireEvent(tabsSwipable, 'swipeableRightOpen')
expect(onCloseMock).toHaveBeenCalled()
expect(mockedNavigationStore.setActiveTab).toHaveBeenCalledWith(0)
}) })
}) })

View File

@ -1,659 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Composer renders correctly 1`] = `
<View
collapsable={false}
style={
Object {
"backgroundColor": "#fff",
"bottom": 0,
"paddingTop": 24,
"position": "absolute",
"top": 0,
"transform": Array [
Object {
"translateY": 844,
},
],
"width": "100%",
}
}
>
<View
onLayout={[Function]}
style={
Array [
Object {
"backgroundColor": "#fff",
"flex": 1,
"flexDirection": "column",
"height": "100%",
"padding": 15,
"paddingBottom": 0,
},
Object {
"paddingBottom": 0,
},
]
}
>
<RCTSafeAreaView
emulateUnlessSupported={true}
style={
Object {
"flex": 1,
}
}
>
<View
style={
Object {
"alignItems": "center",
"flexDirection": "row",
"height": 55,
"paddingBottom": 10,
"paddingHorizontal": 5,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"opacity": 1,
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Array [
Object {
"color": "#0085ff",
},
Object {
"fontSize": 18,
},
],
]
}
>
Cancel
</Text>
</View>
<View
style={
Object {
"flex": 1,
}
}
/>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"opacity": 1,
}
}
>
<BVLinearGradient
colors={
Array [
4292542719,
4294901882,
]
}
endPoint={
Object {
"x": 1,
"y": 1,
}
}
locations={null}
startPoint={
Object {
"x": 0,
"y": 0,
}
}
style={
Object {
"borderRadius": 20,
"paddingHorizontal": 20,
"paddingVertical": 6,
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Array [
Object {
"color": "#ffffff",
},
Object {
"fontSize": 16,
},
Object {
"fontWeight": "bold",
},
],
]
}
>
Reply
</Text>
</BVLinearGradient>
</View>
</View>
<RCTScrollView
style={
Object {
"flex": 1,
}
}
>
<View>
<View
style={
Object {
"borderTopColor": "#e4e2e2",
"borderTopWidth": 1,
"flexDirection": "row",
"paddingBottom": 16,
"paddingTop": 16,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={50}
bbWidth={50}
focusable={false}
height={50}
meetOrSlice={0}
minX={0}
minY={0}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"flex": 0,
"height": 50,
"width": 50,
},
]
}
vbHeight={100}
vbWidth={100}
width={50}
>
<RNSVGGroup>
<RNSVGDefs>
<RNSVGLinearGradient
gradient={
Array [
0,
-16742913,
1,
-14631929,
]
}
gradientTransform={null}
gradientUnits={0}
name="grad"
x1="0"
x2="1"
y1="0"
y2="1"
/>
</RNSVGDefs>
<RNSVGCircle
cx="50"
cy="50"
fill={
Array [
1,
"grad",
]
}
propList={
Array [
"fill",
]
}
r="50"
/>
<RNSVGText
content={null}
dx={Array []}
dy={Array []}
fill={4294967295}
font={
Object {
"fontSize": "50",
"fontWeight": "bold",
"textAnchor": "middle",
}
}
propList={
Array [
"fill",
]
}
rotate={Array []}
x={
Array [
"50",
]
}
y={
Array [
"67",
]
}
>
<RNSVGTSpan
content="A"
dx={Array []}
dy={Array []}
font={Object {}}
rotate={Array []}
x={Array []}
y={Array []}
/>
</RNSVGText>
</RNSVGGroup>
</RNSVGSvgView>
<View
style={
Object {
"flex": 1,
"paddingLeft": 13,
"paddingRight": 8,
}
}
>
<Text
onLongPress={[Function]}
onPress={[Function]}
style={
Array [
Object {
"color": "#000000",
},
Array [
Object {
"fontSize": 16,
},
Object {
"fontWeight": "bold",
},
Object {
"color": "#000000",
},
],
]
}
>
Alice
</Text>
<Text
numberOfLines={6}
style={
Array [
Object {
"color": "#000000",
},
Array [
Object {
"fontSize": 16,
},
Object {
"lineHeight": 20.8,
},
Object {
"color": "#000000",
},
],
]
}
>
Captain, maybe we ought to turn on the searchlights now. No… thats just what theyll be expecting us to do.
</Text>
</View>
</View>
<View
style={
Array [
Object {
"borderTopColor": "#e4e2e2",
"borderTopWidth": 1,
"flexDirection": "row",
"paddingTop": 16,
},
Object {
"flex": 1,
},
]
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={50}
bbWidth={50}
focusable={false}
height={50}
meetOrSlice={0}
minX={0}
minY={0}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"flex": 0,
"height": 50,
"width": 50,
},
]
}
vbHeight={100}
vbWidth={100}
width={50}
>
<RNSVGGroup>
<RNSVGDefs>
<RNSVGLinearGradient
gradient={
Array [
0,
-1292135,
1,
-2424577,
]
}
gradientTransform={null}
gradientUnits={0}
name="grad"
x1="0"
x2="1"
y1="0"
y2="1"
/>
</RNSVGDefs>
<RNSVGCircle
cx="50"
cy="50"
fill={
Array [
1,
"grad",
]
}
propList={
Array [
"fill",
]
}
r="50"
/>
<RNSVGText
content={null}
dx={Array []}
dy={Array []}
fill={4294967295}
font={
Object {
"fontSize": "50",
"fontWeight": "bold",
"textAnchor": "middle",
}
}
propList={
Array [
"fill",
]
}
rotate={Array []}
x={
Array [
"50",
]
}
y={
Array [
"67",
]
}
>
<RNSVGTSpan
content="X"
dx={Array []}
dy={Array []}
font={Object {}}
rotate={Array []}
x={Array []}
y={Array []}
/>
</RNSVGText>
</RNSVGGroup>
</RNSVGSvgView>
<TextInput
multiline={true}
onChangeText={[Function]}
placeholder="Write your reply"
placeholderTextColor="#968d8d"
scrollEnabled={true}
style={
Object {
"alignSelf": "flex-start",
"color": "#000000",
"flex": 1,
"fontSize": 18,
"marginLeft": 8,
"padding": 5,
}
}
/>
</View>
</View>
</RCTScrollView>
<View
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderTopColor": "#e4e2e2",
"borderTopWidth": 1,
"flexDirection": "row",
"paddingRight": 5,
"paddingVertical": 10,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
hitSlop={
Object {
"bottom": 10,
"left": 10,
"right": 10,
"top": 10,
}
}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"opacity": 1,
"paddingLeft": 5,
}
}
>
<
icon={
Array [
"far",
"image",
]
}
size={24}
style={
Object {
"color": "#0085ff",
}
}
/>
</View>
<View
style={
Object {
"flex": 1,
}
}
/>
<Text
style={
Array [
Object {
"color": "#000000",
},
Array [
Object {
"marginRight": 10,
},
Object {
"color": undefined,
},
],
]
}
>
256
</Text>
<View>
<View
indeterminateAnimationDuration={1000}
style={
Array [
Object {
"backgroundColor": "transparent",
"overflow": "hidden",
},
undefined,
]
}
>
<RNSVGSvgView
bbHeight={30}
bbWidth={30}
collapsable={false}
focusable={false}
height={30}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {},
Object {
"flex": 0,
"height": 30,
"width": 30,
},
]
}
width={30}
>
<RNSVGGroup>
<RNSVGPath
d="M15 2.5
A12.5 12.5 0 0 1 15 2.5"
propList={
Array [
"stroke",
"strokeWidth",
"strokeLinecap",
]
}
stroke={4278221567}
strokeLinecap={0}
strokeWidth={3}
/>
<RNSVGPath
d="M15 0.5
a14.5 14.5 0 0 1 0 29
a14.5 14.5 0 0 1 0 -29"
propList={
Array [
"stroke",
"strokeWidth",
"strokeLinecap",
]
}
stroke={4293190370}
strokeLinecap={0}
strokeWidth={1}
/>
</RNSVGGroup>
</RNSVGSvgView>
</View>
</View>
</View>
<View
collapsable={false}
style={
Object {
"backgroundColor": "#ffffff",
"borderTopColor": "#e4e2e2",
"borderTopWidth": 1,
"bottom": 0,
"left": 0,
"position": "absolute",
"right": 0,
"top": 1334,
}
}
/>
</RCTSafeAreaView>
</View>
</View>
`;

View File

@ -1,837 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Menu renders correctly 1`] = `
<View
style={
Object {
"backgroundColor": "#ffffff",
"flex": 1,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"flexDirection": "row",
"margin": 10,
"marginBottom": 6,
"opacity": 1,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={60}
bbWidth={60}
focusable={false}
height={60}
meetOrSlice={0}
minX={0}
minY={0}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"flex": 0,
"height": 60,
"width": 60,
},
]
}
vbHeight={100}
vbWidth={100}
width={60}
>
<RNSVGGroup>
<RNSVGDefs>
<RNSVGLinearGradient
gradient={
Array [
0,
-1292135,
1,
-2424577,
]
}
gradientTransform={null}
gradientUnits={0}
name="grad"
x1="0"
x2="1"
y1="0"
y2="1"
/>
</RNSVGDefs>
<RNSVGCircle
cx="50"
cy="50"
fill={
Array [
1,
"grad",
]
}
propList={
Array [
"fill",
]
}
r="50"
/>
<RNSVGText
content={null}
dx={Array []}
dy={Array []}
fill={4294967295}
font={
Object {
"fontSize": "50",
"fontWeight": "bold",
"textAnchor": "middle",
}
}
propList={
Array [
"fill",
]
}
rotate={Array []}
x={
Array [
"50",
]
}
y={
Array [
"67",
]
}
>
<RNSVGTSpan
content="X"
dx={Array []}
dy={Array []}
font={Object {}}
rotate={Array []}
x={Array []}
y={Array []}
/>
</RNSVGText>
</RNSVGGroup>
</RNSVGSvgView>
<View
style={
Object {
"flex": 1,
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#2D2626",
"fontSize": 24,
"fontWeight": "bold",
"marginLeft": 12,
},
]
}
>
</Text>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#423737",
"fontSize": 18,
"marginLeft": 12,
},
]
}
>
</Text>
</View>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"backgroundColor": "#f8f3f3",
"borderRadius": 8,
"flexDirection": "row",
"margin": 10,
"marginBottom": 0,
"opacity": 1,
"paddingHorizontal": 12,
"paddingVertical": 10,
}
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight={25}
bbWidth={25}
color={4284765268}
fill="none"
focusable={false}
height={25}
meetOrSlice={0}
minX={0}
minY={0}
stroke="currentColor"
strokeWidth={2}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"color": "#645454",
},
Object {
"flex": 0,
"height": 25,
"width": 25,
},
]
}
tintColor={4284765268}
vbHeight={24}
vbWidth={24}
width={25}
>
<RNSVGGroup
fill={null}
propList={
Array [
"fill",
"stroke",
"strokeWidth",
]
}
stroke={
Array [
2,
]
}
strokeWidth={2}
>
<RNSVGPath
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"
propList={
Array [
"strokeLinecap",
"strokeLinejoin",
]
}
strokeLinecap={1}
strokeLinejoin={1}
/>
</RNSVGGroup>
</RNSVGSvgView>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#423737",
"fontSize": 19,
"marginLeft": 8,
},
]
}
>
Search
</Text>
</View>
<View
style={
Object {
"borderBottomColor": "#f8f3f3",
"borderBottomWidth": 1,
"paddingBottom": 10,
"paddingHorizontal": 10,
"paddingTop": 10,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"flexDirection": "row",
"opacity": 1,
"paddingHorizontal": 6,
"paddingVertical": 8,
}
}
>
<View
style={
Array [
Object {
"alignItems": "center",
"height": 36,
"justifyContent": "center",
"marginRight": 12,
"width": 36,
},
]
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight="26"
bbWidth="26"
color={4282529591}
focusable={false}
height="26"
meetOrSlice={0}
minX={0}
minY={0}
stroke="currentColor"
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"color": "#423737",
},
Object {
"flex": 0,
"height": 26,
"width": 26,
},
]
}
tintColor={4282529591}
vbHeight={48}
vbWidth={48}
width="26"
>
<RNSVGGroup
propList={
Array [
"stroke",
]
}
stroke={
Array [
2,
]
}
>
<RNSVGPath
d="M 23.951 2 C 23.631 2.011 23.323 2.124 23.072 2.322 L 8.859 13.52 C 7.055 14.941 6 17.114 6 19.41 L 6 38.5 C 6 39.864 7.136 41 8.5 41 L 18.5 41 C 19.864 41 21 39.864 21 38.5 L 21 28.5 C 21 28.205 21.205 28 21.5 28 L 26.5 28 C 26.795 28 27 28.205 27 28.5 L 27 38.5 C 27 39.864 28.136 41 29.5 41 L 39.5 41 C 40.864 41 42 39.864 42 38.5 L 42 19.41 C 42 17.114 40.945 14.941 39.141 13.52 L 24.928 2.322 C 24.65 2.103 24.304 1.989 23.951 2 Z"
propList={
Array [
"strokeWidth",
]
}
strokeWidth={4}
/>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<Text
numberOfLines={1}
style={
Array [
Object {
"color": "#000000",
},
Array [
Object {
"color": "#2D2626",
"fontSize": 19,
},
undefined,
],
]
}
>
Home
</Text>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"flexDirection": "row",
"opacity": 1,
"paddingHorizontal": 6,
"paddingVertical": 8,
}
}
>
<View
style={
Array [
Object {
"alignItems": "center",
"height": 36,
"justifyContent": "center",
"marginRight": 12,
"width": 36,
},
]
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight="28"
bbWidth="28"
color={4282529591}
fill="none"
focusable={false}
height="28"
meetOrSlice={0}
minX={0}
minY={0}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"color": "#423737",
},
Object {
"flex": 0,
"height": 28,
"width": 28,
},
]
}
tintColor={4282529591}
vbHeight={24}
vbWidth={24}
width="28"
>
<RNSVGGroup
fill={null}
propList={
Array [
"fill",
]
}
>
<RNSVGPath
d="M0 0h24v24H0z"
fill={null}
propList={
Array [
"fill",
]
}
/>
<RNSVGPath
d="M20 17h2v2H2v-2h2v-7a8 8 0 1 1 16 0v7zm-2 0v-7a6 6 0 1 0-12 0v7h12zm-9 4h6v2H9v-2z"
fill={
Array [
2,
]
}
propList={
Array [
"fill",
]
}
/>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<Text
numberOfLines={1}
style={
Array [
Object {
"color": "#000000",
},
Array [
Object {
"color": "#2D2626",
"fontSize": 19,
},
undefined,
],
]
}
>
Notifications
</Text>
</View>
</View>
<View
style={
Object {
"borderBottomColor": "#f8f3f3",
"borderBottomWidth": 1,
"paddingBottom": 10,
"paddingHorizontal": 10,
"paddingTop": 10,
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"fontSize": 16,
"fontWeight": "bold",
"paddingHorizontal": 4,
"paddingVertical": 8,
},
]
}
>
Scenes
</Text>
</View>
<View
style={
Object {
"borderBottomColor": "#f8f3f3",
"borderBottomWidth": 1,
"paddingBottom": 10,
"paddingHorizontal": 10,
"paddingTop": 10,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"flexDirection": "row",
"opacity": 1,
"paddingHorizontal": 6,
"paddingVertical": 8,
}
}
>
<View
style={
Array [
Object {
"alignItems": "center",
"height": 36,
"justifyContent": "center",
"marginRight": 12,
"width": 36,
},
]
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight="30"
bbWidth="30"
color={4282529591}
fill="none"
focusable={false}
height="30"
meetOrSlice={0}
minX={0}
minY={0}
stroke="currentColor"
strokeWidth={2}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"color": "#423737",
},
Object {
"flex": 0,
"height": 30,
"width": 30,
},
]
}
tintColor={4282529591}
vbHeight={24}
vbWidth={24}
width="30"
>
<RNSVGGroup
fill={null}
propList={
Array [
"fill",
"stroke",
"strokeWidth",
]
}
stroke={
Array [
2,
]
}
strokeWidth={2}
>
<RNSVGPath
d="M18 18.72a9.094 9.094 0 003.741-.479 3 3 0 00-4.682-2.72m.94 3.198l.001.031c0 .225-.012.447-.037.666A11.944 11.944 0 0112 21c-2.17 0-4.207-.576-5.963-1.584A6.062 6.062 0 016 18.719m12 0a5.971 5.971 0 00-.941-3.197m0 0A5.995 5.995 0 0012 12.75a5.995 5.995 0 00-5.058 2.772m0 0a3 3 0 00-4.681 2.72 8.986 8.986 0 003.74.477m.94-3.197a5.971 5.971 0 00-.94 3.197M15 6.75a3 3 0 11-6 0 3 3 0 016 0zm6 3a2.25 2.25 0 11-4.5 0 2.25 2.25 0 014.5 0zm-13.5 0a2.25 2.25 0 11-4.5 0 2.25 2.25 0 014.5 0z"
propList={
Array [
"strokeLinecap",
"strokeLinejoin",
]
}
strokeLinecap={1}
strokeLinejoin={1}
/>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<Text
numberOfLines={1}
style={
Array [
Object {
"color": "#000000",
},
Array [
Object {
"color": "#2D2626",
"fontSize": 19,
},
undefined,
],
]
}
>
Create a scene
</Text>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"flexDirection": "row",
"opacity": 1,
"paddingHorizontal": 6,
"paddingVertical": 8,
}
}
>
<View
style={
Array [
Object {
"alignItems": "center",
"height": 36,
"justifyContent": "center",
"marginRight": 12,
"width": 36,
},
]
}
>
<RNSVGSvgView
align="xMidYMid"
bbHeight="30"
bbWidth="30"
color={4282529591}
fill="none"
focusable={false}
height="30"
meetOrSlice={0}
minX={0}
minY={0}
stroke="currentColor"
strokeWidth={2}
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"color": "#423737",
},
Object {
"flex": 0,
"height": 30,
"width": 30,
},
]
}
tintColor={4282529591}
vbHeight={24}
vbWidth={24}
width="30"
>
<RNSVGGroup
fill={null}
propList={
Array [
"fill",
"stroke",
"strokeWidth",
]
}
stroke={
Array [
2,
]
}
strokeWidth={2}
>
<RNSVGPath
d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z"
propList={
Array [
"strokeLinecap",
"strokeLinejoin",
]
}
strokeLinecap={1}
strokeLinejoin={1}
/>
<RNSVGPath
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
propList={
Array [
"strokeLinecap",
"strokeLinejoin",
]
}
strokeLinecap={1}
strokeLinejoin={1}
/>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<Text
numberOfLines={1}
style={
Array [
Object {
"color": "#000000",
},
Array [
Object {
"color": "#2D2626",
"fontSize": 19,
},
undefined,
],
]
}
>
Settings
</Text>
</View>
</View>
<View
style={
Object {
"paddingHorizontal": 14,
"paddingVertical": 18,
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#968d8d",
},
]
}
>
Build version
(
)
</Text>
</View>
</View>
`;

View File

@ -1,651 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`TabsSelector renders correctly 1`] = `
<View
collapsable={false}
style={
Object {
"backgroundColor": "#fff",
"borderTopColor": "#e4e2e2",
"borderTopWidth": 1,
"bottom": 55,
"height": 320,
"opacity": 1,
"position": "absolute",
"transform": Array [
Object {
"translateY": 320,
},
],
"width": "100%",
}
}
>
<View
onLayout={[Function]}
>
<View
style={
Array [
Object {
"padding": 10,
},
Object {
"borderBottomColor": "#e4e2e2",
"borderBottomWidth": 1,
},
]
}
>
<View
style={
Object {
"flexDirection": "row",
"paddingTop": 2,
}
}
>
<View
accessible={true}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Array [
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 4,
"flex": 1,
"flexDirection": "row",
"justifyContent": "center",
"marginRight": 5,
"paddingLeft": 12,
"paddingRight": 16,
"paddingVertical": 10,
},
]
}
>
<View
style={
Object {
"marginRight": 8,
}
}
>
<
icon="share"
size={16}
/>
</View>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"fontSize": 16,
"fontWeight": "500",
},
]
}
>
Share
</Text>
</View>
<View
accessible={true}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Array [
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 4,
"flex": 1,
"flexDirection": "row",
"justifyContent": "center",
"marginRight": 5,
"paddingLeft": 12,
"paddingRight": 16,
"paddingVertical": 10,
},
]
}
>
<View
style={
Object {
"marginRight": 8,
}
}
>
<
icon={
Array [
"far",
"clone",
]
}
size={16}
/>
</View>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"fontSize": 16,
"fontWeight": "500",
},
]
}
>
Clone tab
</Text>
</View>
<View
accessible={true}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Array [
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderRadius": 4,
"flex": 1,
"flexDirection": "row",
"justifyContent": "center",
"marginRight": 5,
"paddingLeft": 12,
"paddingRight": 16,
"paddingVertical": 10,
},
]
}
>
<View
style={
Object {
"marginRight": 8,
}
}
>
<
icon="plus"
size={16}
/>
</View>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"fontSize": 16,
"fontWeight": "500",
},
]
}
>
New tab
</Text>
</View>
</View>
</View>
<View
style={
Array [
Object {
"padding": 10,
},
Object {
"borderBottomColor": "#e4e2e2",
"borderBottomWidth": 1,
},
Object {
"backgroundColor": "#f8f3f3",
},
]
}
>
<RCTScrollView
style={
Object {
"height": 240,
}
}
>
<View>
<View
collapsable={false}
forwardedRef={[Function]}
handlerTag={1}
handlerType="PanGestureHandler"
onGestureHandlerEvent={[Function]}
onGestureHandlerStateChange={[Function]}
onLayout={[Function]}
style={
Object {
"overflow": "hidden",
}
}
>
<View
collapsable={false}
style={
Object {
"bottom": 0,
"flexDirection": "row",
"left": 0,
"position": "absolute",
"right": 0,
"top": 0,
"transform": Array [
Object {
"translateX": -10000,
},
],
}
}
>
<View
style={
Array [
Object {
"padding": 2,
},
]
}
/>
<View
onLayout={[Function]}
/>
</View>
<View
collapsable={false}
style={
Object {
"bottom": 0,
"flexDirection": "row-reverse",
"left": 0,
"position": "absolute",
"right": 0,
"top": 0,
"transform": Array [
Object {
"translateX": -10000,
},
],
}
}
>
<View
style={
Array [
Object {
"padding": 2,
},
]
}
/>
<View
onLayout={[Function]}
/>
</View>
<View
collapsable={false}
forwardedRef={[Function]}
handlerTag={2}
handlerType="TapGestureHandler"
onGestureHandlerEvent={[Function]}
onGestureHandlerStateChange={[Function]}
pointerEvents="auto"
style={
Object {
"transform": Array [
Object {
"translateX": -0,
},
],
}
}
>
<View
collapsable={false}
style={
Object {
"height": 46,
"overflow": "hidden",
}
}
>
<View
collapsable={false}
forwardedRef={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#ffffff",
"borderColor": "#000000",
"borderRadius": 4,
"borderWidth": 1,
"flexDirection": "row",
"height": 42,
}
}
>
<View
accessible={true}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"flex": 1,
"flexDirection": "row",
"paddingLeft": 12,
"paddingVertical": 12,
}
}
>
<View
style={Object {}}
>
<
icon="house"
size={20}
/>
</View>
<Text
ellipsizeMode="tail"
numberOfLines={1}
style={
Array [
Object {
"color": "#000000",
},
Array [
Object {
"flex": 1,
"fontSize": 16,
"paddingHorizontal": 10,
},
Object {
"fontWeight": "500",
},
],
]
}
suppressHighlighting={true}
>
/
</Text>
</View>
<View
accessible={true}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"paddingRight": 16,
"paddingVertical": 16,
}
}
>
<
icon="x"
size={14}
style={
Object {
"color": "#655",
}
}
/>
</View>
</View>
</View>
</View>
</View>
<View
collapsable={false}
forwardedRef={[Function]}
handlerTag={3}
handlerType="PanGestureHandler"
onGestureHandlerEvent={[Function]}
onGestureHandlerStateChange={[Function]}
onLayout={[Function]}
style={
Object {
"overflow": "hidden",
}
}
>
<View
collapsable={false}
style={
Object {
"bottom": 0,
"flexDirection": "row",
"left": 0,
"position": "absolute",
"right": 0,
"top": 0,
"transform": Array [
Object {
"translateX": -10000,
},
],
}
}
>
<View
style={
Array [
Object {
"padding": 2,
},
]
}
/>
<View
onLayout={[Function]}
/>
</View>
<View
collapsable={false}
style={
Object {
"bottom": 0,
"flexDirection": "row-reverse",
"left": 0,
"position": "absolute",
"right": 0,
"top": 0,
"transform": Array [
Object {
"translateX": -10000,
},
],
}
}
>
<View
style={
Array [
Object {
"padding": 2,
},
]
}
/>
<View
onLayout={[Function]}
/>
</View>
<View
collapsable={false}
forwardedRef={[Function]}
handlerTag={4}
handlerType="TapGestureHandler"
onGestureHandlerEvent={[Function]}
onGestureHandlerStateChange={[Function]}
pointerEvents="auto"
style={
Object {
"transform": Array [
Object {
"translateX": -0,
},
],
}
}
>
<View
collapsable={false}
style={
Object {
"height": 46,
"overflow": "hidden",
}
}
>
<View
collapsable={false}
forwardedRef={[Function]}
style={
Object {
"alignItems": "center",
"backgroundColor": "#f8f3f3",
"borderColor": "#968d8d",
"borderRadius": 4,
"borderWidth": 1,
"flexDirection": "row",
"height": 42,
}
}
>
<View
accessible={true}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"alignItems": "center",
"flex": 1,
"flexDirection": "row",
"paddingLeft": 12,
"paddingVertical": 12,
}
}
>
<View
style={Object {}}
>
<
icon="bell"
size={20}
/>
</View>
<Text
ellipsizeMode="tail"
numberOfLines={1}
style={
Array [
Object {
"color": "#000000",
},
Array [
Object {
"flex": 1,
"fontSize": 16,
"paddingHorizontal": 10,
},
false,
],
]
}
suppressHighlighting={true}
>
/notifications
</Text>
</View>
<View
accessible={true}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"paddingRight": 16,
"paddingVertical": 16,
}
}
>
<
icon="x"
size={14}
style={
Object {
"color": "#655",
}
}
/>
</View>
</View>
</View>
</View>
</View>
</View>
</RCTScrollView>
</View>
</View>
</View>
`;

View File

@ -1,421 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`MobileShell renders correctly 1`] = `
<BVLinearGradient
colors={
Array [
4278222079,
4278238463,
]
}
endPoint={
Object {
"x": 0,
"y": 1,
}
}
locations={null}
startPoint={
Object {
"x": 0,
"y": 0.8,
}
}
style={
Object {
"flex": 1,
"height": "100%",
}
}
>
<RCTSafeAreaView
emulateUnlessSupported={true}
style={
Object {
"flex": 1,
}
}
>
<View
style={
Object {
"flex": 1,
}
}
>
<View
style={
Object {
"flex": 2,
"justifyContent": "center",
}
}
>
<View
style={
Object {
"flexDirection": "row",
"justifyContent": "center",
}
}
>
<RNSVGSvgView
bbHeight="100"
bbWidth="100"
focusable={false}
height="100"
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"flex": 0,
"height": 100,
"width": 100,
},
]
}
width="100"
>
<RNSVGGroup>
<RNSVGCircle
cx="50"
cy="50"
fill={null}
propList={
Array [
"fill",
"stroke",
"strokeWidth",
]
}
r="46"
stroke={4294967295}
strokeWidth={2}
/>
<RNSVGLine
propList={
Array [
"stroke",
"strokeWidth",
]
}
stroke={4294967295}
strokeWidth={1}
x1="30"
x2="30"
y1="0"
y2="100"
/>
<RNSVGLine
propList={
Array [
"stroke",
"strokeWidth",
]
}
stroke={4294967295}
strokeWidth={1}
x1="74"
x2="74"
y1="0"
y2="100"
/>
<RNSVGLine
propList={
Array [
"stroke",
"strokeWidth",
]
}
stroke={4294967295}
strokeWidth={1}
x1="0"
x2="100"
y1="22"
y2="22"
/>
<RNSVGLine
propList={
Array [
"stroke",
"strokeWidth",
]
}
stroke={4294967295}
strokeWidth={1}
x1="0"
x2="100"
y1="74"
y2="74"
/>
<RNSVGText
content={null}
dx={Array []}
dy={Array []}
fill={null}
font={
Object {
"fontSize": "60",
"fontWeight": "bold",
"textAnchor": "middle",
}
}
propList={
Array [
"fill",
"stroke",
"strokeWidth",
]
}
rotate={Array []}
stroke={4294967295}
strokeWidth={2}
x={
Array [
"52",
]
}
y={
Array [
"70",
]
}
>
<RNSVGTSpan
content="B"
dx={Array []}
dy={Array []}
font={Object {}}
rotate={Array []}
x={Array []}
y={Array []}
/>
</RNSVGText>
</RNSVGGroup>
</RNSVGSvgView>
</View>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#ffffff",
"fontSize": 68,
"fontWeight": "bold",
"textAlign": "center",
},
]
}
>
Bluesky
</Text>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#ffffff",
"fontSize": 18,
"textAlign": "center",
},
]
}
>
[ private beta ]
</Text>
</View>
<View
style={
Object {
"flex": 1,
}
}
>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"backgroundColor": "#0085ff",
"borderColor": "#ffffff",
"borderRadius": 10,
"borderWidth": 1,
"marginBottom": 20,
"marginHorizontal": 20,
"opacity": 1,
"paddingVertical": 16,
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#ffffff",
"fontSize": 18,
"fontWeight": "bold",
"textAlign": "center",
},
]
}
>
Create a new account
</Text>
</View>
<View
style={
Object {
"marginBottom": 20,
}
}
>
<RNSVGSvgView
bbHeight="1"
bbWidth={750}
focusable={false}
height="1"
style={
Array [
Object {
"backgroundColor": "transparent",
"borderWidth": 0,
},
Object {
"position": "absolute",
"top": 10,
},
Object {
"flex": 0,
"height": 1,
"width": 750,
},
]
}
width={750}
>
<RNSVGGroup>
<RNSVGLine
propList={
Array [
"stroke",
"strokeWidth",
]
}
stroke={4294967295}
strokeWidth="1"
x1="30"
x2={355}
y1="0"
y2="0"
/>
<RNSVGLine
propList={
Array [
"stroke",
"strokeWidth",
]
}
stroke={4294967295}
strokeWidth="1"
x1={395}
x2={720}
y1="0"
y2="0"
/>
</RNSVGGroup>
</RNSVGSvgView>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#ffffff",
"fontSize": 16,
"textAlign": "center",
},
]
}
>
or
</Text>
</View>
<View
accessible={true}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"backgroundColor": "#0085ff",
"borderColor": "#ffffff",
"borderRadius": 10,
"borderWidth": 1,
"marginBottom": 20,
"marginHorizontal": 20,
"opacity": 1,
"paddingVertical": 16,
}
}
>
<Text
style={
Array [
Object {
"color": "#000000",
},
Object {
"color": "#ffffff",
"fontSize": 18,
"fontWeight": "bold",
"textAlign": "center",
},
]
}
>
Sign in
</Text>
</View>
</View>
</View>
</RCTSafeAreaView>
<View
enablePanDownToClose={true}
index={-1}
keyboardBehavior="fillParent"
onChange={[Function]}
snapPoints={
Array [
"10%",
]
}
>
<View />
</View>
</BVLinearGradient>
`;

View File

@ -1,18 +0,0 @@
import React from 'react'
import {MobileShell} from '../../../../src/view/shell/mobile'
import renderer from 'react-test-renderer'
import {SafeAreaProvider} from 'react-native-safe-area-context'
// import {render} from '../../../../jest/test-utils'
describe('MobileShell', () => {
it('renders correctly', () => {
const tree = renderer
.create(
<SafeAreaProvider>
<MobileShell />
</SafeAreaProvider>,
)
.toJSON()
expect(tree).toMatchSnapshot()
})
})

View File

@ -11,9 +11,9 @@
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; }; 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
56F0250941FE75DA8CF8094A /* libPods-app-appTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F5D2424078D205E2F98F0707 /* libPods-app-appTests.a */; }; 5698CA584FD738B2091BD18F /* libPods-app-appTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C0C7BDE7769B84011D3747DC /* libPods-app-appTests.a */; };
67BF1AE6AABFC881715B2D6A /* libPods-app.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8789F612EDA2C48C6064ADD6 /* libPods-app.a */; };
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
BFADB63545C91424F7C8293A /* libPods-app.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C668306DD1C0A63684EDCB0 /* libPods-app.a */; };
E4BBD590292C1F5200296224 /* app.entitlements in Resources */ = {isa = PBXBuildFile; fileRef = E4437C9E28581FA7006DA9E7 /* app.entitlements */; }; E4BBD590292C1F5200296224 /* app.entitlements in Resources */ = {isa = PBXBuildFile; fileRef = E4437C9E28581FA7006DA9E7 /* app.entitlements */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@ -37,15 +37,15 @@
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = app/Images.xcassets; sourceTree = "<group>"; }; 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = app/Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = app/Info.plist; sourceTree = "<group>"; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = app/Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = app/main.m; sourceTree = "<group>"; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = app/main.m; sourceTree = "<group>"; };
3D3D4D80CD734363E3EADE03 /* Pods-app.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app.release.xcconfig"; path = "Target Support Files/Pods-app/Pods-app.release.xcconfig"; sourceTree = "<group>"; }; 53DBA218C184B95B107AC33E /* Pods-app.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app.release.xcconfig"; path = "Target Support Files/Pods-app/Pods-app.release.xcconfig"; sourceTree = "<group>"; };
65D2EDDD9D88DA37994C7743 /* Pods-app-appTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app-appTests.debug.xcconfig"; path = "Target Support Files/Pods-app-appTests/Pods-app-appTests.debug.xcconfig"; sourceTree = "<group>"; };
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = app/LaunchScreen.storyboard; sourceTree = "<group>"; }; 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = app/LaunchScreen.storyboard; sourceTree = "<group>"; };
9C668306DD1C0A63684EDCB0 /* libPods-app.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-app.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 8789F612EDA2C48C6064ADD6 /* libPods-app.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-app.a"; sourceTree = BUILT_PRODUCTS_DIR; };
A79BD0E1A3F5B868AD4F5D68 /* Pods-app.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app.debug.xcconfig"; path = "Target Support Files/Pods-app/Pods-app.debug.xcconfig"; sourceTree = "<group>"; }; 8BB4EDB104E125B8A1913E74 /* Pods-app.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app.debug.xcconfig"; path = "Target Support Files/Pods-app/Pods-app.debug.xcconfig"; sourceTree = "<group>"; };
AA0AD1B60CF7C90FFDB948B9 /* Pods-app-appTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app-appTests.release.xcconfig"; path = "Target Support Files/Pods-app-appTests/Pods-app-appTests.release.xcconfig"; sourceTree = "<group>"; }; A8E093A0B5DA947150924A68 /* Pods-app-appTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app-appTests.release.xcconfig"; path = "Target Support Files/Pods-app-appTests/Pods-app-appTests.release.xcconfig"; sourceTree = "<group>"; };
C01FB6762BC17DADC0319338 /* Pods-app-appTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app-appTests.debug.xcconfig"; path = "Target Support Files/Pods-app-appTests/Pods-app-appTests.debug.xcconfig"; sourceTree = "<group>"; };
C0C7BDE7769B84011D3747DC /* libPods-app-appTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-app-appTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
E4437C9E28581FA7006DA9E7 /* app.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = app.entitlements; path = app/app.entitlements; sourceTree = "<group>"; }; E4437C9E28581FA7006DA9E7 /* app.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = app.entitlements; path = app/app.entitlements; sourceTree = "<group>"; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
F5D2424078D205E2F98F0707 /* libPods-app-appTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-app-appTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -53,7 +53,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
56F0250941FE75DA8CF8094A /* libPods-app-appTests.a in Frameworks */, 5698CA584FD738B2091BD18F /* libPods-app-appTests.a in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -61,7 +61,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
BFADB63545C91424F7C8293A /* libPods-app.a in Frameworks */, 67BF1AE6AABFC881715B2D6A /* libPods-app.a in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -103,8 +103,8 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
ED297162215061F000B7C4FE /* JavaScriptCore.framework */, ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
9C668306DD1C0A63684EDCB0 /* libPods-app.a */, 8789F612EDA2C48C6064ADD6 /* libPods-app.a */,
F5D2424078D205E2F98F0707 /* libPods-app-appTests.a */, C0C7BDE7769B84011D3747DC /* libPods-app-appTests.a */,
); );
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
@ -143,10 +143,10 @@
BBD78D7AC51CEA395F1C20DB /* Pods */ = { BBD78D7AC51CEA395F1C20DB /* Pods */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
A79BD0E1A3F5B868AD4F5D68 /* Pods-app.debug.xcconfig */, 8BB4EDB104E125B8A1913E74 /* Pods-app.debug.xcconfig */,
3D3D4D80CD734363E3EADE03 /* Pods-app.release.xcconfig */, 53DBA218C184B95B107AC33E /* Pods-app.release.xcconfig */,
65D2EDDD9D88DA37994C7743 /* Pods-app-appTests.debug.xcconfig */, C01FB6762BC17DADC0319338 /* Pods-app-appTests.debug.xcconfig */,
AA0AD1B60CF7C90FFDB948B9 /* Pods-app-appTests.release.xcconfig */, A8E093A0B5DA947150924A68 /* Pods-app-appTests.release.xcconfig */,
); );
path = Pods; path = Pods;
sourceTree = "<group>"; sourceTree = "<group>";
@ -158,11 +158,11 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "appTests" */; buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "appTests" */;
buildPhases = ( buildPhases = (
A8646FFAA087C80271BB2CC6 /* [CP] Check Pods Manifest.lock */, A6849EFFDCB214D4F4EAE972 /* [CP] Check Pods Manifest.lock */,
00E356EA1AD99517003FC87E /* Sources */, 00E356EA1AD99517003FC87E /* Sources */,
00E356EB1AD99517003FC87E /* Frameworks */, 00E356EB1AD99517003FC87E /* Frameworks */,
00E356EC1AD99517003FC87E /* Resources */, 00E356EC1AD99517003FC87E /* Resources */,
8DC349844744C81F79F94A1E /* [CP] Copy Pods Resources */, DFA0C2B14E2F369C4B2337CE /* [CP] Copy Pods Resources */,
); );
buildRules = ( buildRules = (
); );
@ -178,13 +178,13 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "app" */; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "app" */;
buildPhases = ( buildPhases = (
AFA1F7779F8B1AF36C3A7914 /* [CP] Check Pods Manifest.lock */, DDF15D430A078CE70E577FDA /* [CP] Check Pods Manifest.lock */,
FD10A7F022414F080027D42C /* Start Packager */, FD10A7F022414F080027D42C /* Start Packager */,
13B07F871A680F5B00A75B9A /* Sources */, 13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */, 13B07F8E1A680F5B00A75B9A /* Resources */,
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
EEF3465D9B31EDDCEB2438EA /* [CP] Copy Pods Resources */, 45E56D79C207C80AF89FBAA2 /* [CP] Copy Pods Resources */,
); );
buildRules = ( buildRules = (
); );
@ -266,24 +266,24 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "set -e\n\nexport NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n"; shellScript = "set -e\n\nexport NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
}; };
8DC349844744C81F79F94A1E /* [CP] Copy Pods Resources */ = { 45E56D79C207C80AF89FBAA2 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
inputFileListPaths = ( inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-app-appTests/Pods-app-appTests-resources-${CONFIGURATION}-input-files.xcfilelist", "${PODS_ROOT}/Target Support Files/Pods-app/Pods-app-resources-${CONFIGURATION}-input-files.xcfilelist",
); );
name = "[CP] Copy Pods Resources"; name = "[CP] Copy Pods Resources";
outputFileListPaths = ( outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-app-appTests/Pods-app-appTests-resources-${CONFIGURATION}-output-files.xcfilelist", "${PODS_ROOT}/Target Support Files/Pods-app/Pods-app-resources-${CONFIGURATION}-output-files.xcfilelist",
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-app-appTests/Pods-app-appTests-resources.sh\"\n"; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-app/Pods-app-resources.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
A8646FFAA087C80271BB2CC6 /* [CP] Check Pods Manifest.lock */ = { A6849EFFDCB214D4F4EAE972 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
@ -305,7 +305,7 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
AFA1F7779F8B1AF36C3A7914 /* [CP] Check Pods Manifest.lock */ = { DDF15D430A078CE70E577FDA /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
@ -327,21 +327,21 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
EEF3465D9B31EDDCEB2438EA /* [CP] Copy Pods Resources */ = { DFA0C2B14E2F369C4B2337CE /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
inputFileListPaths = ( inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-app/Pods-app-resources-${CONFIGURATION}-input-files.xcfilelist", "${PODS_ROOT}/Target Support Files/Pods-app-appTests/Pods-app-appTests-resources-${CONFIGURATION}-input-files.xcfilelist",
); );
name = "[CP] Copy Pods Resources"; name = "[CP] Copy Pods Resources";
outputFileListPaths = ( outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-app/Pods-app-resources-${CONFIGURATION}-output-files.xcfilelist", "${PODS_ROOT}/Target Support Files/Pods-app-appTests/Pods-app-appTests-resources-${CONFIGURATION}-output-files.xcfilelist",
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-app/Pods-app-resources.sh\"\n"; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-app-appTests/Pods-app-appTests-resources.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
FD10A7F022414F080027D42C /* Start Packager */ = { FD10A7F022414F080027D42C /* Start Packager */ = {
@ -396,7 +396,7 @@
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */
00E356F61AD99517003FC87E /* Debug */ = { 00E356F61AD99517003FC87E /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 65D2EDDD9D88DA37994C7743 /* Pods-app-appTests.debug.xcconfig */; baseConfigurationReference = C01FB6762BC17DADC0319338 /* Pods-app-appTests.debug.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_LOADER = "$(TEST_HOST)"; BUNDLE_LOADER = "$(TEST_HOST)";
@ -424,7 +424,7 @@
}; };
00E356F71AD99517003FC87E /* Release */ = { 00E356F71AD99517003FC87E /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = AA0AD1B60CF7C90FFDB948B9 /* Pods-app-appTests.release.xcconfig */; baseConfigurationReference = A8E093A0B5DA947150924A68 /* Pods-app-appTests.release.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_LOADER = "$(TEST_HOST)"; BUNDLE_LOADER = "$(TEST_HOST)";
@ -449,7 +449,7 @@
}; };
13B07F941A680F5B00A75B9A /* Debug */ = { 13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = A79BD0E1A3F5B868AD4F5D68 /* Pods-app.debug.xcconfig */; baseConfigurationReference = 8BB4EDB104E125B8A1913E74 /* Pods-app.debug.xcconfig */;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
@ -479,7 +479,7 @@
}; };
13B07F951A680F5B00A75B9A /* Release */ = { 13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 3D3D4D80CD734363E3EADE03 /* Pods-app.release.xcconfig */; baseConfigurationReference = 53DBA218C184B95B107AC33E /* Pods-app.release.xcconfig */;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;

View File

@ -1,17 +1,17 @@
import 'react-native-gesture-handler/jestSetup'
jest.mock('@react-native-async-storage/async-storage', () => jest.mock('@react-native-async-storage/async-storage', () =>
require('@react-native-async-storage/async-storage/jest/async-storage-mock'), require('@react-native-async-storage/async-storage/jest/async-storage-mock'),
) )
jest.mock('react-native/Libraries/EventEmitter/NativeEventEmitter') jest.mock('react-native/Libraries/EventEmitter/NativeEventEmitter')
// Silence the warning: Animated: `useNativeDriver` is not supported
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper')
require('react-native-reanimated/lib/reanimated2/jestUtils').setUpTests()
jest.mock('@fortawesome/react-native-fontawesome', () => ({ jest.mock('@fortawesome/react-native-fontawesome', () => ({
FontAwesomeIcon: '', FontAwesomeIcon: '',
})) }))
require('react-native-reanimated/lib/reanimated2/jestUtils').setUpTests()
// Silence the warning: Animated: `useNativeDriver` is not supported
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper')
jest.mock('react-native-safe-area-context', () => { jest.mock('react-native-safe-area-context', () => {
const inset = {top: 0, right: 0, bottom: 0, left: 0} const inset = {top: 0, right: 0, bottom: 0, left: 0}
return { return {
@ -36,4 +36,18 @@ jest.mock('@gorhom/bottom-sheet', () => {
} }
}) })
jest.useFakeTimers() jest.mock('rn-fetch-blob', () => ({
config: jest.fn().mockReturnThis(),
cancel: jest.fn(),
fetch: jest.fn(),
}))
jest.mock('@bam.tech/react-native-image-resizer', () => ({
createResizedImage: jest.fn(),
}))
import {View as mockedView} from 'react-native'
jest.mock('react-native-tab-view', () => ({
...jest.requireActual('react-native-tab-view'),
TabView: mockedView,
}))

View File

@ -1,29 +1,27 @@
import React from 'react' import React from 'react'
import RN from 'react-native'
import {render} from '@testing-library/react-native' import {render} from '@testing-library/react-native'
import {GestureHandlerRootView} from 'react-native-gesture-handler' import {GestureHandlerRootView} from 'react-native-gesture-handler'
import {RootSiblingParent} from 'react-native-root-siblings' import {RootSiblingParent} from 'react-native-root-siblings'
import {SafeAreaProvider} from 'react-native-safe-area-context' import {SafeAreaProvider} from 'react-native-safe-area-context'
import {DEFAULT_SERVICE, RootStoreModel, RootStoreProvider} from '../src/state' import {RootStoreProvider} from '../src/state'
import {SessionServiceClient} from '../src/third-party/api/src' import {mockedRootStore} from '../__mocks__/state-mock'
import {sessionClient as AtpApi} from '../src/third-party/api'
const WrappedComponent = ({children}: any) => { const customRender = (ui: any, storeMock?: any) =>
const api = AtpApi.service(DEFAULT_SERVICE) as SessionServiceClient render(
const rootStore = new RootStoreModel(api) // eslint-disable-next-line react-native/no-inline-styles
return (
<GestureHandlerRootView style={{flex: 1}}> <GestureHandlerRootView style={{flex: 1}}>
<RootSiblingParent> <RootSiblingParent>
<RootStoreProvider value={rootStore}> <RootStoreProvider
<SafeAreaProvider>{children}</SafeAreaProvider> value={
storeMock != null
? {...mockedRootStore, ...storeMock}
: mockedRootStore
}>
<SafeAreaProvider>{ui}</SafeAreaProvider>
</RootStoreProvider> </RootStoreProvider>
</RootSiblingParent> </RootSiblingParent>
</GestureHandlerRootView> </GestureHandlerRootView>,
) )
}
const customRender = (ui: any, options?: any) =>
render(ui, {wrapper: WrappedComponent, ...options})
// re-export everything // re-export everything
export * from '@testing-library/react-native' export * from '@testing-library/react-native'

View File

@ -9,8 +9,7 @@
"start": "react-native start", "start": "react-native start",
"clean-cache": "rm -rf node_modules/.cache/babel-loader/*", "clean-cache": "rm -rf node_modules/.cache/babel-loader/*",
"test": "jest --coverage", "test": "jest --coverage",
"lint": "eslint . --ext .js,.jsx,.ts,.tsx", "lint": "eslint . --ext .js,.jsx,.ts,.tsx"
"postinstall": "patch-package"
}, },
"dependencies": { "dependencies": {
"@atproto/api": "^0.0.6", "@atproto/api": "^0.0.6",
@ -34,7 +33,6 @@
"lru_map": "^0.4.1", "lru_map": "^0.4.1",
"mobx": "^6.6.1", "mobx": "^6.6.1",
"mobx-react-lite": "^3.4.0", "mobx-react-lite": "^3.4.0",
"patch-package": "^6.5.0",
"react": "17.0.2", "react": "17.0.2",
"react-circular-progressbar": "^2.1.0", "react-circular-progressbar": "^2.1.0",
"react-dom": "17.0.2", "react-dom": "17.0.2",
@ -112,6 +110,8 @@
"<rootDir>/node_modules/", "<rootDir>/node_modules/",
"<rootDir>/src/platform", "<rootDir>/src/platform",
"<rootDir>/src/third-party", "<rootDir>/src/third-party",
"<rootDir>/src/view/com/util",
"<rootDir>/src/state/lib",
"<rootDir>/__tests__/test-utils.js" "<rootDir>/__tests__/test-utils.js"
] ]
}, },

File diff suppressed because one or more lines are too long

View File

@ -46,6 +46,7 @@ export function Autocomplete({
<Animated.View style={[styles.outer, pal.view, pal.border, topAnimStyle]}> <Animated.View style={[styles.outer, pal.view, pal.border, topAnimStyle]}>
{items.map((item, i) => ( {items.map((item, i) => (
<TouchableOpacity <TouchableOpacity
testID="autocompleteButton"
key={i} key={i}
style={[pal.border, styles.item]} style={[pal.border, styles.item]}
onPress={() => onSelect(item.handle)}> onPress={() => onSelect(item.handle)}>

View File

@ -56,11 +56,12 @@ export const ComposePost = observer(function ComposePost({
const [isSelectingPhotos, setIsSelectingPhotos] = useState(false) const [isSelectingPhotos, setIsSelectingPhotos] = useState(false)
const [selectedPhotos, setSelectedPhotos] = useState<string[]>([]) const [selectedPhotos, setSelectedPhotos] = useState<string[]>([])
const autocompleteView = useMemo<UserAutocompleteViewModel>( // Using default import (React.use...) instead of named import (use...) to be able to mock store's data in jest environment
const autocompleteView = React.useMemo<UserAutocompleteViewModel>(
() => new UserAutocompleteViewModel(store), () => new UserAutocompleteViewModel(store),
[store], [store],
) )
const localPhotos = useMemo<UserLocalPhotosModel>( const localPhotos = React.useMemo<UserLocalPhotosModel>(
() => new UserLocalPhotosModel(store), () => new UserLocalPhotosModel(store),
[store], [store],
) )
@ -179,11 +180,14 @@ export const ComposePost = observer(function ComposePost({
return ( return (
<KeyboardAvoidingView <KeyboardAvoidingView
testID="composePostView"
behavior={Platform.OS === 'ios' ? 'padding' : 'height'} behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={[pal.view, styles.outer]}> style={[pal.view, styles.outer]}>
<SafeAreaView style={s.flex1}> <SafeAreaView style={s.flex1}>
<View style={styles.topbar}> <View style={styles.topbar}>
<TouchableOpacity onPress={onPressCancel}> <TouchableOpacity
testID="composerCancelButton"
onPress={onPressCancel}>
<Text style={[pal.link, s.f18]}>Cancel</Text> <Text style={[pal.link, s.f18]}>Cancel</Text>
</TouchableOpacity> </TouchableOpacity>
<View style={s.flex1} /> <View style={s.flex1} />
@ -192,7 +196,9 @@ export const ComposePost = observer(function ComposePost({
<ActivityIndicator /> <ActivityIndicator />
</View> </View>
) : canPost ? ( ) : canPost ? (
<TouchableOpacity onPress={onPressPublish}> <TouchableOpacity
testID="composerPublishButton"
onPress={onPressPublish}>
<LinearGradient <LinearGradient
colors={[gradients.primary.start, gradients.primary.end]} colors={[gradients.primary.start, gradients.primary.end]}
start={{x: 0, y: 0}} start={{x: 0, y: 0}}
@ -257,6 +263,7 @@ export const ComposePost = observer(function ComposePost({
size={50} size={50}
/> />
<TextInput <TextInput
testID="composerTextInput"
ref={textInput} ref={textInput}
multiline multiline
scrollEnabled scrollEnabled
@ -283,6 +290,7 @@ export const ComposePost = observer(function ComposePost({
)} )}
<View style={[pal.border, styles.bottomBar]}> <View style={[pal.border, styles.bottomBar]}>
<TouchableOpacity <TouchableOpacity
testID="composerSelectPhotosButton"
onPress={onPressSelectPhotos} onPress={onPressSelectPhotos}
style={[s.pl5]} style={[s.pl5]}
hitSlop={HITSLOP}> hitSlop={HITSLOP}>

View File

@ -85,21 +85,25 @@ export const PhotoCarouselPicker = ({
return ( return (
<ScrollView <ScrollView
testID="photoCarouselPickerView"
horizontal horizontal
style={[pal.view, styles.photosContainer]} style={[pal.view, styles.photosContainer]}
showsHorizontalScrollIndicator={false}> showsHorizontalScrollIndicator={false}>
<TouchableOpacity <TouchableOpacity
testID="openCameraButton"
style={[styles.galleryButton, pal.border, styles.photo]} style={[styles.galleryButton, pal.border, styles.photo]}
onPress={handleOpenCamera}> onPress={handleOpenCamera}>
<FontAwesomeIcon icon="camera" size={24} style={pal.link} /> <FontAwesomeIcon icon="camera" size={24} style={pal.link} />
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity <TouchableOpacity
testID="openGalleryButton"
style={[styles.galleryButton, pal.border, styles.photo]} style={[styles.galleryButton, pal.border, styles.photo]}
onPress={handleOpenGallery}> onPress={handleOpenGallery}>
<FontAwesomeIcon icon="image" style={pal.link} size={24} /> <FontAwesomeIcon icon="image" style={pal.link} size={24} />
</TouchableOpacity> </TouchableOpacity>
{localPhotos.photos.map((item: any, index: number) => ( {localPhotos.photos.map((item: any, index: number) => (
<TouchableOpacity <TouchableOpacity
testID="openSelectPhotoButton"
key={`local-image-${index}`} key={`local-image-${index}`}
style={[pal.border, styles.photoButton]} style={[pal.border, styles.photoButton]}
onPress={() => handleSelectPhoto(item.node.image.uri)}> onPress={() => handleSelectPhoto(item.node.image.uri)}>

View File

@ -17,6 +17,7 @@ export function ComposePrompt({
const pal = usePalette('default') const pal = usePalette('default')
return ( return (
<TouchableOpacity <TouchableOpacity
testID="composePromptButton"
style={[ style={[
pal.view, pal.view,
pal.border, pal.border,

View File

@ -25,13 +25,14 @@ export const SelectedPhoto = ({
) )
return selectedPhotos.length !== 0 ? ( return selectedPhotos.length !== 0 ? (
<View style={styles.imageContainer}> <View testID="selectedPhotosView" style={styles.imageContainer}>
{selectedPhotos.length !== 0 && {selectedPhotos.length !== 0 &&
selectedPhotos.map((item, index) => ( selectedPhotos.map((item, index) => (
<View <View
key={`selected-image-${index}`} key={`selected-image-${index}`}
style={[styles.image, imageStyle]}> style={[styles.image, imageStyle]}>
<TouchableOpacity <TouchableOpacity
testID="removePhotoButton"
onPress={() => handleRemovePhoto(item)} onPress={() => handleRemovePhoto(item)}
style={styles.removePhotoButton}> style={styles.removePhotoButton}>
<FontAwesomeIcon <FontAwesomeIcon
@ -41,7 +42,11 @@ export const SelectedPhoto = ({
/> />
</TouchableOpacity> </TouchableOpacity>
<Image style={[styles.image, imageStyle]} source={{uri: item}} /> <Image
testID="selectedPhotoImage"
style={[styles.image, imageStyle]}
source={{uri: item}}
/>
</View> </View>
))} ))}
</View> </View>

View File

@ -1,4 +1,4 @@
import React, {useMemo, useEffect, useState} from 'react' import React, {useEffect, useState} from 'react'
import { import {
ActivityIndicator, ActivityIndicator,
FlatList, FlatList,
@ -36,7 +36,8 @@ export const SuggestedFollows = observer(
const store = useStores() const store = useStores()
const [follows, setFollows] = useState<Record<string, string>>({}) const [follows, setFollows] = useState<Record<string, string>>({})
const view = useMemo<SuggestedActorsViewModel>( // Using default import (React.use...) instead of named import (use...) to be able to mock store's data in jest environment
const view = React.useMemo<SuggestedActorsViewModel>(
() => new SuggestedActorsViewModel(store), () => new SuggestedActorsViewModel(store),
[], [],
) )

View File

@ -171,7 +171,7 @@ export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => {
const isReady = !!email && !!password && !!handle && is13 const isReady = !!email && !!password && !!handle && is13
return ( return (
<ScrollView style={{flex: 1}}> <ScrollView testID="createAccount" style={{flex: 1}}>
<KeyboardAvoidingView behavior="padding" style={{flex: 1}}> <KeyboardAvoidingView behavior="padding" style={{flex: 1}}>
<View style={styles.logoHero}> <View style={styles.logoHero}>
<Logo /> <Logo />
@ -193,6 +193,7 @@ export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => {
<View style={styles.groupContent}> <View style={styles.groupContent}>
<FontAwesomeIcon icon="globe" style={styles.groupContentIcon} /> <FontAwesomeIcon icon="globe" style={styles.groupContentIcon} />
<TouchableOpacity <TouchableOpacity
testID="registerSelectServiceButton"
style={styles.textBtn} style={styles.textBtn}
onPress={onPressSelectService}> onPress={onPressSelectService}>
<Text style={styles.textBtnLabel}> <Text style={styles.textBtnLabel}>
@ -235,6 +236,7 @@ export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => {
style={styles.groupContentIcon} style={styles.groupContentIcon}
/> />
<TextInput <TextInput
testID="registerEmailInput"
style={[styles.textInput]} style={[styles.textInput]}
placeholder="Email address" placeholder="Email address"
placeholderTextColor={colors.blue0} placeholderTextColor={colors.blue0}
@ -248,6 +250,7 @@ export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => {
<View style={styles.groupContent}> <View style={styles.groupContent}>
<FontAwesomeIcon icon="lock" style={styles.groupContentIcon} /> <FontAwesomeIcon icon="lock" style={styles.groupContentIcon} />
<TextInput <TextInput
testID="registerPasswordInput"
style={[styles.textInput]} style={[styles.textInput]}
placeholder="Choose your password" placeholder="Choose your password"
placeholderTextColor={colors.blue0} placeholderTextColor={colors.blue0}
@ -273,6 +276,7 @@ export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => {
<View style={styles.groupContent}> <View style={styles.groupContent}>
<FontAwesomeIcon icon="at" style={styles.groupContentIcon} /> <FontAwesomeIcon icon="at" style={styles.groupContentIcon} />
<TextInput <TextInput
testID="registerHandleInput"
style={[styles.textInput]} style={[styles.textInput]}
placeholder="eg alice" placeholder="eg alice"
placeholderTextColor={colors.blue0} placeholderTextColor={colors.blue0}
@ -317,6 +321,7 @@ export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => {
</View> </View>
<View style={styles.groupContent}> <View style={styles.groupContent}>
<TouchableOpacity <TouchableOpacity
testID="registerIs13Input"
style={styles.textBtn} style={styles.textBtn}
onPress={() => setIs13(!is13)}> onPress={() => setIs13(!is13)}>
<View style={is13 ? styles.checkboxFilled : styles.checkbox}> <View style={is13 ? styles.checkboxFilled : styles.checkbox}>
@ -339,7 +344,9 @@ export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => {
</TouchableOpacity> </TouchableOpacity>
<View style={s.flex1} /> <View style={s.flex1} />
{isReady ? ( {isReady ? (
<TouchableOpacity onPress={onPressNext}> <TouchableOpacity
testID="createAccountButton"
onPress={onPressNext}>
{isProcessing ? ( {isProcessing ? (
<ActivityIndicator color="#fff" /> <ActivityIndicator color="#fff" />
) : ( ) : (
@ -347,7 +354,9 @@ export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => {
)} )}
</TouchableOpacity> </TouchableOpacity>
) : !serviceDescription && error ? ( ) : !serviceDescription && error ? (
<TouchableOpacity onPress={onPressRetryConnect}> <TouchableOpacity
testID="registerRetryButton"
onPress={onPressRetryConnect}>
<Text style={[s.white, s.f18, s.bold, s.pr5]}>Retry</Text> <Text style={[s.white, s.f18, s.bold, s.pr5]}>Retry</Text>
</TouchableOpacity> </TouchableOpacity>
) : !serviceDescription ? ( ) : !serviceDescription ? (

View File

@ -69,7 +69,7 @@ export const Signin = ({onPressBack}: {onPressBack: () => void}) => {
const onPressRetryConnect = () => setRetryDescribeTrigger({}) const onPressRetryConnect = () => setRetryDescribeTrigger({})
return ( return (
<KeyboardAvoidingView behavior="padding" style={{flex: 1}}> <KeyboardAvoidingView testID="signIn" behavior="padding" style={{flex: 1}}>
<View style={styles.logoHero}> <View style={styles.logoHero}>
<Logo /> <Logo />
</View> </View>
@ -194,8 +194,9 @@ const LoginForm = ({
const isReady = !!serviceDescription && !!handle && !!password const isReady = !!serviceDescription && !!handle && !!password
return ( return (
<> <>
<View style={styles.group}> <View testID="loginFormView" style={styles.group}>
<TouchableOpacity <TouchableOpacity
testID="loginSelectServiceButton"
style={[styles.groupTitle, {paddingRight: 0, paddingVertical: 6}]} style={[styles.groupTitle, {paddingRight: 0, paddingVertical: 6}]}
onPress={onPressSelectService}> onPress={onPressSelectService}>
<Text style={[s.flex1, s.white, s.f18, s.bold]} numberOfLines={1}> <Text style={[s.flex1, s.white, s.f18, s.bold]} numberOfLines={1}>
@ -213,6 +214,7 @@ const LoginForm = ({
<View style={styles.groupContent}> <View style={styles.groupContent}>
<FontAwesomeIcon icon="at" style={styles.groupContentIcon} /> <FontAwesomeIcon icon="at" style={styles.groupContentIcon} />
<TextInput <TextInput
testID="loginUsernameInput"
style={styles.textInput} style={styles.textInput}
placeholder="Username" placeholder="Username"
placeholderTextColor={colors.blue0} placeholderTextColor={colors.blue0}
@ -227,6 +229,7 @@ const LoginForm = ({
<View style={styles.groupContent}> <View style={styles.groupContent}>
<FontAwesomeIcon icon="lock" style={styles.groupContentIcon} /> <FontAwesomeIcon icon="lock" style={styles.groupContentIcon} />
<TextInput <TextInput
testID="loginPasswordInput"
style={styles.textInput} style={styles.textInput}
placeholder="Password" placeholder="Password"
placeholderTextColor={colors.blue0} placeholderTextColor={colors.blue0}
@ -238,6 +241,7 @@ const LoginForm = ({
editable={!isProcessing} editable={!isProcessing}
/> />
<TouchableOpacity <TouchableOpacity
testID="forgotPasswordButton"
style={styles.textInputInnerBtn} style={styles.textInputInnerBtn}
onPress={onPressForgotPassword}> onPress={onPressForgotPassword}>
<Text style={styles.textInputInnerBtnLabel}>Forgot</Text> <Text style={styles.textInputInnerBtnLabel}>Forgot</Text>
@ -260,7 +264,9 @@ const LoginForm = ({
</TouchableOpacity> </TouchableOpacity>
<View style={s.flex1} /> <View style={s.flex1} />
{!serviceDescription && error ? ( {!serviceDescription && error ? (
<TouchableOpacity onPress={onPressRetryConnect}> <TouchableOpacity
testID="loginRetryButton"
onPress={onPressRetryConnect}>
<Text style={[s.white, s.f18, s.bold, s.pr5]}>Retry</Text> <Text style={[s.white, s.f18, s.bold, s.pr5]}>Retry</Text>
</TouchableOpacity> </TouchableOpacity>
) : !serviceDescription ? ( ) : !serviceDescription ? (
@ -271,7 +277,7 @@ const LoginForm = ({
) : isProcessing ? ( ) : isProcessing ? (
<ActivityIndicator color="#fff" /> <ActivityIndicator color="#fff" />
) : isReady ? ( ) : isReady ? (
<TouchableOpacity onPress={onPressNext}> <TouchableOpacity testID="loginNextButton" onPress={onPressNext}>
<Text style={[s.white, s.f18, s.bold, s.pr5]}>Next</Text> <Text style={[s.white, s.f18, s.bold, s.pr5]}>Next</Text>
</TouchableOpacity> </TouchableOpacity>
) : undefined} ) : undefined}
@ -339,8 +345,9 @@ const ForgotPasswordForm = ({
Enter the email you used to create your account. We'll send you a "reset Enter the email you used to create your account. We'll send you a "reset
code" so you can set a new password. code" so you can set a new password.
</Text> </Text>
<View style={styles.group}> <View testID="forgotPasswordView" style={styles.group}>
<TouchableOpacity <TouchableOpacity
testID="forgotPasswordSelectServiceButton"
style={[styles.groupContent, {borderTopWidth: 0}]} style={[styles.groupContent, {borderTopWidth: 0}]}
onPress={onPressSelectService}> onPress={onPressSelectService}>
<FontAwesomeIcon icon="globe" style={styles.groupContentIcon} /> <FontAwesomeIcon icon="globe" style={styles.groupContentIcon} />
@ -359,6 +366,7 @@ const ForgotPasswordForm = ({
<View style={styles.groupContent}> <View style={styles.groupContent}>
<FontAwesomeIcon icon="envelope" style={styles.groupContentIcon} /> <FontAwesomeIcon icon="envelope" style={styles.groupContentIcon} />
<TextInput <TextInput
testID="forgotPasswordEmail"
style={styles.textInput} style={styles.textInput}
placeholder="Email address" placeholder="Email address"
placeholderTextColor={colors.blue0} placeholderTextColor={colors.blue0}
@ -391,7 +399,7 @@ const ForgotPasswordForm = ({
) : !email ? ( ) : !email ? (
<Text style={[s.blue1, s.f18, s.bold, s.pr5]}>Next</Text> <Text style={[s.blue1, s.f18, s.bold, s.pr5]}>Next</Text>
) : ( ) : (
<TouchableOpacity onPress={onPressNext}> <TouchableOpacity testID="newPasswordButton" onPress={onPressNext}>
<Text style={[s.white, s.f18, s.bold, s.pr5]}>Next</Text> <Text style={[s.white, s.f18, s.bold, s.pr5]}>Next</Text>
</TouchableOpacity> </TouchableOpacity>
)} )}
@ -451,10 +459,11 @@ const SetNewPasswordForm = ({
You will receive an email with a "reset code." Enter that code here, You will receive an email with a "reset code." Enter that code here,
then enter your new password. then enter your new password.
</Text> </Text>
<View style={styles.group}> <View testID="newPasswordView" style={styles.group}>
<View style={[styles.groupContent, {borderTopWidth: 0}]}> <View style={[styles.groupContent, {borderTopWidth: 0}]}>
<FontAwesomeIcon icon="ticket" style={styles.groupContentIcon} /> <FontAwesomeIcon icon="ticket" style={styles.groupContentIcon} />
<TextInput <TextInput
testID="resetCodeInput"
style={[styles.textInput]} style={[styles.textInput]}
placeholder="Reset code" placeholder="Reset code"
placeholderTextColor={colors.blue0} placeholderTextColor={colors.blue0}
@ -469,6 +478,7 @@ const SetNewPasswordForm = ({
<View style={styles.groupContent}> <View style={styles.groupContent}>
<FontAwesomeIcon icon="lock" style={styles.groupContentIcon} /> <FontAwesomeIcon icon="lock" style={styles.groupContentIcon} />
<TextInput <TextInput
testID="newPasswordInput"
style={styles.textInput} style={styles.textInput}
placeholder="New password" placeholder="New password"
placeholderTextColor={colors.blue0} placeholderTextColor={colors.blue0}
@ -501,7 +511,7 @@ const SetNewPasswordForm = ({
) : !resetCode || !password ? ( ) : !resetCode || !password ? (
<Text style={[s.blue1, s.f18, s.bold, s.pr5]}>Next</Text> <Text style={[s.blue1, s.f18, s.bold, s.pr5]}>Next</Text>
) : ( ) : (
<TouchableOpacity onPress={onPressNext}> <TouchableOpacity testID="setNewPasswordButton" onPress={onPressNext}>
<Text style={[s.white, s.f18, s.bold, s.pr5]}>Next</Text> <Text style={[s.white, s.f18, s.bold, s.pr5]}>Next</Text>
</TouchableOpacity> </TouchableOpacity>
)} )}

View File

@ -1,4 +1,4 @@
import React, {useState} from 'react' import React from 'react'
import {StyleSheet, TouchableOpacity, View} from 'react-native' import {StyleSheet, TouchableOpacity, View} from 'react-native'
import LinearGradient from 'react-native-linear-gradient' import LinearGradient from 'react-native-linear-gradient'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
@ -13,7 +13,8 @@ import {s, colors, gradients} from '../../lib/styles'
export function InviteAccepter({item}: {item: NotificationsViewItemModel}) { export function InviteAccepter({item}: {item: NotificationsViewItemModel}) {
const store = useStores() const store = useStores()
const [confirmationUri, setConfirmationUri] = useState<string>('') // Using default import (React.use...) instead of named import (use...) to be able to mock store's data in jest environment
const [confirmationUri, setConfirmationUri] = React.useState<string>('')
const isMember = const isMember =
confirmationUri !== '' || store.me.memberships?.isMemberOf(item.author.did) confirmationUri !== '' || store.me.memberships?.isMemberOf(item.author.did)
const onPressAccept = async () => { const onPressAccept = async () => {
@ -54,7 +55,7 @@ export function InviteAccepter({item}: {item: NotificationsViewItemModel}) {
return ( return (
<View style={styles.container}> <View style={styles.container}>
{!isMember ? ( {!isMember ? (
<TouchableOpacity onPress={onPressAccept}> <TouchableOpacity testID="acceptInviteButton" onPress={onPressAccept}>
<LinearGradient <LinearGradient
colors={[gradients.primary.start, gradients.primary.end]} colors={[gradients.primary.start, gradients.primary.end]}
start={{x: 0, y: 0}} start={{x: 0, y: 0}}
@ -64,7 +65,7 @@ export function InviteAccepter({item}: {item: NotificationsViewItemModel}) {
</LinearGradient> </LinearGradient>
</TouchableOpacity> </TouchableOpacity>
) : ( ) : (
<View style={styles.inviteAccepted}> <View testID="inviteAccepted" style={styles.inviteAccepted}>
<FontAwesomeIcon icon="check" size={14} style={s.mr5} /> <FontAwesomeIcon icon="check" size={14} style={s.mr5} />
<Text style={[s.gray5, s.f15]}>Invite accepted</Text> <Text style={[s.gray5, s.f15]}>Invite accepted</Text>
</View> </View>

View File

@ -1,4 +1,4 @@
import React, {useState, useEffect} from 'react' import React, {useEffect} from 'react'
import {observer} from 'mobx-react-lite' import {observer} from 'mobx-react-lite'
import {ActivityIndicator, FlatList, StyleSheet, View} from 'react-native' import {ActivityIndicator, FlatList, StyleSheet, View} from 'react-native'
import { import {
@ -18,7 +18,8 @@ export const PostRepostedBy = observer(function PostRepostedBy({
uri: string uri: string
}) { }) {
const store = useStores() const store = useStores()
const [view, setView] = useState<RepostedByViewModel | undefined>() // Using default import (React.use...) instead of named import (use...) to be able to mock store's data in jest environment
const [view, setView] = React.useState<RepostedByViewModel | undefined>()
useEffect(() => { useEffect(() => {
if (view?.params.uri === uri) { if (view?.params.uri === uri) {

View File

@ -1,4 +1,4 @@
import React, {useState, useEffect} from 'react' import React, {useEffect} from 'react'
import {observer} from 'mobx-react-lite' import {observer} from 'mobx-react-lite'
import {ActivityIndicator, FlatList, StyleSheet, View} from 'react-native' import {ActivityIndicator, FlatList, StyleSheet, View} from 'react-native'
import { import {
@ -20,7 +20,7 @@ export const PostVotedBy = observer(function PostVotedBy({
direction: 'up' | 'down' direction: 'up' | 'down'
}) { }) {
const store = useStores() const store = useStores()
const [view, setView] = useState<VotesViewModel | undefined>() const [view, setView] = React.useState<VotesViewModel | undefined>()
useEffect(() => { useEffect(() => {
if (view?.params.uri === uri) { if (view?.params.uri === uri) {

View File

@ -25,6 +25,7 @@ export const Feed = observer(function Feed({
onPressCompose, onPressCompose,
onPressTryAgain, onPressTryAgain,
onScroll, onScroll,
testID,
}: { }: {
feed: FeedModel feed: FeedModel
style?: StyleProp<ViewStyle> style?: StyleProp<ViewStyle>
@ -32,6 +33,7 @@ export const Feed = observer(function Feed({
onPressCompose: () => void onPressCompose: () => void
onPressTryAgain?: () => void onPressTryAgain?: () => void
onScroll?: OnScrollCb onScroll?: OnScrollCb
testID?: string
}) { }) {
// TODO optimize renderItem or FeedItem, we're getting this notice from RN: -prf // TODO optimize renderItem or FeedItem, we're getting this notice from RN: -prf
// VirtualizedList: You have a large list that is slow to update - make sure your // VirtualizedList: You have a large list that is slow to update - make sure your
@ -83,7 +85,7 @@ export const Feed = observer(function Feed({
<View /> <View />
) )
return ( return (
<View style={style}> <View testID={testID} style={style}>
{!data && <ComposePrompt onPressCompose={onPressCompose} />} {!data && <ComposePrompt onPressCompose={onPressCompose} />}
{feed.isLoading && !data && <PostFeedLoadingPlaceholder />} {feed.isLoading && !data && <PostFeedLoadingPlaceholder />}
{feed.hasError && ( {feed.hasError && (

View File

@ -1,4 +1,4 @@
import React, {useState, useEffect} from 'react' import React, {useEffect} from 'react'
import {observer} from 'mobx-react-lite' import {observer} from 'mobx-react-lite'
import {ActivityIndicator, FlatList, StyleSheet, View} from 'react-native' import {ActivityIndicator, FlatList, StyleSheet, View} from 'react-native'
import { import {
@ -19,7 +19,7 @@ export const ProfileFollowers = observer(function ProfileFollowers({
name: string name: string
}) { }) {
const store = useStores() const store = useStores()
const [view, setView] = useState<UserFollowersViewModel | undefined>() const [view, setView] = React.useState<UserFollowersViewModel | undefined>()
useEffect(() => { useEffect(() => {
if (view?.params.user === name) { if (view?.params.user === name) {

View File

@ -1,4 +1,4 @@
import React, {useState, useEffect} from 'react' import React, {useEffect} from 'react'
import {observer} from 'mobx-react-lite' import {observer} from 'mobx-react-lite'
import {ActivityIndicator, FlatList, StyleSheet, View} from 'react-native' import {ActivityIndicator, FlatList, StyleSheet, View} from 'react-native'
import { import {
@ -10,7 +10,7 @@ import {Link} from '../util/Link'
import {Text} from '../util/text/Text' import {Text} from '../util/text/Text'
import {ErrorMessage} from '../util/error/ErrorMessage' import {ErrorMessage} from '../util/error/ErrorMessage'
import {UserAvatar} from '../util/UserAvatar' import {UserAvatar} from '../util/UserAvatar'
import {s, colors} from '../../lib/styles' import {s} from '../../lib/styles'
import {usePalette} from '../../lib/hooks/usePalette' import {usePalette} from '../../lib/hooks/usePalette'
export const ProfileFollows = observer(function ProfileFollows({ export const ProfileFollows = observer(function ProfileFollows({
@ -19,7 +19,7 @@ export const ProfileFollows = observer(function ProfileFollows({
name: string name: string
}) { }) {
const store = useStores() const store = useStores()
const [view, setView] = useState<UserFollowsViewModel | undefined>() const [view, setView] = React.useState<UserFollowsViewModel | undefined>()
useEffect(() => { useEffect(() => {
if (view?.params.user === name) { if (view?.params.user === name) {

View File

@ -147,7 +147,7 @@ export const ProfileHeader = observer(function ProfileHeader({
// = // =
if (view.hasError) { if (view.hasError) {
return ( return (
<View> <View testID="profileHeaderHasError">
<Text>{view.error}</Text> <Text>{view.error}</Text>
</View> </View>
) )
@ -192,6 +192,7 @@ export const ProfileHeader = observer(function ProfileHeader({
<View style={[styles.buttonsLine]}> <View style={[styles.buttonsLine]}>
{isMe ? ( {isMe ? (
<TouchableOpacity <TouchableOpacity
testID="profileHeaderEditProfileButton"
onPress={onPressEditProfile} onPress={onPressEditProfile}
style={[styles.btn, styles.mainBtn, pal.btn]}> style={[styles.btn, styles.mainBtn, pal.btn]}>
<Text type="button" style={pal.text}> <Text type="button" style={pal.text}>
@ -214,7 +215,9 @@ export const ProfileHeader = observer(function ProfileHeader({
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
) : ( ) : (
<TouchableOpacity onPress={onPressToggleFollow}> <TouchableOpacity
testID="profileHeaderToggleFollowButton"
onPress={onPressToggleFollow}>
<LinearGradient <LinearGradient
colors={[gradient[1], gradient[0]]} colors={[gradient[1], gradient[0]]}
start={{x: 0, y: 0}} start={{x: 0, y: 0}}
@ -257,6 +260,7 @@ export const ProfileHeader = observer(function ProfileHeader({
</View> </View>
<View style={styles.metricsLine}> <View style={styles.metricsLine}>
<TouchableOpacity <TouchableOpacity
testID="profileHeaderFollowersButton"
style={[s.flexRow, s.mr10]} style={[s.flexRow, s.mr10]}
onPress={onPressFollowers}> onPress={onPressFollowers}>
<Text type="body2" style={[s.bold, s.mr2, pal.text]}> <Text type="body2" style={[s.bold, s.mr2, pal.text]}>
@ -268,6 +272,7 @@ export const ProfileHeader = observer(function ProfileHeader({
</TouchableOpacity> </TouchableOpacity>
{view.isUser ? ( {view.isUser ? (
<TouchableOpacity <TouchableOpacity
testID="profileHeaderFollowsButton"
style={[s.flexRow, s.mr10]} style={[s.flexRow, s.mr10]}
onPress={onPressFollows}> onPress={onPressFollows}>
<Text type="body2" style={[s.bold, s.mr2, pal.text]}> <Text type="body2" style={[s.bold, s.mr2, pal.text]}>
@ -280,6 +285,7 @@ export const ProfileHeader = observer(function ProfileHeader({
) : undefined} ) : undefined}
{view.isScene ? ( {view.isScene ? (
<TouchableOpacity <TouchableOpacity
testID="profileHeaderMembersButton"
style={[s.flexRow, s.mr10]} style={[s.flexRow, s.mr10]}
onPress={onPressMembers}> onPress={onPressMembers}>
<Text type="body2" style={[s.bold, s.mr2, pal.text]}> <Text type="body2" style={[s.bold, s.mr2, pal.text]}>
@ -350,7 +356,9 @@ export const ProfileHeader = observer(function ProfileHeader({
</View> </View>
{view.isScene && view.creator === store.me.did ? ( {view.isScene && view.creator === store.me.did ? (
<View style={[styles.sceneAdminContainer, pal.border]}> <View style={[styles.sceneAdminContainer, pal.border]}>
<TouchableOpacity onPress={onPressInviteMembers}> <TouchableOpacity
testID="profileHeaderInviteMembersButton"
onPress={onPressInviteMembers}>
<LinearGradient <LinearGradient
colors={[gradient[1], gradient[0]]} colors={[gradient[1], gradient[0]]}
start={{x: 0, y: 0}} start={{x: 0, y: 0}}
@ -369,6 +377,7 @@ export const ProfileHeader = observer(function ProfileHeader({
</View> </View>
) : undefined} ) : undefined}
<TouchableOpacity <TouchableOpacity
testID="profileHeaderAviButton"
style={[pal.view, {borderColor: pal.colors.background}, styles.avi]} style={[pal.view, {borderColor: pal.colors.background}, styles.avi]}
onPress={onPressAvi}> onPress={onPressAvi}>
<UserAvatar <UserAvatar

View File

@ -1,4 +1,4 @@
import React, {useState, useEffect} from 'react' import React, {useEffect} from 'react'
import {observer} from 'mobx-react-lite' import {observer} from 'mobx-react-lite'
import {ActivityIndicator, FlatList, View} from 'react-native' import {ActivityIndicator, FlatList, View} from 'react-native'
import {MembersViewModel, MemberItem} from '../../../state/models/members-view' import {MembersViewModel, MemberItem} from '../../../state/models/members-view'
@ -12,7 +12,8 @@ export const ProfileMembers = observer(function ProfileMembers({
name: string name: string
}) { }) {
const store = useStores() const store = useStores()
const [view, setView] = useState<MembersViewModel | undefined>() // Using default import (React.use...) instead of named import (use...) to be able to mock store's data in jest environment
const [view, setView] = React.useState<MembersViewModel | undefined>()
useEffect(() => { useEffect(() => {
if (view?.params.actor === name) { if (view?.params.actor === name) {
@ -37,7 +38,7 @@ export const ProfileMembers = observer(function ProfileMembers({
view.params.actor !== name view.params.actor !== name
) { ) {
return ( return (
<View> <View testID="profileMembersActivityIndicatorView">
<ActivityIndicator /> <ActivityIndicator />
</View> </View>
) )
@ -68,7 +69,7 @@ export const ProfileMembers = observer(function ProfileMembers({
/> />
) )
return ( return (
<View> <View testID="profileMembersFlatList">
<FlatList <FlatList
data={view.members} data={view.members}
keyExtractor={item => item._reactKey} keyExtractor={item => item._reactKey}

View File

@ -115,6 +115,7 @@ export function PostCtrls(opts: PostCtrlsOpts) {
<View style={[styles.ctrls, opts.style]}> <View style={[styles.ctrls, opts.style]}>
<View style={s.flex1}> <View style={s.flex1}>
<TouchableOpacity <TouchableOpacity
testID="postCtrlsReplyButton"
style={styles.ctrl} style={styles.ctrl}
hitSlop={HITSLOP} hitSlop={HITSLOP}
onPress={opts.onPressReply}> onPress={opts.onPressReply}>
@ -130,6 +131,7 @@ export function PostCtrls(opts: PostCtrlsOpts) {
</View> </View>
<View style={s.flex1}> <View style={s.flex1}>
<TouchableOpacity <TouchableOpacity
testID="postCtrlsToggleRepostButton"
hitSlop={HITSLOP} hitSlop={HITSLOP}
onPress={onPressToggleRepostWrapper} onPress={onPressToggleRepostWrapper}
style={styles.ctrl}> style={styles.ctrl}>
@ -156,6 +158,7 @@ export function PostCtrls(opts: PostCtrlsOpts) {
</View> </View>
<View style={s.flex1}> <View style={s.flex1}>
<TouchableOpacity <TouchableOpacity
testID="postCtrlsToggleUpvoteButton"
style={styles.ctrl} style={styles.ctrl}
hitSlop={HITSLOP} hitSlop={HITSLOP}
onPress={onPressToggleUpvoteWrapper}> onPress={onPressToggleUpvoteWrapper}>

View File

@ -8,7 +8,6 @@ import {
} from 'react-native' } from 'react-native'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {Text} from '../text/Text' import {Text} from '../text/Text'
import {colors} from '../../../lib/styles'
import {useTheme} from '../../../lib/ThemeContext' import {useTheme} from '../../../lib/ThemeContext'
import {usePalette} from '../../../lib/hooks/usePalette' import {usePalette} from '../../../lib/hooks/usePalette'
@ -26,7 +25,7 @@ export function ErrorMessage({
const theme = useTheme() const theme = useTheme()
const pal = usePalette('error') const pal = usePalette('error')
return ( return (
<View style={[styles.outer, pal.view, style]}> <View testID="errorMessageView" style={[styles.outer, pal.view, style]}>
<View <View
style={[styles.errorIcon, {backgroundColor: theme.palette.error.icon}]}> style={[styles.errorIcon, {backgroundColor: theme.palette.error.icon}]}>
<FontAwesomeIcon icon="exclamation" style={pal.text} size={16} /> <FontAwesomeIcon icon="exclamation" style={pal.text} size={16} />
@ -38,7 +37,10 @@ export function ErrorMessage({
{message} {message}
</Text> </Text>
{onPressTryAgain && ( {onPressTryAgain && (
<TouchableOpacity style={styles.btn} onPress={onPressTryAgain}> <TouchableOpacity
testID="errorMessageTryAgainButton"
style={styles.btn}
onPress={onPressTryAgain}>
<FontAwesomeIcon <FontAwesomeIcon
icon="arrows-rotate" icon="arrows-rotate"
style={{color: theme.palette.error.icon}} style={{color: theme.palette.error.icon}}

View File

@ -11,16 +11,18 @@ export function ErrorScreen({
message, message,
details, details,
onPressTryAgain, onPressTryAgain,
testID,
}: { }: {
title: string title: string
message: string message: string
details?: string details?: string
onPressTryAgain?: () => void onPressTryAgain?: () => void
testID?: string
}) { }) {
const theme = useTheme() const theme = useTheme()
const pal = usePalette('error') const pal = usePalette('error')
return ( return (
<View style={[styles.outer, pal.view]}> <View testID={testID} style={[styles.outer, pal.view]}>
<View style={styles.errorIconContainer}> <View style={styles.errorIconContainer}>
<View <View
style={[ style={[
@ -40,6 +42,7 @@ export function ErrorScreen({
<Text style={[styles.message, pal.textLight]}>{message}</Text> <Text style={[styles.message, pal.textLight]}>{message}</Text>
{details && ( {details && (
<Text <Text
testID={`${testID}-details`}
type="body2" type="body2"
style={[ style={[
styles.details, styles.details,
@ -52,6 +55,7 @@ export function ErrorScreen({
{onPressTryAgain && ( {onPressTryAgain && (
<View style={styles.btnContainer}> <View style={styles.btnContainer}>
<TouchableOpacity <TouchableOpacity
testID="errorScreenTryAgainButton"
style={[styles.btn, {backgroundColor: theme.palette.error.icon}]} style={[styles.btn, {backgroundColor: theme.palette.error.icon}]}
onPress={onPressTryAgain}> onPress={onPressTryAgain}>
<FontAwesomeIcon icon="arrows-rotate" style={pal.text} size={16} /> <FontAwesomeIcon icon="arrows-rotate" style={pal.text} size={16} />

View File

@ -75,7 +75,8 @@ export function DropdownButton({
style={style} style={style}
onPress={onPress} onPress={onPress}
hitSlop={HITSLOP} hitSlop={HITSLOP}
ref={ref}> // Fix an issue where specific references cause runtime error in jest environment
ref={process.env.JEST_WORKER_ID != null ? null : ref}>
{children} {children}
</TouchableOpacity> </TouchableOpacity>
) )

View File

@ -25,7 +25,9 @@ export const Contacts = ({navIdx, visible, params}: ScreenParams) => {
return ( return (
<View> <View>
<View style={styles.section}> <View style={styles.section}>
<Text style={styles.title}>Contacts</Text> <Text testID="contactsTitle" style={styles.title}>
Contacts
</Text>
</View> </View>
<View style={styles.section}> <View style={styles.section}>
<View style={styles.searchContainer}> <View style={styles.searchContainer}>
@ -35,6 +37,7 @@ export const Contacts = ({navIdx, visible, params}: ScreenParams) => {
style={styles.searchIcon} style={styles.searchIcon}
/> />
<TextInput <TextInput
testID="contactsTextInput"
ref={inputRef} ref={inputRef}
value={searchText} value={searchText}
style={styles.searchInput} style={styles.searchInput}

View File

@ -1,4 +1,4 @@
import React, {useState, useEffect} from 'react' import React, {useEffect} from 'react'
import {StyleSheet, TouchableOpacity, View} from 'react-native' import {StyleSheet, TouchableOpacity, View} from 'react-native'
import {observer} from 'mobx-react-lite' import {observer} from 'mobx-react-lite'
import useAppState from 'react-native-appstate-hook' import useAppState from 'react-native-appstate-hook'
@ -24,12 +24,13 @@ export const Home = observer(function Home({
const store = useStores() const store = useStores()
const onMainScroll = useOnMainScroll(store) const onMainScroll = useOnMainScroll(store)
const safeAreaInsets = useSafeAreaInsets() const safeAreaInsets = useSafeAreaInsets()
const [hasSetup, setHasSetup] = useState<boolean>(false) const [wasVisible, setWasVisible] = React.useState<boolean>(false)
const {appState} = useAppState({ const {appState} = useAppState({
onForeground: () => doPoll(true), onForeground: () => doPoll(true),
}) })
const doPoll = (knownActive = false) => { const doPoll = React.useCallback(
(knownActive = false) => {
if ((!knownActive && appState !== 'active') || !visible) { if ((!knownActive && appState !== 'active') || !visible) {
return return
} }
@ -40,32 +41,31 @@ export const Home = observer(function Home({
store.me.mainFeed.checkForLatest().catch(e => { store.me.mainFeed.checkForLatest().catch(e => {
store.log.error('Failed to poll feed', e) store.log.error('Failed to poll feed', e)
}) })
} },
[appState, visible, store],
)
useEffect(() => { useEffect(() => {
let aborted = false
const pollInterval = setInterval(() => doPoll(), 15e3) const pollInterval = setInterval(() => doPoll(), 15e3)
if (!visible) { if (!visible) {
setWasVisible(false)
return
} else if (wasVisible) {
return return
} }
setWasVisible(true)
if (hasSetup) {
store.log.debug('Updating home feed')
store.me.mainFeed.update()
doPoll()
} else {
store.nav.setTitle(navIdx, 'Home') store.nav.setTitle(navIdx, 'Home')
store.log.debug('Fetching home feed') store.log.debug('Updating home feed')
store.me.mainFeed.setup().then(() => { if (store.me.mainFeed.hasContent) {
if (aborted) return store.me.mainFeed.update()
setHasSetup(true) } else {
}) store.me.mainFeed.setup()
} }
return () => { return () => {
clearInterval(pollInterval) clearInterval(pollInterval)
aborted = true
} }
}, [visible, store]) }, [visible, store, navIdx, doPoll, wasVisible])
const onPressCompose = () => { const onPressCompose = () => {
store.shell.openComposer({}) store.shell.openComposer({})
@ -82,6 +82,7 @@ export const Home = observer(function Home({
<View style={s.flex1}> <View style={s.flex1}>
<ViewHeader title="Bluesky" subtitle="Private Beta" canGoBack={false} /> <ViewHeader title="Bluesky" subtitle="Private Beta" canGoBack={false} />
<Feed <Feed
testID="homeFeed"
key="default" key="default"
feed={store.me.mainFeed} feed={store.me.mainFeed}
scrollElRef={scrollElRef} scrollElRef={scrollElRef}

View File

@ -35,8 +35,11 @@ const SigninOrCreateAccount = ({
<Text style={styles.title}>Bluesky</Text> <Text style={styles.title}>Bluesky</Text>
<Text style={styles.subtitle}>[ private beta ]</Text> <Text style={styles.subtitle}>[ private beta ]</Text>
</View> </View>
<View style={s.flex1}> <View testID="signinOrCreateAccount" style={s.flex1}>
<TouchableOpacity style={styles.btn} onPress={onPressCreateAccount}> <TouchableOpacity
testID="createAccountButton"
style={styles.btn}
onPress={onPressCreateAccount}>
<Text style={styles.btnLabel}>Create a new account</Text> <Text style={styles.btnLabel}>Create a new account</Text>
</TouchableOpacity> </TouchableOpacity>
<View style={styles.or}> <View style={styles.or}>
@ -60,7 +63,10 @@ const SigninOrCreateAccount = ({
</Svg> </Svg>
<Text style={styles.orLabel}>or</Text> <Text style={styles.orLabel}>or</Text>
</View> </View>
<TouchableOpacity style={styles.btn} onPress={onPressSignin}> <TouchableOpacity
testID="signInButton"
style={styles.btn}
onPress={onPressSignin}>
<Text style={styles.btnLabel}>Sign in</Text> <Text style={styles.btnLabel}>Sign in</Text>
</TouchableOpacity> </TouchableOpacity>
</View> </View>

View File

@ -7,7 +7,7 @@ import {useStores} from '../../state'
export const NotFound = () => { export const NotFound = () => {
const stores = useStores() const stores = useStores()
return ( return (
<View> <View testID="notFoundView">
<ViewHeader title="Page not found" /> <ViewHeader title="Page not found" />
<View <View
style={{ style={{
@ -16,7 +16,11 @@ export const NotFound = () => {
paddingTop: 100, paddingTop: 100,
}}> }}>
<Text style={{fontSize: 40, fontWeight: 'bold'}}>Page not found</Text> <Text style={{fontSize: 40, fontWeight: 'bold'}}>Page not found</Text>
<Button title="Home" onPress={() => stores.nav.navigate('/')} /> <Button
testID="navigateHomeButton"
title="Home"
onPress={() => stores.nav.navigate('/')}
/>
</View> </View>
</View> </View>
) )

View File

@ -1,4 +1,4 @@
import React, {useEffect, useState, useMemo} from 'react' import React, {useEffect, useState} from 'react'
import {ActivityIndicator, StyleSheet, View} from 'react-native' import {ActivityIndicator, StyleSheet, View} from 'react-native'
import {observer} from 'mobx-react-lite' import {observer} from 'mobx-react-lite'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
@ -30,7 +30,7 @@ export const Profile = observer(({navIdx, visible, params}: ScreenParams) => {
const store = useStores() const store = useStores()
const onMainScroll = useOnMainScroll(store) const onMainScroll = useOnMainScroll(store)
const [hasSetup, setHasSetup] = useState<boolean>(false) const [hasSetup, setHasSetup] = useState<boolean>(false)
const uiState = useMemo( const uiState = React.useMemo(
() => new ProfileUiModel(store, {user: params.name}), () => new ProfileUiModel(store, {user: params.name}),
[params.user], [params.user],
) )
@ -201,6 +201,7 @@ export const Profile = observer(({navIdx, visible, params}: ScreenParams) => {
? () => ( ? () => (
<> <>
<FontAwesomeIcon <FontAwesomeIcon
testID="shouldAdminButton"
icon="user-xmark" icon="user-xmark"
style={[s.mr5]} style={[s.mr5]}
size={14} size={14}
@ -242,10 +243,11 @@ export const Profile = observer(({navIdx, visible, params}: ScreenParams) => {
const title = const title =
uiState.profile.displayName || uiState.profile.handle || params.name uiState.profile.displayName || uiState.profile.handle || params.name
return ( return (
<View style={styles.container}> <View testID="profileView" style={styles.container}>
<ViewHeader title={title} /> <ViewHeader title={title} />
{uiState.profile.hasError ? ( {uiState.profile.hasError ? (
<ErrorScreen <ErrorScreen
testID="profileErrorScreen"
title="Failed to load profile" title="Failed to load profile"
message={`There was an issue when attempting to load ${params.name}`} message={`There was an issue when attempting to load ${params.name}`}
details={uiState.profile.error} details={uiState.profile.error}

View File

@ -57,6 +57,7 @@ export const Search = ({navIdx, visible, params}: ScreenParams) => {
<View style={[pal.view, pal.border, styles.inputContainer]}> <View style={[pal.view, pal.border, styles.inputContainer]}>
<MagnifyingGlassIcon style={[pal.text, styles.inputIcon]} /> <MagnifyingGlassIcon style={[pal.text, styles.inputIcon]} />
<TextInput <TextInput
testID="searchTextInput"
ref={textInput} ref={textInput}
placeholder="Type your query here..." placeholder="Type your query here..."
placeholderTextColor={pal.colors.textLight} placeholderTextColor={pal.colors.textLight}
@ -68,7 +69,7 @@ export const Search = ({navIdx, visible, params}: ScreenParams) => {
</View> </View>
<View style={styles.outputContainer}> <View style={styles.outputContainer}>
{query ? ( {query ? (
<ScrollView onScroll={Keyboard.dismiss}> <ScrollView testID="searchScrollView" onScroll={Keyboard.dismiss}>
{autocompleteView.searchRes.map((item, i) => ( {autocompleteView.searchRes.map((item, i) => (
<TouchableOpacity <TouchableOpacity
key={i} key={i}

View File

@ -75,6 +75,7 @@ export const Menu = observer(
onPress?: () => void onPress?: () => void
}) => ( }) => (
<TouchableOpacity <TouchableOpacity
testID="menuItemButton"
style={styles.menuItem} style={styles.menuItem}
onPress={onPress ? onPress : () => onNavigate(url || '/')}> onPress={onPress ? onPress : () => onNavigate(url || '/')}>
<View style={[styles.menuItemIconWrapper]}> <View style={[styles.menuItemIconWrapper]}>
@ -98,8 +99,9 @@ export const Menu = observer(
) )
return ( return (
<ScrollView style={[styles.view, pal.view]}> <ScrollView testID="menuView" style={[styles.view, pal.view]}>
<TouchableOpacity <TouchableOpacity
testID="profileCardButton"
onPress={() => onNavigate(`/profile/${store.me.handle}`)} onPress={() => onNavigate(`/profile/${store.me.handle}`)}
style={styles.profileCard}> style={styles.profileCard}>
<UserAvatar <UserAvatar
@ -123,6 +125,7 @@ export const Menu = observer(
</View> </View>
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity <TouchableOpacity
testID="searchBtn"
style={[styles.searchBtn, pal.btn]} style={[styles.searchBtn, pal.btn]}
onPress={() => onNavigate('/search')}> onPress={() => onNavigate('/search')}>
<MagnifyingGlassIcon <MagnifyingGlassIcon

View File

@ -116,11 +116,12 @@ export const TabsSelector = observer(
} }
if (!active) { if (!active) {
return <View /> return <View testID="emptyView" />
} }
return ( return (
<Animated.View <Animated.View
testID="tabsSelectorView"
style={[ style={[
styles.wrapper, styles.wrapper,
{bottom: insets.bottom + 55}, {bottom: insets.bottom + 55},
@ -129,7 +130,9 @@ export const TabsSelector = observer(
<View onLayout={onLayout}> <View onLayout={onLayout}>
<View style={[s.p10, styles.section]}> <View style={[s.p10, styles.section]}>
<View style={styles.btns}> <View style={styles.btns}>
<TouchableWithoutFeedback onPress={onPressShareTab}> <TouchableWithoutFeedback
testID="shareButton"
onPress={onPressShareTab}>
<View style={[styles.btn]}> <View style={[styles.btn]}>
<View style={styles.btnIcon}> <View style={styles.btnIcon}>
<FontAwesomeIcon size={16} icon="share" /> <FontAwesomeIcon size={16} icon="share" />
@ -137,7 +140,9 @@ export const TabsSelector = observer(
<Text style={styles.btnText}>Share</Text> <Text style={styles.btnText}>Share</Text>
</View> </View>
</TouchableWithoutFeedback> </TouchableWithoutFeedback>
<TouchableWithoutFeedback onPress={onPressCloneTab}> <TouchableWithoutFeedback
testID="cloneButton"
onPress={onPressCloneTab}>
<View style={[styles.btn]}> <View style={[styles.btn]}>
<View style={styles.btnIcon}> <View style={styles.btnIcon}>
<FontAwesomeIcon size={16} icon={['far', 'clone']} /> <FontAwesomeIcon size={16} icon={['far', 'clone']} />
@ -145,7 +150,9 @@ export const TabsSelector = observer(
<Text style={styles.btnText}>Clone tab</Text> <Text style={styles.btnText}>Clone tab</Text>
</View> </View>
</TouchableWithoutFeedback> </TouchableWithoutFeedback>
<TouchableWithoutFeedback onPress={onPressNewTab}> <TouchableWithoutFeedback
testID="newTabButton"
onPress={onPressNewTab}>
<View style={[styles.btn]}> <View style={[styles.btn]}>
<View style={styles.btnIcon}> <View style={styles.btnIcon}>
<FontAwesomeIcon size={16} icon="plus" /> <FontAwesomeIcon size={16} icon="plus" />
@ -164,6 +171,7 @@ export const TabsSelector = observer(
return ( return (
<Swipeable <Swipeable
key={tab.id} key={tab.id}
testID="tabsSwipable"
renderLeftActions={renderSwipeActions} renderLeftActions={renderSwipeActions}
renderRightActions={renderSwipeActions} renderRightActions={renderSwipeActions}
leftThreshold={100} leftThreshold={100}
@ -185,6 +193,7 @@ export const TabsSelector = observer(
isActive && styles.active, isActive && styles.active,
]}> ]}>
<TouchableWithoutFeedback <TouchableWithoutFeedback
testID="changeTabButton"
onPress={() => onPressChangeTab(tabIndex)}> onPress={() => onPressChangeTab(tabIndex)}>
<View style={styles.tabInner}> <View style={styles.tabInner}>
<View style={styles.tabIcon}> <View style={styles.tabIcon}>
@ -203,6 +212,7 @@ export const TabsSelector = observer(
</View> </View>
</TouchableWithoutFeedback> </TouchableWithoutFeedback>
<TouchableWithoutFeedback <TouchableWithoutFeedback
testID="closeTabButton"
onPress={() => onCloseTab(tabIndex)}> onPress={() => onCloseTab(tabIndex)}>
<View style={styles.tabClose}> <View style={styles.tabClose}>
<FontAwesomeIcon <FontAwesomeIcon

View File

@ -327,7 +327,7 @@ export const MobileShell: React.FC = observer(() => {
start={{x: 0, y: 0.8}} start={{x: 0, y: 0.8}}
end={{x: 0, y: 1}} end={{x: 0, y: 1}}
style={styles.outerContainer}> style={styles.outerContainer}>
<SafeAreaView style={styles.innerContainer}> <SafeAreaView testID="noSessionView" style={styles.innerContainer}>
<ErrorBoundary> <ErrorBoundary>
<Login /> <Login />
</ErrorBoundary> </ErrorBoundary>
@ -338,7 +338,7 @@ export const MobileShell: React.FC = observer(() => {
} }
if (store.onboard.isOnboarding) { if (store.onboard.isOnboarding) {
return ( return (
<View style={styles.outerContainer}> <View testID="onboardOuterView" style={styles.outerContainer}>
<View style={styles.innerContainer}> <View style={styles.innerContainer}>
<ErrorBoundary> <ErrorBoundary>
<Onboard /> <Onboard />
@ -355,7 +355,7 @@ export const MobileShell: React.FC = observer(() => {
backgroundColor: theme.colorScheme === 'dark' ? colors.gray7 : colors.gray1, backgroundColor: theme.colorScheme === 'dark' ? colors.gray7 : colors.gray1,
} }
return ( return (
<View style={[styles.outerContainer, pal.view]}> <View testID="mobileShellView" style={[styles.outerContainer, pal.view]}>
<StatusBar <StatusBar
barStyle={ barStyle={
theme.colorScheme === 'dark' ? 'light-content' : 'dark-content' theme.colorScheme === 'dark' ? 'light-content' : 'dark-content'

View File

@ -3027,11 +3027,6 @@
resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
"@yarnpkg/lockfile@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31"
integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==
"@zxing/text-encoding@^0.9.0": "@zxing/text-encoding@^0.9.0":
version "0.9.0" version "0.9.0"
resolved "https://registry.yarnpkg.com/@zxing/text-encoding/-/text-encoding-0.9.0.tgz#fb50ffabc6c7c66a0c96b4c03e3d9be74864b70b" resolved "https://registry.yarnpkg.com/@zxing/text-encoding/-/text-encoding-0.9.0.tgz#fb50ffabc6c7c66a0c96b4c03e3d9be74864b70b"
@ -4389,7 +4384,7 @@ cross-fetch@^3.1.5:
dependencies: dependencies:
node-fetch "2.6.7" node-fetch "2.6.7"
cross-spawn@^6.0.0, cross-spawn@^6.0.5: cross-spawn@^6.0.0:
version "6.0.5" version "6.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
@ -5930,13 +5925,6 @@ find-up@^5.0.0:
locate-path "^6.0.0" locate-path "^6.0.0"
path-exists "^4.0.0" path-exists "^4.0.0"
find-yarn-workspace-root@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd"
integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==
dependencies:
micromatch "^4.0.2"
flat-cache@^3.0.4: flat-cache@^3.0.4:
version "3.0.4" version "3.0.4"
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11"
@ -6999,7 +6987,7 @@ is-wsl@^1.1.0:
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d"
integrity sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw== integrity sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==
is-wsl@^2.1.1, is-wsl@^2.2.0: is-wsl@^2.2.0:
version "2.2.0" version "2.2.0"
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271"
integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==
@ -8177,13 +8165,6 @@ kind-of@^6.0.0, kind-of@^6.0.2:
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
klaw-sync@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/klaw-sync/-/klaw-sync-6.0.0.tgz#1fd2cfd56ebb6250181114f0a581167099c2b28c"
integrity sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==
dependencies:
graceful-fs "^4.1.11"
klaw@^1.0.0: klaw@^1.0.0:
version "1.3.1" version "1.3.1"
resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439"
@ -9217,14 +9198,6 @@ open@^6.2.0:
dependencies: dependencies:
is-wsl "^1.1.0" is-wsl "^1.1.0"
open@^7.4.2:
version "7.4.2"
resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321"
integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==
dependencies:
is-docker "^2.0.0"
is-wsl "^2.1.1"
open@^8.0.9, open@^8.4.0: open@^8.0.9, open@^8.4.0:
version "8.4.0" version "8.4.0"
resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8"
@ -9290,7 +9263,7 @@ ora@^5.4.1:
strip-ansi "^6.0.0" strip-ansi "^6.0.0"
wcwidth "^1.0.1" wcwidth "^1.0.1"
os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: os-tmpdir@^1.0.0:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==
@ -9409,26 +9382,6 @@ pascalcase@^0.1.1:
resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14"
integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==
patch-package@^6.5.0:
version "6.5.1"
resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.5.1.tgz#3e5d00c16997e6160291fee06a521c42ac99b621"
integrity sha512-I/4Zsalfhc6bphmJTlrLoOcAF87jcxko4q0qsv4bGcurbr8IskEOtdnt9iCmsQVGL1B+iUhSQqweyTLJfCF9rA==
dependencies:
"@yarnpkg/lockfile" "^1.1.0"
chalk "^4.1.2"
cross-spawn "^6.0.5"
find-yarn-workspace-root "^2.0.0"
fs-extra "^9.0.0"
is-ci "^2.0.0"
klaw-sync "^6.0.0"
minimist "^1.2.6"
open "^7.4.2"
rimraf "^2.6.3"
semver "^5.6.0"
slash "^2.0.0"
tmp "^0.0.33"
yaml "^1.10.2"
path-exists@^3.0.0: path-exists@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
@ -10973,7 +10926,7 @@ reusify@^1.0.4:
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
rimraf@^2.5.4, rimraf@^2.6.3: rimraf@^2.5.4:
version "2.7.1" version "2.7.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
@ -11348,11 +11301,6 @@ sisteransi@^1.0.5:
resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed"
integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==
slash@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44"
integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==
slash@^3.0.0: slash@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
@ -11991,13 +11939,6 @@ tlds@^1.234.0:
resolved "https://registry.yarnpkg.com/tlds/-/tlds-1.236.0.tgz#a118eebe33261c577e3a3025144faeabb7dd813c" resolved "https://registry.yarnpkg.com/tlds/-/tlds-1.236.0.tgz#a118eebe33261c577e3a3025144faeabb7dd813c"
integrity sha512-oP2PZ3KeGlgpHgsEfrtva3/K9kzsJUNliQSbCfrJ7JMCWFoCdtG+9YMq/g2AnADQ1v5tVlbtvKJZ4KLpy/P6MA== integrity sha512-oP2PZ3KeGlgpHgsEfrtva3/K9kzsJUNliQSbCfrJ7JMCWFoCdtG+9YMq/g2AnADQ1v5tVlbtvKJZ4KLpy/P6MA==
tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==
dependencies:
os-tmpdir "~1.0.2"
tmpl@1.0.5: tmpl@1.0.5:
version "1.0.5" version "1.0.5"
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc"