From 30719ac6a01d5b468cad3d72da390c5186c560ce Mon Sep 17 00:00:00 2001
From: HenryShan <zshan2@illinois.edu>
Date: Tue, 30 Mar 2021 12:27:55 +0800
Subject: [PATCH] repairing uploading

---
 src/Components/Followers.js                   |  56 +++
 src/Components/Following.js                   |  55 +++
 src/Components/LoadFollowersScreenModule.js   |  48 +++
 src/Components/LoadFollowingScreenModule.js   |  47 +++
 src/Components/LoadProfileScreenModule.js     |  46 +++
 src/Components/LoadRepoScreenModule.js        |  42 +++
 src/Components/Users.js                       |  36 ++
 src/__tests__/Button-test.js                  |  59 ++++
 src/__tests__/ErrorInFollowers-test.js        |  57 ++++
 src/__tests__/ErrorInProfile-test.js          |  87 +++++
 src/__tests__/FollowerScreen-test.js          |  74 ++++
 src/__tests__/FollowingScreen-test.js         |  74 ++++
 src/__tests__/Loading-test.js                 |  17 +
 src/__tests__/LoadingFollowersScreen-test.js  |  40 +++
 src/__tests__/LoadingFollowingScreen-test.js  |  39 +++
 src/__tests__/Profile-test.js                 |  26 ++
 src/__tests__/Repo-test.js                    |  27 ++
 src/__tests__/Unfound-test.js                 |  21 ++
 src/__tests__/Users-test.js                   |  27 ++
 .../ErrorInFollowers-test.js.snap             | 155 +++++++++
 .../__snapshots__/Loading-test.js.snap        |  78 +++++
 .../LoadingFollowersScreen-test.js.snap       |  78 +++++
 .../LoadingFollowingScreen-test.js.snap       |  78 +++++
 .../__snapshots__/Profile-test.js.snap        | 321 ++++++++++++++++++
 src/__tests__/__snapshots__/Repo-test.js.snap | 120 +++++++
 .../__snapshots__/Unfound-test.js.snap        | 110 ++++++
 .../__snapshots__/Users-test.js.snap          | 120 +++++++
 src/package.json                              |   1 +
 28 files changed, 1939 insertions(+)
 create mode 100644 src/Components/Followers.js
 create mode 100644 src/Components/Following.js
 create mode 100644 src/Components/LoadFollowersScreenModule.js
 create mode 100644 src/Components/LoadFollowingScreenModule.js
 create mode 100644 src/Components/LoadProfileScreenModule.js
 create mode 100644 src/Components/LoadRepoScreenModule.js
 create mode 100644 src/Components/Users.js
 create mode 100644 src/__tests__/Button-test.js
 create mode 100644 src/__tests__/ErrorInFollowers-test.js
 create mode 100644 src/__tests__/ErrorInProfile-test.js
 create mode 100644 src/__tests__/FollowerScreen-test.js
 create mode 100644 src/__tests__/FollowingScreen-test.js
 create mode 100644 src/__tests__/Loading-test.js
 create mode 100644 src/__tests__/LoadingFollowersScreen-test.js
 create mode 100644 src/__tests__/LoadingFollowingScreen-test.js
 create mode 100644 src/__tests__/Profile-test.js
 create mode 100644 src/__tests__/Repo-test.js
 create mode 100644 src/__tests__/Unfound-test.js
 create mode 100644 src/__tests__/Users-test.js
 create mode 100644 src/__tests__/__snapshots__/ErrorInFollowers-test.js.snap
 create mode 100644 src/__tests__/__snapshots__/Loading-test.js.snap
 create mode 100644 src/__tests__/__snapshots__/LoadingFollowersScreen-test.js.snap
 create mode 100644 src/__tests__/__snapshots__/LoadingFollowingScreen-test.js.snap
 create mode 100644 src/__tests__/__snapshots__/Profile-test.js.snap
 create mode 100644 src/__tests__/__snapshots__/Repo-test.js.snap
 create mode 100644 src/__tests__/__snapshots__/Unfound-test.js.snap
 create mode 100644 src/__tests__/__snapshots__/Users-test.js.snap

diff --git a/src/Components/Followers.js b/src/Components/Followers.js
new file mode 100644
index 0000000..778230d
--- /dev/null
+++ b/src/Components/Followers.js
@@ -0,0 +1,56 @@
+import * as React from 'react';
+import { Pressable, View, Text, Image, StyleSheet } from 'react-native';
+import Users from './Users'
+
+const styles = StyleSheet.create({
+  viewStyleVertical : { alignItems: 'center', justifyContent: 'center', margin: '10%' },
+  viewStyleHorizon : { flex: 1, flexDirection: 'row', justifyContent: 'space-between'},
+  pressableStyle : {flex: 1, flexDirection: 'row', justifyContent: 'space-between', backgroundColor:'lavender', paddingHorizontal:20, 
+  paddingVertical:10, borderColor:'thistle', borderWidth:2, borderRadius:5, marginHorizontal: 10, marginTop: 10},
+  image: { flex: 1, resizeMode: "cover", justifyContent: "center"},
+  container : {flex: 1},
+  textBox : {flex: 1, marginTop: 20, backgroundColor:'white', borderColor:'black', borderWidth:2, borderRadius:5, 
+  marginHorizontal: 10, paddingVertical:10, paddingHorizontal: 50, alignItems: 'flex-start'}
+});
+
+function Followers (user, navigation) {
+    const nodes = user['followers']['nodes']
+    const login = user['login']
+    let cards = []
+    if (nodes.length === 0) {
+        cards.push(
+        <Pressable style={styles.textBox} key={'Nobody'}>
+            <Text style={{ fontSize: 30 }}> 
+                Oops! Nobody is in this list!
+            </Text> 
+        </Pressable>
+        )
+    } else {
+        for (let i = 0; i < nodes.length; i++) {
+        var name = 'Name: \n' + nodes[i]['name'] + '\n'
+        var userName = 'Github Username: \n' + nodes[i]['login'] + '\n'
+        var key = 'user#' + i
+        var avatarUrl = nodes[i]['avatarUrl']
+        cards.push(
+        <Pressable style={styles.textBox} key={key} onPress={()=>navigation.push('LoadingProfile', {login: nodes[i]['login']})}>
+            <View style={styles.viewStyleVertical}>
+                <Image style={{width:90, height:90}} source={{uri: avatarUrl}}/>
+            </View>
+            <View style={styles.viewStyleVertical}>
+                <Text> {name} </Text>
+                <Text> {userName} </Text>
+            </View>
+        </Pressable>
+        )
+        }
+    }
+    const dataFile = {}
+    dataFile['cards'] = cards
+    dataFile['navi'] = navigation
+    dataFile['login'] = login
+    return (
+        <Users data={dataFile}/>
+    );
+}
+
+export default Followers
\ No newline at end of file
diff --git a/src/Components/Following.js b/src/Components/Following.js
new file mode 100644
index 0000000..79a8a9d
--- /dev/null
+++ b/src/Components/Following.js
@@ -0,0 +1,55 @@
+import * as React from 'react';
+import { Pressable, View, Text, Image, StyleSheet } from 'react-native';
+import Users from './Users'
+
+const styles = StyleSheet.create({
+  viewStyleVertical : { alignItems: 'center', justifyContent: 'center', margin: '10%' },
+  viewStyleHorizon : { flex: 1, flexDirection: 'row', justifyContent: 'space-between'},
+  pressableStyle : {flex: 1, flexDirection: 'row', justifyContent: 'space-between', backgroundColor:'lavender', paddingHorizontal:20, 
+  paddingVertical:10, borderColor:'thistle', borderWidth:2, borderRadius:5, marginHorizontal: 10, marginTop: 10},
+  image: { flex: 1, resizeMode: "cover", justifyContent: "center"},
+  container : {flex: 1},
+  textBox : {flex: 1, marginTop: 20, backgroundColor:'white', borderColor:'black', borderWidth:2, borderRadius:5, 
+  marginHorizontal: 10, paddingVertical:10, paddingHorizontal: 50, alignItems: 'flex-start'}
+});
+
+function Following (user, navigation) {
+    const nodes = user['following']['nodes']
+    const login = user['login']
+    let cards = []
+    if (nodes.length === 0) {
+        cards.push(
+        <Pressable style={styles.textBox} key={'Nobody'}>
+            <Text style={{ fontSize: 30 }}> 
+                Oops! Nobody is in this list!
+            </Text> 
+        </Pressable>
+        )
+    } else {
+        for (let i = 0; i < nodes.length; i++) {
+        var name = 'Name: \n' + nodes[i]['name'] + '\n'
+        var userName = 'Github Username: \n' + nodes[i]['login'] + '\n'
+        var key = 'user#' + i
+        var avatarUrl = nodes[i]['avatarUrl']
+        cards.push(
+            <Pressable style={styles.textBox} key={key} onPress={()=>navigation.push('LoadingProfile', {login: nodes[i]['login']})}>
+                <View style={styles.viewStyleVertical}>
+                <Image style={{width:90, height:90}} source={{uri: avatarUrl}}/>
+                </View>
+                <View style={styles.viewStyleVertical}>
+                <Text> {name} </Text>
+                <Text> {userName} </Text>
+                </View>
+            </Pressable>
+            )
+        }
+    }
+    const dataFile = {}
+    dataFile['cards'] = cards
+    dataFile['navi'] = navigation
+    dataFile['login'] = login
+    return (
+        <Users data={dataFile}/>
+    );
+}
+export default Following
\ No newline at end of file
diff --git a/src/Components/LoadFollowersScreenModule.js b/src/Components/LoadFollowersScreenModule.js
new file mode 100644
index 0000000..785c471
--- /dev/null
+++ b/src/Components/LoadFollowersScreenModule.js
@@ -0,0 +1,48 @@
+import * as React from 'react';
+import Loading from './Loading'
+
+/** Module part of followers screen, used to fetch data and send to View part */
+function LoadFollowersScreenModule(login, endPoint, token, navigation) {
+    fetch(endPoint, {
+        method: 'POST',
+        headers: {
+          "Content-Type": "application/json",
+          "Authorization": token
+        },
+        body: JSON.stringify({
+          query: `
+            query {
+              user(login:"`+ login +`"){
+                login
+                followers(last:100) {
+                  nodes {
+                    name
+                    login
+                    avatarUrl
+                  }
+                }
+              }
+            }
+          `
+        })
+      })
+      .then(res => res.json())
+      .then((data)=> {
+        if (data['data']['user'] === null) {
+          /** User not found! **/
+          navigation.push('Unfound', {errorMsg: 'Error, cannot find the github user by the login username:' 
+          + login + ', maybe this is an organization! \n Also maybe your internet was unstable'})
+        } else {
+          navigation.push('Followers', data['data']['user'])
+        }
+      })
+      .catch(error => {
+        navigation.push('Unfound', {errorMsg: 'Error happened' + error})
+      })
+      
+      return (
+        <Loading/>
+      );
+}
+
+export default LoadFollowersScreenModule
\ No newline at end of file
diff --git a/src/Components/LoadFollowingScreenModule.js b/src/Components/LoadFollowingScreenModule.js
new file mode 100644
index 0000000..44e8631
--- /dev/null
+++ b/src/Components/LoadFollowingScreenModule.js
@@ -0,0 +1,47 @@
+import * as React from 'react';
+import Loading from './Loading'
+
+/** Module part of following screen, used to fetch data and send to View part */
+function LoadFollowingScreenModule(login, endPoint, token, navigation) {
+    fetch(endPoint, {
+    method: 'POST',
+    headers: {
+      "Content-Type": "application/json",
+      "Authorization": token
+    },
+    body: JSON.stringify({
+      query: `
+        query {
+          user(login:"` + login + `"){
+            login
+            following(last:100) {
+              nodes {
+                name
+                login
+                avatarUrl
+              }
+            }
+          }
+        }
+      `
+    })
+  })
+  .then(res => res.json())
+  .then((data)=> {
+    if (data['data']['user'] === null) {
+      /** User not found! **/
+      navigation.push('Unfound', {errorMsg: 'Error, cannot find the github user by the login username:' 
+      + login + ', maybe this is an organization! \n Also maybe your internet was unstable'})
+    } else {
+      navigation.push('Following', data['data']['user'])
+    }
+  })
+  .catch(error => {
+    navigation.push('Unfound', {errorMsg: 'Error happened' + error})
+  })
+  return (
+    <Loading/>
+  );
+}
+
+export default LoadFollowingScreenModule;
\ No newline at end of file
diff --git a/src/Components/LoadProfileScreenModule.js b/src/Components/LoadProfileScreenModule.js
new file mode 100644
index 0000000..60c63fa
--- /dev/null
+++ b/src/Components/LoadProfileScreenModule.js
@@ -0,0 +1,46 @@
+async function LoadProfileScreenModule(login, endPoint, token, navigation) {
+    await fetch(endPoint, {
+        method: 'POST',
+        headers: {
+          "Content-Type": "application/json",
+          "Authorization": token
+        },
+        body: JSON.stringify({
+          query: `
+            query {
+              user(login:"`+ login + `") {
+                name
+                login
+                avatarUrl
+                bio
+                createdAt
+                email
+                websiteUrl
+                repositories(last:100, privacy:PUBLIC){
+                  nodes{
+                    name
+                  }
+                }
+              }
+            }
+          `
+        })
+      })
+      .then(res => res.json())
+      .then((data)=> {
+        if (data['data']['user'] === undefined) {
+          /** User not found! **/
+          navigation.push('Unfound', {errorMsg: 'Error, cannot find the github user by the login username:' 
+          + login + ', maybe this is an organization!'})
+          throw new Error('User Unfound!')
+        } else {
+          navigation.push('Profile', data['data']['user'])
+        }
+      })
+      .catch(error => {
+        navigation.push('Unfound', {errorMsg: 'Error: ' + error})
+      })
+    
+}
+
+export default LoadProfileScreenModule;
\ No newline at end of file
diff --git a/src/Components/LoadRepoScreenModule.js b/src/Components/LoadRepoScreenModule.js
new file mode 100644
index 0000000..9181ea2
--- /dev/null
+++ b/src/Components/LoadRepoScreenModule.js
@@ -0,0 +1,42 @@
+function LoadRepoScreenModule(login, endPoint, token, navigation) {
+    fetch(endPoint, {
+        method: 'POST',
+        headers: {
+          "Content-Type": "application/json",
+          "Authorization": token
+        },
+        body: JSON.stringify({
+          query: `
+            query {
+              user(login:"`+login+`"){
+                login
+                repositories(last:100, privacy:PUBLIC){
+                  nodes{
+                    name
+                    owner{
+                      login
+                    }
+                    description
+                  }
+                }
+              }
+            }
+          `
+        })
+      })
+      .then(res => res.json())
+      .then((data)=> {
+        if (data['data']['user'] === null) {
+          /** User not found! **/
+          navigation.push('Unfound', {errorMsg: 'Error, cannot find the github user by the login username:' + login + ', maybe this is an organization!'})
+        } else {
+          navigation.push('Repo', data['data']['user'])
+        }
+      })
+      .catch(error => {
+        navigation.push('Unfound', {errorMsg: 'Error: ' + error})
+      })
+    
+}
+
+export default LoadRepoScreenModule;
\ No newline at end of file
diff --git a/src/Components/Users.js b/src/Components/Users.js
new file mode 100644
index 0000000..ef70491
--- /dev/null
+++ b/src/Components/Users.js
@@ -0,0 +1,36 @@
+import * as React from 'react';
+import { Pressable, View, Text, Image, StyleSheet, ImageBackground } from 'react-native';
+
+const styles = StyleSheet.create({
+  viewStyleVertical : { alignItems: 'center', justifyContent: 'center', margin: '10%' },
+  viewStyleHorizon : { flex: 1, flexDirection: 'row', justifyContent: 'space-between'},
+  pressableStyle : {flex: 1, flexDirection: 'row', justifyContent: 'space-between', backgroundColor:'lavender', paddingHorizontal:20, 
+  paddingVertical:10, borderColor:'thistle', borderWidth:2, borderRadius:5, marginHorizontal: 10, marginTop: 10},
+  image: { flex: 1, resizeMode: "cover", justifyContent: "center"},
+  container : {flex: 1},
+  textBox : {flex: 1, marginTop: 20, backgroundColor:'white', borderColor:'black', borderWidth:2, borderRadius:5, 
+  marginHorizontal: 10, paddingVertical:10, paddingHorizontal: 50, alignItems: 'flex-start'}
+});
+
+const Users = (props) => {
+    const file = props.data
+    const cards = file['cards']
+    const navigation = file['navi']
+    return (
+        <View style={styles.container}>
+            <ImageBackground source={{uri: "https://www.fonewalls.com/wp-content/uploads/2020/04/Ice-Phone-Wallpaper.jpg"}} style={styles.image}>
+            <View style={styles.viewStyleVertical}>
+                <Pressable  style={styles.pressableStyle} onPress={() => navigation.pop(2)}>
+                <Text> Go to Profile </Text>
+                </Pressable>
+                {cards}
+                <Pressable  style={styles.pressableStyle} onPress={() => navigation.pop(2)}>
+                <Text> Go to Profile </Text>
+                </Pressable>
+            </View>
+            </ImageBackground>
+        </View>
+    )
+}
+
+export default Users;
diff --git a/src/__tests__/Button-test.js b/src/__tests__/Button-test.js
new file mode 100644
index 0000000..911bf83
--- /dev/null
+++ b/src/__tests__/Button-test.js
@@ -0,0 +1,59 @@
+import * as React from 'react';
+import { View, Text, Pressable, StyleSheet } from 'react-native';
+import { render, fireEvent } from '@testing-library/react-native';
+import Profile from '../Components/Profile'
+
+const styles = StyleSheet.create({
+  viewStyleVertical : { alignItems: 'center', justifyContent: 'center', margin: '10%' },
+  viewStyleHorizon : { flex: 1, flexDirection: 'row', justifyContent: 'space-between'},
+  pressableStyle : {flex: 1, flexDirection: 'row', justifyContent: 'space-between', backgroundColor:'lavender', paddingHorizontal:20, 
+  paddingVertical:10, borderColor:'thistle', borderWidth:2, borderRadius:5, marginHorizontal: 10, marginTop: 10},
+  image: { flex: 1, resizeMode: "cover", justifyContent: "center"},
+  container : {flex: 1},
+  textBox : {flex: 1, marginTop: 20, backgroundColor:'white', borderColor:'black', borderWidth:2, borderRadius:5, 
+  marginHorizontal: 10, paddingVertical:10, paddingHorizontal: 50, alignItems: 'flex-start'}
+});
+
+test('Followers button should trigger navigating', () => {
+  const push = jest.fn()
+  const dataFile = {
+    iconUrl: "https://avatars.githubusercontent.com/u/42978932?u=b4a7beb2752bb6059cd13d12ca26d097767abf77&v=4",
+      nameContent: null,
+      userNameContent: null,
+      bioContent: null,
+      websiteLink: null,
+      emailContent: null,
+      createData: null,
+      repoCount: 0,
+      navi: {push},
+      login: "test1"
+  }
+  const { getByText } = render(
+    <Profile data={dataFile} />
+  );
+
+  fireEvent.press(getByText(' Followers '));
+  expect(push).toHaveBeenNthCalledWith(1, "LoadingFollowers" ,{"login": "test1"});
+})
+
+test('Following button should trigger navigating', () => {
+  const push = jest.fn()
+  const dataFile = {
+    iconUrl: "https://avatars.githubusercontent.com/u/42978932?u=b4a7beb2752bb6059cd13d12ca26d097767abf77&v=4",
+      nameContent: null,
+      userNameContent: null,
+      bioContent: null,
+      websiteLink: null,
+      emailContent: null,
+      createData: null,
+      repoCount: 0,
+      navi: {push},
+      login: "test2"
+  }
+  const { getByText } = render(
+    <Profile data={dataFile} />
+  );
+
+  fireEvent.press(getByText(' Followings '));
+  expect(push).toHaveBeenNthCalledWith(1, "LoadingFollowing", {"login": "test2"});
+})
\ No newline at end of file
diff --git a/src/__tests__/ErrorInFollowers-test.js b/src/__tests__/ErrorInFollowers-test.js
new file mode 100644
index 0000000..99798c5
--- /dev/null
+++ b/src/__tests__/ErrorInFollowers-test.js
@@ -0,0 +1,57 @@
+import 'react-native';
+import renderer from 'react-test-renderer';
+import LoadFollowersScreenModule from  '../Components/LoadFollowersScreenModule'
+
+beforeEach(() => {
+  fetch.resetMocks();
+});
+
+/** Testing Loading View of Followers with Empty avatarUrl link */
+test('In the case that a user has no avatarUrl, its avatar should be a default one set in main page', () => {
+    fetch.mockResponseOnce(JSON.stringify({
+      data: {
+        user: {
+          login: "HenryShan",
+          followers: {
+            nodes: [{
+              name: "RX-78-2",
+              login: "G plan",
+              avatarUrl: null
+            }]
+          }
+        }
+      }
+    }));
+    const login = "HenryShan"
+    const envData = require('C:/Coding/cs242-assignment3/env.json')
+    const endPoint = envData['endPoint']
+    const token = envData['token']
+    const navigation = { push: jest.fn() };
+    const tree = renderer.create(
+       LoadFollowersScreenModule(login, endPoint, token, navigation)
+    ).toJSON();
+    expect(tree).toMatchSnapshot();
+  }, 70000);
+
+  /** Testing the loading view of followers when the followers value is empty, a textbox should be shown and informing this */
+  test('In the case that a user has no avatarUrl, its avatar should be a default one set in main page', () => {
+    fetch.mockResponseOnce(JSON.stringify({
+      data: {
+        user: {
+          login: "HenryShan",
+          followers: {
+            nodes: [{}]
+          }
+        }
+      }
+    }));
+    const login = "HenryShan"
+    const envData = require('C:/Coding/cs242-assignment3/env.json')
+    const endPoint = envData['endPoint']
+    const token = envData['token']
+    const navigation = { push: jest.fn() };
+    const tree = renderer.create(
+       LoadFollowersScreenModule(login, endPoint, token, navigation)
+    ).toJSON();
+    expect(tree).toMatchSnapshot();
+  }, 70000);
\ No newline at end of file
diff --git a/src/__tests__/ErrorInProfile-test.js b/src/__tests__/ErrorInProfile-test.js
new file mode 100644
index 0000000..73e6c32
--- /dev/null
+++ b/src/__tests__/ErrorInProfile-test.js
@@ -0,0 +1,87 @@
+import LoadProfileScreenModule from '../Components/LoadProfileScreenModule'
+import 'react-native';
+
+beforeEach(() => {
+    fetch.resetMocks();
+  });
+
+
+/** Testing the case when the username/login is not a person but other thing like an org */
+test('expect throwing error', () => {
+    
+    fetch.mockResponseOnce(JSON.stringify({
+        "data": {
+          "user": null
+        },
+        "errors": [
+          {
+            "type": "NOT_FOUND",
+            "path": [
+              "user"
+            ],
+            "locations": [
+              {
+                "line": 32,
+                "column": 3
+              }
+            ],
+            "message": "Could not resolve to a User with the login of '???'."
+          }
+        ]
+    }))
+    const onResponse = jest.fn();
+    const onError = jest.fn();
+    const login = "???"
+    const envData = require('C:/Coding/cs242-assignment3/env.json')
+    const endPoint = envData['endPoint']
+    const token = envData['token']
+    const navigation = { push: jest.fn() };
+    return LoadProfileScreenModule(login, endPoint, token, navigation)
+        .then(onResponse)
+        .catch(onError)
+        .finally(() => {
+            // since in this situation, return value still contains data PKT thus still get in response state
+            expect(onResponse).toHaveBeenCalled();
+            expect(onError).not.toHaveBeenCalled();
+        });
+  }, 70000);
+
+  /** Testing the case when the Internet is down and loading Profile should return the error page and throw error*/
+test('expect throwing error', () => {
+    
+    fetch.mockResponseOnce(JSON.stringify({
+        "data": {
+            "user": null
+          },
+          "errors": [
+            {
+              "type": "INTERNET_DOWN",
+              "path": [
+                "user"
+              ],
+              "locations": [
+                {
+                  "line": 32,
+                  "column": 3
+                }
+              ],
+              "message": "Cannot connect to graphQL API server."
+            }
+          ]
+    }))
+    const onResponse = jest.fn();
+    const onError = jest.fn();
+    const login = 'HenryShan'
+    const envData = require('C:/Coding/cs242-assignment3/env.json')
+    const endPoint = envData['endPoint']
+    const token = envData['token']
+    const navigation = { push: jest.fn() };
+    return LoadProfileScreenModule(login, endPoint, token, navigation)
+        .then(onResponse)
+        .catch(onError)
+        .finally(() => {
+            // since in this situation, return value still contains data PKT thus still get in response
+            expect(onResponse).toHaveBeenCalled();
+            expect(onError).not.toHaveBeenCalled();
+        });
+  }, 70000);
diff --git a/src/__tests__/FollowerScreen-test.js b/src/__tests__/FollowerScreen-test.js
new file mode 100644
index 0000000..0d419e7
--- /dev/null
+++ b/src/__tests__/FollowerScreen-test.js
@@ -0,0 +1,74 @@
+import 'react-native';
+import Followers from '../Components/Followers'
+import renderer from 'react-test-renderer';
+
+beforeEach(() => {
+    fetch.resetMocks();
+  });
+
+test('renders correctly', () => {
+    fetch.mockResponseOnce(JSON.stringify({
+      data: {
+        user: {
+            login: "HenryShan",
+            followers: {
+                nodes: [{
+                    name: "RX-78-2",
+                    login: "G plan",
+                    avatarUrl: "https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/7b10552b-57d8-42a7-8dba-d4aaad8e7c82/"
+                    + "d7p3uno-38b831f7-4933-4f09-b366-b951231e1751.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ"
+                    +"1cm46YXBwOiIsImlzcyI6InVybjphcHA6Iiwib2JqIjpbW3sicGF0aCI6IlwvZlwvN2IxMDU1MmItNTdkOC00MmE3LThkYmEtZDRhYWFk"
+                    +"OGU3YzgyXC9kN3AzdW5vLTM4YjgzMWY3LTQ5MzMtNGYwOS1iMzY2LWI5NTEyMzFlMTc1MS5qcGcifV1dLCJhdWQiOlsidXJuOnNlcnZpY2"
+                    +"U6ZmlsZS5kb3dubG9hZCJdfQ.PsPJAzWqHC1z07YMdxE4zYtFuUMXCtEMMI6VRr7Hq-k"
+                }]
+            }
+        }
+      }
+    }));
+    const login = "HenryShan"
+    const envData = require('C:/Coding/cs242-assignment3/env.json')
+    const endPoint = envData['endPoint']
+    const token = envData['token']
+    const navigation = { push: jest.fn() };
+    fetch(endPoint, {
+        method: 'POST',
+        headers: {
+          "Content-Type": "application/json",
+          "Authorization": token
+        },
+        body: JSON.stringify({
+          query: `
+            query {
+              user(login:"`+ login +`"){
+                login
+                followers(last:100) {
+                  nodes {
+                    name
+                    login
+                    avatarUrl
+                  }
+                }
+              }
+            }
+          `
+        })
+      })
+      .then(res => res.json())
+      .then((data)=> {
+        if (data['data']['user'] === null) {
+          /** User not found! **/
+          navigation.push('Unfound', {errorMsg: 'Error, cannot find the github user by the login username:' + login + ', maybe this is an organization! \n Also maybe your internet was unstable'})
+        } else {
+        //   navigation.push('Followers', data['data']['user'])
+          const tree = renderer.create(
+             Followers(data['data']['user'], navigation)
+          ).toJSON();
+          expect(tree).toMatchSnapshot();
+        }
+      })
+      .catch(error => {
+        navigation.push('Unfound', {errorMsg: 'Error:' + error})
+      })
+    
+    
+  }, 70000);
\ No newline at end of file
diff --git a/src/__tests__/FollowingScreen-test.js b/src/__tests__/FollowingScreen-test.js
new file mode 100644
index 0000000..082581b
--- /dev/null
+++ b/src/__tests__/FollowingScreen-test.js
@@ -0,0 +1,74 @@
+import 'react-native';
+import renderer from 'react-test-renderer';
+import Following from '../Components/Following';
+
+beforeEach(() => {
+    fetch.resetMocks();
+  });
+
+test('renders correctly', () => {
+    fetch.mockResponseOnce(JSON.stringify({
+      data: {
+        user: {
+            login: "HenryShan",
+            following: {
+                nodes: [{
+                    name: "RX-78-2",
+                    login: "G plan",
+                    avatarUrl: "https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/7b10552b-57d8-42a7-8dba-d4aaad8e7c82/"
+                    + "d7p3uno-38b831f7-4933-4f09-b366-b951231e1751.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ"
+                    +"1cm46YXBwOiIsImlzcyI6InVybjphcHA6Iiwib2JqIjpbW3sicGF0aCI6IlwvZlwvN2IxMDU1MmItNTdkOC00MmE3LThkYmEtZDRhYWFk"
+                    +"OGU3YzgyXC9kN3AzdW5vLTM4YjgzMWY3LTQ5MzMtNGYwOS1iMzY2LWI5NTEyMzFlMTc1MS5qcGcifV1dLCJhdWQiOlsidXJuOnNlcnZpY2"
+                    +"U6ZmlsZS5kb3dubG9hZCJdfQ.PsPJAzWqHC1z07YMdxE4zYtFuUMXCtEMMI6VRr7Hq-k"
+                }]
+            }
+        }
+      }
+    }));
+    const login = "HenryShan"
+    const envData = require('C:/Coding/cs242-assignment3/env.json')
+    const endPoint = envData['endPoint']
+    const token = envData['token']
+    const navigation = { push: jest.fn() };
+    fetch(endPoint, {
+        method: 'POST',
+        headers: {
+          "Content-Type": "application/json",
+          "Authorization": token
+        },
+        body: JSON.stringify({
+          query: `
+            query {
+              user(login:"`+ login +`"){
+                login
+                followers(last:100) {
+                  nodes {
+                    name
+                    login
+                    avatarUrl
+                  }
+                }
+              }
+            }
+          `
+        })
+      })
+      .then(res => res.json())
+      .then((data)=> {
+        if (data['data']['user'] === null) {
+          /** User not found! **/
+          navigation.push('Unfound', {errorMsg: 'Error, cannot find the github user by the login username:' + login + ', maybe this is an organization! \n Also maybe your internet was unstable'})
+        } else {
+        //   navigation.push('Followers', data['data']['user'])
+          const tree = renderer.create(
+             Following(data['data']['user'], navigation)
+          ).toJSON();
+          expect(tree).toMatchSnapshot();
+        }
+      })
+      .catch(error => {
+        navigation.push('Unfound', {errorMsg: 'Error: ' + error})
+      })
+    
+    
+  }, 70000);
\ No newline at end of file
diff --git a/src/__tests__/Loading-test.js b/src/__tests__/Loading-test.js
new file mode 100644
index 0000000..2fee5fd
--- /dev/null
+++ b/src/__tests__/Loading-test.js
@@ -0,0 +1,17 @@
+import 'react-native';
+import React from 'react';
+import renderer from 'react-test-renderer';
+import Loading from '../Components/Loading';
+import { createStackNavigator } from '@react-navigation/stack';
+
+beforeEach(() => {
+    fetch.resetMocks();
+  });
+
+/** Testing all loading pages */
+test('renders correctly', () => {
+    const tree = renderer.create(
+        <Loading />
+    ).toJSON();
+    expect(tree).toMatchSnapshot();
+});
\ No newline at end of file
diff --git a/src/__tests__/LoadingFollowersScreen-test.js b/src/__tests__/LoadingFollowersScreen-test.js
new file mode 100644
index 0000000..2b18f62
--- /dev/null
+++ b/src/__tests__/LoadingFollowersScreen-test.js
@@ -0,0 +1,40 @@
+import * as React from 'react';
+import 'react-native';
+import renderer from 'react-test-renderer';
+import LoadFollowersScreenModule from  '../Components/LoadFollowersScreenModule'
+
+beforeEach(() => {
+  fetch.resetMocks();
+});
+
+  /** Testing Loading View of Followers */
+  test('renders correctly', () => {
+    fetch.mockResponseOnce(JSON.stringify({
+      data: {
+        user: {
+          login: "HenryShan",
+          followers: {
+            nodes: [{
+              name: "RX-78-2",
+              login: "G plan",
+              avatarUrl: "https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/7b10552b-57d8-42a7-8dba-d4aaad8e7c82/"
+                + "d7p3uno-38b831f7-4933-4f09-b366-b951231e1751.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ"
+                +"1cm46YXBwOiIsImlzcyI6InVybjphcHA6Iiwib2JqIjpbW3sicGF0aCI6IlwvZlwvN2IxMDU1MmItNTdkOC00MmE3LThkYmEtZDRhYWFk"
+                +"OGU3YzgyXC9kN3AzdW5vLTM4YjgzMWY3LTQ5MzMtNGYwOS1iMzY2LWI5NTEyMzFlMTc1MS5qcGcifV1dLCJhdWQiOlsidXJuOnNlcnZpY2"
+                +"U6ZmlsZS5kb3dubG9hZCJdfQ.PsPJAzWqHC1z07YMdxE4zYtFuUMXCtEMMI6VRr7Hq-k"
+            }]
+          }
+        }
+      }
+    }));
+    const login = "HenryShan"
+    const envData = require('C:/Coding/cs242-assignment3/env.json')
+    const endPoint = envData['endPoint']
+    const token = envData['token']
+    const push = jest.fn();
+    const tree = renderer.create(
+       LoadFollowersScreenModule(login, endPoint, token, {push})
+    ).toJSON();
+    expect(tree).toMatchSnapshot();
+  }, 70000);
+  
diff --git a/src/__tests__/LoadingFollowingScreen-test.js b/src/__tests__/LoadingFollowingScreen-test.js
new file mode 100644
index 0000000..6abcee1
--- /dev/null
+++ b/src/__tests__/LoadingFollowingScreen-test.js
@@ -0,0 +1,39 @@
+import 'react-native';
+import renderer from 'react-test-renderer';
+import LoadFollowingScreenModule from  '../Components/LoadFollowingScreenModule'
+
+beforeEach(() => {
+    fetch.resetMocks();
+  });
+
+  /** Testing Loading View for Following */
+  test('renders correctly', () => {
+    fetch.mockResponseOnce(JSON.stringify({
+        data: {
+            user: {
+                login: "HenryShan",
+                following: {
+                    nodes: [{
+                        name: "RX-78-2",
+                        login: "G plan",
+                        avatarUrl: "https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/7b10552b-57d8-42a7-8dba-d4aaad8e7c82/"
+                        + "d7p3uno-38b831f7-4933-4f09-b366-b951231e1751.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ"
+                        +"1cm46YXBwOiIsImlzcyI6InVybjphcHA6Iiwib2JqIjpbW3sicGF0aCI6IlwvZlwvN2IxMDU1MmItNTdkOC00MmE3LThkYmEtZDRhYWFk"
+                        +"OGU3YzgyXC9kN3AzdW5vLTM4YjgzMWY3LTQ5MzMtNGYwOS1iMzY2LWI5NTEyMzFlMTc1MS5qcGcifV1dLCJhdWQiOlsidXJuOnNlcnZpY2"
+                        +"U6ZmlsZS5kb3dubG9hZCJdfQ.PsPJAzWqHC1z07YMdxE4zYtFuUMXCtEMMI6VRr7Hq-k"
+                    }]
+                }
+            }
+        }
+    }));
+    const login = "HenryShan"
+    const envData = require('C:/Coding/cs242-assignment3/env.json')
+    const endPoint = envData['endPoint']
+    const token = envData['token']
+    const navigation = { push: jest.fn() };
+    const tree = renderer.create(
+        LoadFollowingScreenModule(login, endPoint, token, navigation)
+    ).toJSON();
+    expect(tree).toMatchSnapshot();
+  }, 70000);
+  
\ No newline at end of file
diff --git a/src/__tests__/Profile-test.js b/src/__tests__/Profile-test.js
new file mode 100644
index 0000000..031ed57
--- /dev/null
+++ b/src/__tests__/Profile-test.js
@@ -0,0 +1,26 @@
+import 'react-native';
+import React from 'react';
+import Profile from '../Components/Profile';
+import renderer from 'react-test-renderer';
+
+beforeEach(() => {
+    fetch.resetMocks();
+  });
+
+test('renders correctly', () => {
+    const dataFile = {
+      iconUrl: "https://avatars.githubusercontent.com/u/42978932?u=b4a7beb2752bb6059cd13d12ca26d097767abf77&v=4",
+      nameContent: null,
+      userNameContent: null,
+      bioContent: null,
+      websiteLink: null,
+      emailContent: null,
+      createData: null,
+      repoCount: 0,
+      navi: { navigate: jest.fn() }
+    }
+    const tree = renderer.create(
+      <Profile data={dataFile}/>
+    ).toJSON();
+    expect(tree).toMatchSnapshot();
+  }, 70000);
\ No newline at end of file
diff --git a/src/__tests__/Repo-test.js b/src/__tests__/Repo-test.js
new file mode 100644
index 0000000..2ac8c22
--- /dev/null
+++ b/src/__tests__/Repo-test.js
@@ -0,0 +1,27 @@
+import 'react-native';
+import React from 'react';
+import renderer from 'react-test-renderer';
+import Repo from '../Components/Repo';
+
+beforeEach(() => {
+    fetch.resetMocks();
+  });
+
+  /** Testing repo pages */
+  test('renders correctly', () => {
+    const dataFile = {
+      iconUrl: "https://avatars.githubusercontent.com/u/42978932?u=b4a7beb2752bb6059cd13d12ca26d097767abf77&v=4",
+      nameContent: null,
+      userNameContent: null,
+      bioContent: null,
+      websiteLink: null,
+      emailContent: null,
+      createData: null,
+      repoCount: 0,
+      navi: { navigate: jest.fn() }
+    }
+    const tree = renderer.create(
+      <Repo data={dataFile}/>
+    ).toJSON();
+    expect(tree).toMatchSnapshot();
+  }, 70000);
diff --git a/src/__tests__/Unfound-test.js b/src/__tests__/Unfound-test.js
new file mode 100644
index 0000000..70973c3
--- /dev/null
+++ b/src/__tests__/Unfound-test.js
@@ -0,0 +1,21 @@
+import 'react-native';
+import React from 'react';
+import renderer from 'react-test-renderer';
+import Unfound from '../Components/Unfound';
+
+beforeEach(() => {
+    fetch.resetMocks();
+  });
+
+
+
+/** Testing unfound/error pages */
+test('renders correctly', () => {
+  const dataFile = {
+    navi: jest.fn()
+  }
+  const tree = renderer.create(
+    <Unfound data={dataFile}/>
+  ).toJSON();
+    expect(tree).toMatchSnapshot();
+}, 50000);
\ No newline at end of file
diff --git a/src/__tests__/Users-test.js b/src/__tests__/Users-test.js
new file mode 100644
index 0000000..2699b83
--- /dev/null
+++ b/src/__tests__/Users-test.js
@@ -0,0 +1,27 @@
+import 'react-native';
+import React from 'react';
+import renderer from 'react-test-renderer';
+import Users from  '../Components/Users'
+
+beforeEach(() => {
+  fetch.resetMocks();
+});
+
+  /** Testing all Users pages (Followers and Following) */
+  test('renders correctly', () => {
+    const dataFile = {
+      iconUrl: "https://avatars.githubusercontent.com/u/42978932?u=b4a7beb2752bb6059cd13d12ca26d097767abf77&v=4",
+      nameContent: null,
+      userNameContent: null,
+      bioContent: null,
+      websiteLink: null,
+      emailContent: null,
+      createData: null,
+      repoCount: 0,
+      navi: { navigate: jest.fn() }
+    }
+    const tree = renderer.create(
+      <Users data={dataFile}/>
+    ).toJSON();
+    expect(tree).toMatchSnapshot();
+  }, 70000);
\ No newline at end of file
diff --git a/src/__tests__/__snapshots__/ErrorInFollowers-test.js.snap b/src/__tests__/__snapshots__/ErrorInFollowers-test.js.snap
new file mode 100644
index 0000000..d557758
--- /dev/null
+++ b/src/__tests__/__snapshots__/ErrorInFollowers-test.js.snap
@@ -0,0 +1,155 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`In the case that a user has no avatarUrl, its avatar should be a default one set in main page 1`] = `
+<View
+  style={
+    Object {
+      "flex": 1,
+    }
+  }
+>
+  <View
+    accessibilityIgnoresInvertColors={true}
+    style={
+      Object {
+        "flex": 1,
+        "justifyContent": "center",
+        "resizeMode": "cover",
+      }
+    }
+  >
+    <Image
+      source={
+        Object {
+          "uri": "https://www.fonewalls.com/wp-content/uploads/2020/04/Ice-Phone-Wallpaper.jpg",
+        }
+      }
+      style={
+        Array [
+          Object {
+            "bottom": 0,
+            "left": 0,
+            "position": "absolute",
+            "right": 0,
+            "top": 0,
+          },
+          Object {
+            "height": undefined,
+            "width": undefined,
+          },
+          undefined,
+        ]
+      }
+    />
+    <View
+      style={
+        Object {
+          "alignItems": "center",
+          "justifyContent": "center",
+          "margin": "10%",
+        }
+      }
+    >
+      <Text
+        style={
+          Object {
+            "fontSize": 30,
+          }
+        }
+      >
+        Loading......
+      </Text>
+      <Image
+        source={
+          Object {
+            "uri": "http://simpleicon.com/wp-content/uploads/refresh.png",
+          }
+        }
+        style={
+          Object {
+            "height": 200,
+            "width": 200,
+          }
+        }
+      />
+    </View>
+  </View>
+</View>
+`;
+
+exports[`In the case that a user has no avatarUrl, its avatar should be a default one set in main page 2`] = `
+<View
+  style={
+    Object {
+      "flex": 1,
+    }
+  }
+>
+  <View
+    accessibilityIgnoresInvertColors={true}
+    style={
+      Object {
+        "flex": 1,
+        "justifyContent": "center",
+        "resizeMode": "cover",
+      }
+    }
+  >
+    <Image
+      source={
+        Object {
+          "uri": "https://www.fonewalls.com/wp-content/uploads/2020/04/Ice-Phone-Wallpaper.jpg",
+        }
+      }
+      style={
+        Array [
+          Object {
+            "bottom": 0,
+            "left": 0,
+            "position": "absolute",
+            "right": 0,
+            "top": 0,
+          },
+          Object {
+            "height": undefined,
+            "width": undefined,
+          },
+          undefined,
+        ]
+      }
+    />
+    <View
+      style={
+        Object {
+          "alignItems": "center",
+          "justifyContent": "center",
+          "margin": "10%",
+        }
+      }
+    >
+      <Text
+        style={
+          Object {
+            "fontSize": 30,
+          }
+        }
+      >
+        Loading......
+      </Text>
+      <Image
+        source={
+          Object {
+            "uri": "http://simpleicon.com/wp-content/uploads/refresh.png",
+          }
+        }
+        style={
+          Object {
+            "height": 200,
+            "width": 200,
+          }
+        }
+      />
+    </View>
+  </View>
+</View>
+`;
diff --git a/src/__tests__/__snapshots__/Loading-test.js.snap b/src/__tests__/__snapshots__/Loading-test.js.snap
new file mode 100644
index 0000000..9834e0e
--- /dev/null
+++ b/src/__tests__/__snapshots__/Loading-test.js.snap
@@ -0,0 +1,78 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders correctly 1`] = `
+<View
+  style={
+    Object {
+      "flex": 1,
+    }
+  }
+>
+  <View
+    accessibilityIgnoresInvertColors={true}
+    style={
+      Object {
+        "flex": 1,
+        "justifyContent": "center",
+        "resizeMode": "cover",
+      }
+    }
+  >
+    <Image
+      source={
+        Object {
+          "uri": "https://www.fonewalls.com/wp-content/uploads/2020/04/Ice-Phone-Wallpaper.jpg",
+        }
+      }
+      style={
+        Array [
+          Object {
+            "bottom": 0,
+            "left": 0,
+            "position": "absolute",
+            "right": 0,
+            "top": 0,
+          },
+          Object {
+            "height": undefined,
+            "width": undefined,
+          },
+          undefined,
+        ]
+      }
+    />
+    <View
+      style={
+        Object {
+          "alignItems": "center",
+          "justifyContent": "center",
+          "margin": "10%",
+        }
+      }
+    >
+      <Text
+        style={
+          Object {
+            "fontSize": 30,
+          }
+        }
+      >
+        Loading......
+      </Text>
+      <Image
+        source={
+          Object {
+            "uri": "http://simpleicon.com/wp-content/uploads/refresh.png",
+          }
+        }
+        style={
+          Object {
+            "height": 200,
+            "width": 200,
+          }
+        }
+      />
+    </View>
+  </View>
+</View>
+`;
diff --git a/src/__tests__/__snapshots__/LoadingFollowersScreen-test.js.snap b/src/__tests__/__snapshots__/LoadingFollowersScreen-test.js.snap
new file mode 100644
index 0000000..9834e0e
--- /dev/null
+++ b/src/__tests__/__snapshots__/LoadingFollowersScreen-test.js.snap
@@ -0,0 +1,78 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders correctly 1`] = `
+<View
+  style={
+    Object {
+      "flex": 1,
+    }
+  }
+>
+  <View
+    accessibilityIgnoresInvertColors={true}
+    style={
+      Object {
+        "flex": 1,
+        "justifyContent": "center",
+        "resizeMode": "cover",
+      }
+    }
+  >
+    <Image
+      source={
+        Object {
+          "uri": "https://www.fonewalls.com/wp-content/uploads/2020/04/Ice-Phone-Wallpaper.jpg",
+        }
+      }
+      style={
+        Array [
+          Object {
+            "bottom": 0,
+            "left": 0,
+            "position": "absolute",
+            "right": 0,
+            "top": 0,
+          },
+          Object {
+            "height": undefined,
+            "width": undefined,
+          },
+          undefined,
+        ]
+      }
+    />
+    <View
+      style={
+        Object {
+          "alignItems": "center",
+          "justifyContent": "center",
+          "margin": "10%",
+        }
+      }
+    >
+      <Text
+        style={
+          Object {
+            "fontSize": 30,
+          }
+        }
+      >
+        Loading......
+      </Text>
+      <Image
+        source={
+          Object {
+            "uri": "http://simpleicon.com/wp-content/uploads/refresh.png",
+          }
+        }
+        style={
+          Object {
+            "height": 200,
+            "width": 200,
+          }
+        }
+      />
+    </View>
+  </View>
+</View>
+`;
diff --git a/src/__tests__/__snapshots__/LoadingFollowingScreen-test.js.snap b/src/__tests__/__snapshots__/LoadingFollowingScreen-test.js.snap
new file mode 100644
index 0000000..9834e0e
--- /dev/null
+++ b/src/__tests__/__snapshots__/LoadingFollowingScreen-test.js.snap
@@ -0,0 +1,78 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders correctly 1`] = `
+<View
+  style={
+    Object {
+      "flex": 1,
+    }
+  }
+>
+  <View
+    accessibilityIgnoresInvertColors={true}
+    style={
+      Object {
+        "flex": 1,
+        "justifyContent": "center",
+        "resizeMode": "cover",
+      }
+    }
+  >
+    <Image
+      source={
+        Object {
+          "uri": "https://www.fonewalls.com/wp-content/uploads/2020/04/Ice-Phone-Wallpaper.jpg",
+        }
+      }
+      style={
+        Array [
+          Object {
+            "bottom": 0,
+            "left": 0,
+            "position": "absolute",
+            "right": 0,
+            "top": 0,
+          },
+          Object {
+            "height": undefined,
+            "width": undefined,
+          },
+          undefined,
+        ]
+      }
+    />
+    <View
+      style={
+        Object {
+          "alignItems": "center",
+          "justifyContent": "center",
+          "margin": "10%",
+        }
+      }
+    >
+      <Text
+        style={
+          Object {
+            "fontSize": 30,
+          }
+        }
+      >
+        Loading......
+      </Text>
+      <Image
+        source={
+          Object {
+            "uri": "http://simpleicon.com/wp-content/uploads/refresh.png",
+          }
+        }
+        style={
+          Object {
+            "height": 200,
+            "width": 200,
+          }
+        }
+      />
+    </View>
+  </View>
+</View>
+`;
diff --git a/src/__tests__/__snapshots__/Profile-test.js.snap b/src/__tests__/__snapshots__/Profile-test.js.snap
new file mode 100644
index 0000000..04de496
--- /dev/null
+++ b/src/__tests__/__snapshots__/Profile-test.js.snap
@@ -0,0 +1,321 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders correctly 1`] = `
+<View
+  style={
+    Object {
+      "flex": 1,
+    }
+  }
+>
+  <View
+    accessibilityIgnoresInvertColors={true}
+    style={
+      Object {
+        "flex": 1,
+        "justifyContent": "center",
+        "resizeMode": "cover",
+      }
+    }
+  >
+    <Image
+      source={
+        Object {
+          "uri": "https://www.fonewalls.com/wp-content/uploads/2020/04/Ice-Phone-Wallpaper.jpg",
+        }
+      }
+      style={
+        Array [
+          Object {
+            "bottom": 0,
+            "left": 0,
+            "position": "absolute",
+            "right": 0,
+            "top": 0,
+          },
+          Object {
+            "height": undefined,
+            "width": undefined,
+          },
+          undefined,
+        ]
+      }
+    />
+    <View
+      style={
+        Object {
+          "alignItems": "center",
+          "justifyContent": "center",
+          "margin": "10%",
+        }
+      }
+    >
+      <View
+        style={
+          Object {
+            "alignItems": "center",
+            "justifyContent": "center",
+            "margin": "10%",
+          }
+        }
+      >
+        <Image
+          source={
+            Object {
+              "uri": "https://avatars.githubusercontent.com/u/42978932?u=b4a7beb2752bb6059cd13d12ca26d097767abf77&v=4",
+            }
+          }
+          style={
+            Object {
+              "height": 120,
+              "width": 120,
+            }
+          }
+        />
+      </View>
+      <View
+        style={
+          Object {
+            "flex": 1,
+            "flexDirection": "row",
+            "justifyContent": "space-between",
+          }
+        }
+      >
+        <View
+          accessible={true}
+          focusable={true}
+          onBlur={[Function]}
+          onClick={[Function]}
+          onFocus={[Function]}
+          onResponderGrant={[Function]}
+          onResponderMove={[Function]}
+          onResponderRelease={[Function]}
+          onResponderTerminate={[Function]}
+          onResponderTerminationRequest={[Function]}
+          onStartShouldSetResponder={[Function]}
+          style={
+            Object {
+              "backgroundColor": "lavender",
+              "borderColor": "thistle",
+              "borderRadius": 5,
+              "borderWidth": 2,
+              "flex": 1,
+              "flexDirection": "row",
+              "justifyContent": "space-between",
+              "marginHorizontal": 10,
+              "marginTop": 10,
+              "paddingHorizontal": 20,
+              "paddingVertical": 10,
+            }
+          }
+        >
+          <Text>
+             Followers 
+          </Text>
+        </View>
+        <View
+          accessible={true}
+          focusable={true}
+          onBlur={[Function]}
+          onClick={[Function]}
+          onFocus={[Function]}
+          onResponderGrant={[Function]}
+          onResponderMove={[Function]}
+          onResponderRelease={[Function]}
+          onResponderTerminate={[Function]}
+          onResponderTerminationRequest={[Function]}
+          onStartShouldSetResponder={[Function]}
+          style={
+            Object {
+              "backgroundColor": "lavender",
+              "borderColor": "thistle",
+              "borderRadius": 5,
+              "borderWidth": 2,
+              "flex": 1,
+              "flexDirection": "row",
+              "justifyContent": "space-between",
+              "marginHorizontal": 10,
+              "marginTop": 10,
+              "paddingHorizontal": 20,
+              "paddingVertical": 10,
+            }
+          }
+        >
+          <Text>
+             Followings 
+          </Text>
+        </View>
+      </View>
+      <View
+        style={
+          Object {
+            "alignItems": "center",
+            "justifyContent": "center",
+            "margin": "10%",
+          }
+        }
+      >
+        <Text
+          style={
+            Object {
+              "alignItems": "flex-start",
+              "backgroundColor": "white",
+              "borderColor": "black",
+              "borderRadius": 5,
+              "borderWidth": 2,
+              "flex": 1,
+              "marginHorizontal": 10,
+              "marginTop": 20,
+              "paddingHorizontal": 50,
+              "paddingVertical": 10,
+            }
+          }
+        >
+           
+           
+        </Text>
+        <Text
+          style={
+            Object {
+              "alignItems": "flex-start",
+              "backgroundColor": "white",
+              "borderColor": "black",
+              "borderRadius": 5,
+              "borderWidth": 2,
+              "flex": 1,
+              "marginHorizontal": 10,
+              "marginTop": 20,
+              "paddingHorizontal": 50,
+              "paddingVertical": 10,
+            }
+          }
+        >
+           
+           
+        </Text>
+        <Text
+          style={
+            Object {
+              "alignItems": "flex-start",
+              "backgroundColor": "white",
+              "borderColor": "black",
+              "borderRadius": 5,
+              "borderWidth": 2,
+              "flex": 1,
+              "marginHorizontal": 10,
+              "marginTop": 20,
+              "paddingHorizontal": 50,
+              "paddingVertical": 10,
+            }
+          }
+        >
+           
+           
+        </Text>
+        <Text
+          style={
+            Object {
+              "alignItems": "flex-start",
+              "backgroundColor": "white",
+              "borderColor": "black",
+              "borderRadius": 5,
+              "borderWidth": 2,
+              "flex": 1,
+              "marginHorizontal": 10,
+              "marginTop": 20,
+              "paddingHorizontal": 50,
+              "paddingVertical": 10,
+            }
+          }
+        >
+           
+           
+        </Text>
+        <Text
+          style={
+            Object {
+              "alignItems": "flex-start",
+              "backgroundColor": "white",
+              "borderColor": "black",
+              "borderRadius": 5,
+              "borderWidth": 2,
+              "flex": 1,
+              "marginHorizontal": 10,
+              "marginTop": 20,
+              "paddingHorizontal": 50,
+              "paddingVertical": 10,
+            }
+          }
+        >
+           
+           
+        </Text>
+        <Text
+          style={
+            Object {
+              "alignItems": "flex-start",
+              "backgroundColor": "white",
+              "borderColor": "black",
+              "borderRadius": 5,
+              "borderWidth": 2,
+              "flex": 1,
+              "marginHorizontal": 10,
+              "marginTop": 20,
+              "paddingHorizontal": 50,
+              "paddingVertical": 10,
+            }
+          }
+        >
+           
+           
+        </Text>
+      </View>
+      <View
+        style={
+          Object {
+            "alignItems": "center",
+            "justifyContent": "center",
+            "margin": "10%",
+          }
+        }
+      >
+        <View
+          accessible={true}
+          focusable={true}
+          onBlur={[Function]}
+          onClick={[Function]}
+          onFocus={[Function]}
+          onResponderGrant={[Function]}
+          onResponderMove={[Function]}
+          onResponderRelease={[Function]}
+          onResponderTerminate={[Function]}
+          onResponderTerminationRequest={[Function]}
+          onStartShouldSetResponder={[Function]}
+          style={
+            Object {
+              "backgroundColor": "lavender",
+              "borderColor": "thistle",
+              "borderRadius": 5,
+              "borderWidth": 2,
+              "flex": 1,
+              "flexDirection": "row",
+              "justifyContent": "space-between",
+              "marginHorizontal": 10,
+              "marginTop": 10,
+              "paddingHorizontal": 20,
+              "paddingVertical": 10,
+            }
+          }
+        >
+          <Text>
+             
+            0
+             
+          </Text>
+        </View>
+      </View>
+    </View>
+  </View>
+</View>
+`;
diff --git a/src/__tests__/__snapshots__/Repo-test.js.snap b/src/__tests__/__snapshots__/Repo-test.js.snap
new file mode 100644
index 0000000..7fc91eb
--- /dev/null
+++ b/src/__tests__/__snapshots__/Repo-test.js.snap
@@ -0,0 +1,120 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders correctly 1`] = `
+<View
+  style={
+    Object {
+      "flex": 1,
+    }
+  }
+>
+  <View
+    accessibilityIgnoresInvertColors={true}
+    style={
+      Object {
+        "flex": 1,
+        "justifyContent": "center",
+        "resizeMode": "cover",
+      }
+    }
+  >
+    <Image
+      source={
+        Object {
+          "uri": "https://www.fonewalls.com/wp-content/uploads/2020/04/Ice-Phone-Wallpaper.jpg",
+        }
+      }
+      style={
+        Array [
+          Object {
+            "bottom": 0,
+            "left": 0,
+            "position": "absolute",
+            "right": 0,
+            "top": 0,
+          },
+          Object {
+            "height": undefined,
+            "width": undefined,
+          },
+          undefined,
+        ]
+      }
+    />
+    <View
+      style={
+        Object {
+          "alignItems": "center",
+          "justifyContent": "center",
+          "margin": "10%",
+        }
+      }
+    >
+      <View
+        accessible={true}
+        focusable={true}
+        onBlur={[Function]}
+        onClick={[Function]}
+        onFocus={[Function]}
+        onResponderGrant={[Function]}
+        onResponderMove={[Function]}
+        onResponderRelease={[Function]}
+        onResponderTerminate={[Function]}
+        onResponderTerminationRequest={[Function]}
+        onStartShouldSetResponder={[Function]}
+        style={
+          Object {
+            "backgroundColor": "lavender",
+            "borderColor": "thistle",
+            "borderRadius": 5,
+            "borderWidth": 2,
+            "flex": 1,
+            "flexDirection": "row",
+            "justifyContent": "space-between",
+            "marginHorizontal": 10,
+            "marginTop": 10,
+            "paddingHorizontal": 20,
+            "paddingVertical": 10,
+          }
+        }
+      >
+        <Text>
+           Go to Profile 
+        </Text>
+      </View>
+      <View
+        accessible={true}
+        focusable={true}
+        onBlur={[Function]}
+        onClick={[Function]}
+        onFocus={[Function]}
+        onResponderGrant={[Function]}
+        onResponderMove={[Function]}
+        onResponderRelease={[Function]}
+        onResponderTerminate={[Function]}
+        onResponderTerminationRequest={[Function]}
+        onStartShouldSetResponder={[Function]}
+        style={
+          Object {
+            "backgroundColor": "lavender",
+            "borderColor": "thistle",
+            "borderRadius": 5,
+            "borderWidth": 2,
+            "flex": 1,
+            "flexDirection": "row",
+            "justifyContent": "space-between",
+            "marginHorizontal": 10,
+            "marginTop": 10,
+            "paddingHorizontal": 20,
+            "paddingVertical": 10,
+          }
+        }
+      >
+        <Text>
+           Go to Profile 
+        </Text>
+      </View>
+    </View>
+  </View>
+</View>
+`;
diff --git a/src/__tests__/__snapshots__/Unfound-test.js.snap b/src/__tests__/__snapshots__/Unfound-test.js.snap
new file mode 100644
index 0000000..7822434
--- /dev/null
+++ b/src/__tests__/__snapshots__/Unfound-test.js.snap
@@ -0,0 +1,110 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders correctly 1`] = `
+<View
+  style={
+    Object {
+      "flex": 1,
+    }
+  }
+>
+  <View
+    accessibilityIgnoresInvertColors={true}
+    style={
+      Object {
+        "flex": 1,
+        "justifyContent": "center",
+        "resizeMode": "cover",
+      }
+    }
+  >
+    <Image
+      source={
+        Object {
+          "uri": "https://www.fonewalls.com/wp-content/uploads/2020/04/Ice-Phone-Wallpaper.jpg",
+        }
+      }
+      style={
+        Array [
+          Object {
+            "bottom": 0,
+            "left": 0,
+            "position": "absolute",
+            "right": 0,
+            "top": 0,
+          },
+          Object {
+            "height": undefined,
+            "width": undefined,
+          },
+          undefined,
+        ]
+      }
+    />
+    <View
+      style={
+        Object {
+          "alignItems": "center",
+          "justifyContent": "center",
+          "margin": "10%",
+        }
+      }
+    >
+      <Text
+        style={
+          Object {
+            "fontSize": 30,
+          }
+        }
+      >
+         Error! Check log to see details 
+      </Text>
+      <Image
+        source={
+          Object {
+            "uri": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/Warning.svg/156px-Warning.svg.png",
+          }
+        }
+        style={
+          Object {
+            "height": 200,
+            "width": 200,
+          }
+        }
+      />
+      <View
+        accessible={true}
+        focusable={true}
+        onBlur={[Function]}
+        onClick={[Function]}
+        onFocus={[Function]}
+        onResponderGrant={[Function]}
+        onResponderMove={[Function]}
+        onResponderRelease={[Function]}
+        onResponderTerminate={[Function]}
+        onResponderTerminationRequest={[Function]}
+        onStartShouldSetResponder={[Function]}
+        style={
+          Object {
+            "backgroundColor": "lavender",
+            "borderColor": "thistle",
+            "borderRadius": 5,
+            "borderWidth": 2,
+            "flex": 1,
+            "flexDirection": "row",
+            "justifyContent": "space-between",
+            "marginHorizontal": 10,
+            "marginTop": 10,
+            "paddingHorizontal": 20,
+            "paddingVertical": 10,
+          }
+        }
+      >
+        <Text>
+           Go back to Home Page 
+        </Text>
+      </View>
+    </View>
+  </View>
+</View>
+`;
diff --git a/src/__tests__/__snapshots__/Users-test.js.snap b/src/__tests__/__snapshots__/Users-test.js.snap
new file mode 100644
index 0000000..7fc91eb
--- /dev/null
+++ b/src/__tests__/__snapshots__/Users-test.js.snap
@@ -0,0 +1,120 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders correctly 1`] = `
+<View
+  style={
+    Object {
+      "flex": 1,
+    }
+  }
+>
+  <View
+    accessibilityIgnoresInvertColors={true}
+    style={
+      Object {
+        "flex": 1,
+        "justifyContent": "center",
+        "resizeMode": "cover",
+      }
+    }
+  >
+    <Image
+      source={
+        Object {
+          "uri": "https://www.fonewalls.com/wp-content/uploads/2020/04/Ice-Phone-Wallpaper.jpg",
+        }
+      }
+      style={
+        Array [
+          Object {
+            "bottom": 0,
+            "left": 0,
+            "position": "absolute",
+            "right": 0,
+            "top": 0,
+          },
+          Object {
+            "height": undefined,
+            "width": undefined,
+          },
+          undefined,
+        ]
+      }
+    />
+    <View
+      style={
+        Object {
+          "alignItems": "center",
+          "justifyContent": "center",
+          "margin": "10%",
+        }
+      }
+    >
+      <View
+        accessible={true}
+        focusable={true}
+        onBlur={[Function]}
+        onClick={[Function]}
+        onFocus={[Function]}
+        onResponderGrant={[Function]}
+        onResponderMove={[Function]}
+        onResponderRelease={[Function]}
+        onResponderTerminate={[Function]}
+        onResponderTerminationRequest={[Function]}
+        onStartShouldSetResponder={[Function]}
+        style={
+          Object {
+            "backgroundColor": "lavender",
+            "borderColor": "thistle",
+            "borderRadius": 5,
+            "borderWidth": 2,
+            "flex": 1,
+            "flexDirection": "row",
+            "justifyContent": "space-between",
+            "marginHorizontal": 10,
+            "marginTop": 10,
+            "paddingHorizontal": 20,
+            "paddingVertical": 10,
+          }
+        }
+      >
+        <Text>
+           Go to Profile 
+        </Text>
+      </View>
+      <View
+        accessible={true}
+        focusable={true}
+        onBlur={[Function]}
+        onClick={[Function]}
+        onFocus={[Function]}
+        onResponderGrant={[Function]}
+        onResponderMove={[Function]}
+        onResponderRelease={[Function]}
+        onResponderTerminate={[Function]}
+        onResponderTerminationRequest={[Function]}
+        onStartShouldSetResponder={[Function]}
+        style={
+          Object {
+            "backgroundColor": "lavender",
+            "borderColor": "thistle",
+            "borderRadius": 5,
+            "borderWidth": 2,
+            "flex": 1,
+            "flexDirection": "row",
+            "justifyContent": "space-between",
+            "marginHorizontal": 10,
+            "marginTop": 10,
+            "paddingHorizontal": 20,
+            "paddingVertical": 10,
+          }
+        }
+      >
+        <Text>
+           Go to Profile 
+        </Text>
+      </View>
+    </View>
+  </View>
+</View>
+`;
diff --git a/src/package.json b/src/package.json
index 9273acf..8486e4a 100644
--- a/src/package.json
+++ b/src/package.json
@@ -39,6 +39,7 @@
   },
   "devDependencies": {
     "@babel/core": "~7.9.0",
+    "@testing-library/react-native": "^7.2.0",
     "jest": "^26.6.3"
   },
   "private": true
-- 
GitLab