Skip to content

Commit

Permalink
test: full coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
LukasFridmansky authored and Lipo11 committed Aug 21, 2023
1 parent aa8236e commit 887491a
Show file tree
Hide file tree
Showing 11 changed files with 554 additions and 117 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/node_modules
/coverage
/coverage
/dist
32 changes: 20 additions & 12 deletions jest.setup.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@

import { BackHandler, Dimensions } from 'react-native';

jest.mock('react-native-reanimated', () => {

const View = require('react-native').View;
Expand All @@ -24,10 +22,10 @@ jest.mock('react-native-reanimated', () => {
useSharedValue: jest.fn(),
useDerivedValue: (a) => ({ value: a() }),
useAnimatedScrollHandler: () => () => {},
useAnimatedGestureHandler: () => () => {},
useAnimatedGestureHandler: ({onStart, onActive, onFinish}) => ({onStart, onActive, onFinish}),
useAnimatedStyle: (cb) => cb(),
useAnimatedRef: () => ({ current: null }),
useAnimatedReaction: (value, cb) => cb(value(), ''),
useAnimatedReaction: jest.fn(),
useAnimatedProps: (cb) => cb(),
withTiming: (toValue, _, cb) => {
cb && cb(true);
Expand All @@ -48,7 +46,7 @@ jest.mock('react-native-reanimated', () => {
return 0;
},
withRepeat: (animation, _, __, cb) => {
cb();
cb?.();
return animation;
},
cancelAnimation: () => {},
Expand Down Expand Up @@ -92,20 +90,30 @@ jest.mock('react-native-reanimated', () => {
jest.mock('react-native-gesture-handler', () => {

const View = require('react-native').View;
const ScrollView = require('react-native').ScrollView;

return {
GestureDetector: ({gesture, children}) => (
PanGestureHandler: ({onGestureEvent, children}) => (
<View
onResponderStart={gesture.onStart}
onResponderEnd={gesture.onEnd}
onResponderMove={gesture.onUpdate}
onResponderStart={onGestureEvent.onStart}
onResponderEnd={onGestureEvent.onFinish}
onResponderMove={onGestureEvent.onActive}
testID="gestureContainer"
>
{children}
</View>
),
ScrollView
gestureHandlerRootHOC: (Component) => Component,
};

});
});

jest.mock('./src/core/helpers/image', () => ({
loadImage: (url) => url,
preloadStories: () => [],
}));

jest.mock('./src/core/helpers/storage', () => ({
clearProgressStorage: () => {},
getProgressStorage: jest.fn(),
setProgressStorage: jest.fn(),
}));
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 12 additions & 12 deletions src/components/Avatar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import React, { FC, memo } from 'react';
import { View, Image, Text } from 'react-native';
import {
View, Image, Text, TouchableOpacity,
} from 'react-native';
import Animated, {
useSharedValue, useAnimatedStyle, useDerivedValue, withTiming,
} from 'react-native-reanimated';
import { TouchableOpacity } from 'react-native-gesture-handler';
import { StoryAvatarProps } from '../../core/dto/componentsDTO';
import AvatarStyles from './Avatar.styles';
import Loader from '../Loader';
import {
AVATAR_OFFSET, AVATAR_SIZE, DEFAULT_COLORS, SEEN_LOADER_COLORS,
} from '../../core/constants';
import { AVATAR_OFFSET, AVATAR_SIZE } from '../../core/constants';

const AnimatedImage = Animated.createAnimatedComponent( Image );

Expand All @@ -21,15 +20,15 @@ const StoryAvatar: FC<StoryAvatarProps> = ( {
loadingStory,
seenStories,
onPress,
colors = DEFAULT_COLORS,
seenColors = SEEN_LOADER_COLORS,
size = AVATAR_SIZE,
showName = false,
colors,
seenColors,
size,
showName,
nameTextStyle,
} ) => {

const loaded = useSharedValue( false );
const isLoading = useDerivedValue( () => loadingStory.value === name || !loaded.value );
const isLoading = useDerivedValue( () => loadingStory.value === id || !loaded.value );
const loaderColor = useDerivedValue( () => (
seenStories.value[id] === stories[stories.length - 1]?.id
? seenColors
Expand All @@ -49,7 +48,7 @@ const StoryAvatar: FC<StoryAvatarProps> = ( {
return (
<View style={AvatarStyles.name}>
<View style={AvatarStyles.container}>
<TouchableOpacity activeOpacity={0.6} onPress={onPress}>
<TouchableOpacity activeOpacity={0.6} onPress={onPress} testID={`${id}StoryAvatar${stories.length}Story`}>
<Loader loading={isLoading} color={loaderColor} size={size + AVATAR_OFFSET * 2} />
<AnimatedImage
source={{ uri: imgUrl }}
Expand All @@ -58,11 +57,12 @@ const StoryAvatar: FC<StoryAvatarProps> = ( {
imageAnimatedStyles,
{ width: AVATAR_SIZE, height: AVATAR_SIZE, borderRadius: AVATAR_SIZE / 2 },
]}
testID="storyAvatarImage"
onLoad={onLoad}
/>
</TouchableOpacity>
</View>
{showName && <Text style={nameTextStyle}>{name}</Text>}
{Boolean( showName ) && <Text style={nameTextStyle}>{name}</Text>}
</View>
);

Expand Down
6 changes: 4 additions & 2 deletions src/components/Header/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { FC, memo } from 'react';
import { View, Text, Image } from 'react-native';
import { TouchableOpacity } from 'react-native-gesture-handler';
import {
View, Text, Image, TouchableOpacity,
} from 'react-native';
import { PROGRESS_COLOR, WIDTH } from '../../core/constants';
import HeaderStyles from './Header.styles';
import { StoryHeaderProps } from '../../core/dto/componentsDTO';
Expand All @@ -24,6 +25,7 @@ const StoryHeader: FC<StoryHeaderProps> = ( {
<TouchableOpacity
onPress={onClose}
hitSlop={16}
testID="storyCloseButton"
onPressIn={() => {

buttonHandled.value = true;
Expand Down
72 changes: 33 additions & 39 deletions src/components/Image/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Image, View } from 'react-native';
import React, {
FC, memo, useState, useEffect,
FC, memo, useState, useEffect, useRef,
} from 'react';
import { runOnJS, useAnimatedReaction, useSharedValue } from 'react-native-reanimated';
import { StoryImageProps } from '../../core/dto/componentsDTO';
Expand All @@ -18,6 +18,8 @@ const StoryImage: FC<StoryImageProps> = ( {
const loading = useSharedValue( true );
const color = useSharedValue( LOADER_COLORS );

const storyImgUrl = useRef( '' );

const onImageChange = async () => {

if ( !active.value ) {
Expand All @@ -26,51 +28,44 @@ const StoryImage: FC<StoryImageProps> = ( {

}

const story = stories.find( ( item ) => item.id === activeStory.value );
const story = stories.find( ( item ) => item.id === activeStory.value )!;

loading.value = true;

if ( story ) {

setUri( undefined );

if ( preloadImages ) {
if ( preloadImages ) {

const image = await loadImage( story.imgUrl );
setUri( image );
const image = await loadImage( story?.imgUrl );

const nextStory = stories[stories.indexOf( story ) ?? 0 + 1];
setUri( image );

if ( nextStory ) {
storyImgUrl.current = story?.imgUrl!;
const nextStory = stories[stories.indexOf( story! ) + 1];

loadImage( nextStory.imgUrl );
if ( nextStory ) {

}
loadImage( nextStory.imgUrl );

} else {
}

setUri( story.imgUrl );
} else if ( story?.imgUrl !== uri ) {

}
setUri( story?.imgUrl );

}

};

const setDefaultImage = async () => {

if ( !active.value ) {

if ( preloadImages ) {
if ( preloadImages ) {

const image = await loadImage( defaultImage );
setUri( image );
const image = await loadImage( defaultImage );
setUri( image );
storyImgUrl.current = defaultImage;

} else {
} else {

setUri( defaultImage );

}
setUri( defaultImage );

}

Expand Down Expand Up @@ -99,20 +94,19 @@ const StoryImage: FC<StoryImageProps> = ( {
<View style={ImageStyles.container}>
<Loader loading={loading} color={color} size={50} />
</View>
{uri && (
<Image
source={{ uri }}
style={{ width: WIDTH, aspectRatio: 0.5626 }}
resizeMode="contain"
onLayout={( e ) => onImageLayout( Math.min( HEIGHT, e.nativeEvent.layout.height ) )}
onLoad={() => {

loading.value = false;
onLoad();

}}
/>
)}
<Image
source={{ uri }}
style={{ width: WIDTH, aspectRatio: 0.5626 }}
resizeMode="contain"
testID="storyImageComponent"
onLayout={( e ) => onImageLayout( Math.min( HEIGHT, e.nativeEvent.layout.height ) )}
onLoad={() => {

loading.value = false;
onLoad();

}}
/>
</>
);

Expand Down
40 changes: 26 additions & 14 deletions src/components/InstagramStories/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, {
forwardRef, useImperativeHandle, useState, useEffect, useRef, memo,
} from 'react';
import { useSharedValue } from 'react-native-reanimated';
import { ScrollView } from 'react-native-gesture-handler';
import { ScrollView } from 'react-native';
import StoryAvatar from '../Avatar';
import { clearProgressStorage, getProgressStorage, setProgressStorage } from '../../core/helpers/storage';
import { InstagramStoriesProps, InstagramStoriesPublicMethods } from '../../core/dto/instagramStoriesDTO';
Expand Down Expand Up @@ -97,10 +97,10 @@ const InstagramStories = forwardRef<InstagramStoriesPublicMethods, InstagramStor
const userData = data.find( ( story ) => story.id === user );
const oldIndex = userData?.stories.findIndex(
( story ) => story.id === seenStories.value[user],
) ?? 0;
const newIndex = userData?.stories.findIndex( ( story ) => story.id === value ) ?? 0;
);
const newIndex = userData?.stories.findIndex( ( story ) => story.id === value );

if ( oldIndex > newIndex ) {
if ( oldIndex! > newIndex! ) {

return;

Expand Down Expand Up @@ -132,22 +132,28 @@ const InstagramStories = forwardRef<InstagramStoriesPublicMethods, InstagramStor
},
spliceUserStories: ( newStories, user, index ) => {

const userIndex = data.findIndex( ( story ) => story.id === user );
const userData = data.find( ( story ) => story.id === user );

if ( !userIndex || !data[userIndex] ) {
if ( !userData ) {

return;

}

const newData = {
...data[userIndex],
stories: index === undefined
? [ ...data[userIndex].stories, ...newStories ]
: data[userIndex].stories.splice( index, 0, ...newStories ),
};
const newData = index === undefined
? [ ...userData.stories, ...newStories ]
: [ ...userData.stories ];

setData( data.map( ( value, i ) => ( i === userIndex ? newData : value ) ) );
if ( index !== undefined ) {

newData.splice( index, 0, ...newStories );

}

setData( data.map( ( value ) => ( value.id === user ? {
...value,
stories: newData,
} : value ) ) );

},
setStories: ( newStories ) => {
Expand All @@ -167,9 +173,15 @@ const InstagramStories = forwardRef<InstagramStoriesPublicMethods, InstagramStor

}, [ data ] );

useEffect( () => {

setData( stories );

}, [ stories ] );

return (
<>
<ScrollView horizontal {...listContainerProps} contentContainerStyle={listContainerStyle}>
<ScrollView horizontal {...listContainerProps} contentContainerStyle={listContainerStyle} testID="storiesList">
{data.map( ( story ) => (
<StoryAvatar
{...story}
Expand Down
16 changes: 15 additions & 1 deletion src/components/Loader/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,28 @@ const Loader: FC<StoryLoaderProps> = ( {

};

const onColorChange = ( newColors: string[] ) => {

'worklet';

if ( JSON.stringify( colors ) === JSON.stringify( newColors ) ) {

return;

}

runOnJS( setColors )( newColors );

};

useAnimatedReaction(
() => loading.value,
( res ) => ( res ? startAnimation() : stopAnimation() ),
[ loading.value ],
);
useAnimatedReaction(
() => color.value,
( res ) => runOnJS( setColors )( res ),
( res ) => onColorChange( res ),
[ color.value ],
);

Expand Down
Loading

0 comments on commit 887491a

Please sign in to comment.