Skip to content
This repository has been archived by the owner on Feb 1, 2025. It is now read-only.

Commit

Permalink
Merge pull request #124 from MediaTo-SDP/profile_header_displays_foll…
Browse files Browse the repository at this point in the history
…owers

Profile header displays followers and following count
  • Loading branch information
simone-kalbermatter authored Apr 16, 2023
2 parents b0734d5 + 738f170 commit ff30f85
Show file tree
Hide file tree
Showing 25 changed files with 539 additions and 150 deletions.
42 changes: 42 additions & 0 deletions .idea/androidTestResultsUserPreferences.xml

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

6 changes: 6 additions & 0 deletions .idea/other.xml

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

13 changes: 0 additions & 13 deletions .idea/saveactions_settings.xml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package com.github.sdp.mediato;

import static com.adevinta.android.barista.assertion.BaristaRecyclerViewAssertions.assertRecyclerViewItemCount;
import static com.adevinta.android.barista.assertion.BaristaVisibilityAssertions.assertDisplayed;
import static com.adevinta.android.barista.assertion.BaristaVisibilityAssertions.assertNotDisplayed;
import static com.adevinta.android.barista.interaction.BaristaListInteractions.clickListItemChild;
import static com.adevinta.android.barista.interaction.BaristaSleepInteractions.sleep;

import android.os.Bundle;
import androidx.fragment.app.FragmentManager;
import androidx.test.core.app.ActivityScenario;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.github.sdp.mediato.data.UserDatabase;
import com.github.sdp.mediato.model.Location;
import com.github.sdp.mediato.model.User;
import com.github.sdp.mediato.ui.MyFollowersFragment;
import com.github.sdp.mediato.ui.MyFollowingFragment;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(AndroidJUnit4.class)
public class MyFollowersFragmentTest {
private final static int STANDARD_USER_TIMEOUT = 10;
User user1;
User user2;
User user3;

@Before
public void setUp() throws ExecutionException, InterruptedException, TimeoutException
{
try {
UserDatabase.database.useEmulator("10.0.2.2", 9000);
} catch (Exception ignored) {
}
//Create new sample users
user1 = new User.UserBuilder("uniqueId1")
.setUsername("user_test_1")
.setEmail("email_test_1")
.setRegisterDate("09/03/2023")
.setLocation(new Location(3.14, 3.14))
.build();
user2 = new User.UserBuilder("uniqueId2")
.setUsername("user_test_2")
.setEmail("email_test_2")
.setRegisterDate("19/03/2023")
.setLocation(new Location(3.14, 3.14))
.build();
user3 = new User.UserBuilder("uniqueId3")
.setUsername("user_test_3")
.setEmail("email_test_3")
.setRegisterDate("19/03/2023")
.setLocation(new Location(3.14, 3.14))
.build();

UserDatabase.addUser(user1).get(STANDARD_USER_TIMEOUT, TimeUnit.SECONDS);
UserDatabase.addUser(user2).get(STANDARD_USER_TIMEOUT, TimeUnit.SECONDS);
UserDatabase.addUser(user3).get(STANDARD_USER_TIMEOUT, TimeUnit.SECONDS);

// Launch the TestingActivity
ActivityScenario<TestingActivity> scenario = ActivityScenario.launch(TestingActivity.class);

// Set up the TestingActivity to display the SearchFragment
scenario.onActivity(activity -> {
FragmentManager fragmentManager = activity.getSupportFragmentManager();
MyFollowersFragment myFollowersFragment = new MyFollowersFragment();

// Pass the username to the fragment like at profile creation
Bundle bundle = new Bundle();
bundle.putString("username", "user_test_1");
myFollowersFragment.setArguments(bundle);
fragmentManager.beginTransaction().replace(R.id.fragment_container, myFollowersFragment)
.commitAllowingStateLoss();
});
}

@Test
public void testRecyclerViewWithNoneFollowing() {
assertRecyclerViewItemCount(R.id.myFollowing_recyclerView, 0);
}

@Test
public void testRecyclerViewWithTwoFollowings() {
UserDatabase.followUser(user2.getUsername(), user1.getUsername());
UserDatabase.followUser(user3.getUsername(), user1.getUsername());

sleep(500);

assertRecyclerViewItemCount(R.id.myFollowing_recyclerView, 2);
assertDisplayed(user2.getUsername());
assertDisplayed(user3.getUsername());

assertNotDisplayed(R.id.searchUserAdapter_unfollowButton);
assertNotDisplayed(R.id.searchUserAdapter_followButton);
}

}


Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public void testRecyclerViewWithTwoFollowings() {
UserDatabase.followUser(user1.getUsername(), user2.getUsername());
UserDatabase.followUser(user1.getUsername(), user3.getUsername());

sleep(500);
sleep(700);

assertRecyclerViewItemCount(R.id.myFollowing_recyclerView, 2);
assertDisplayed(user2.getUsername());
Expand All @@ -103,15 +103,15 @@ public void testOneUnfollowWithTwoFollowings() {
UserDatabase.followUser(user1.getUsername(), user2.getUsername());
UserDatabase.followUser(user1.getUsername(), user3.getUsername());

sleep(500);
sleep(700);

assertRecyclerViewItemCount(R.id.myFollowing_recyclerView, 2);
assertDisplayed(user2.getUsername());
assertDisplayed(user3.getUsername());

clickListItemChild(R.id.myFollowing_recyclerView, 0, R.id.searchUserAdapter_unfollowButton);

sleep(500);
sleep(700);

assertRecyclerViewItemCount(R.id.myFollowing_recyclerView, 1);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.slowSwipeLeft;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static com.adevinta.android.barista.interaction.BaristaSleepInteractions.sleep;
import static org.junit.Assert.fail;

import android.os.Bundle;
Expand Down Expand Up @@ -39,6 +41,7 @@ public class ProfileFragmentTest {
ViewInteraction userNameText = onView(withId(R.id.username_text));
ViewInteraction editButton = onView(withId(R.id.edit_button));
ViewInteraction followingButton = onView(withId(R.id.profile_following_button));
ViewInteraction followersButton = onView(withId(R.id.profile_followers_button));
ViewInteraction defaultCollection = onView(withId(R.id.collection_list));
ViewInteraction addMediaButton = onView(withId(R.id.add_media_button));
ViewInteraction addCollectionButton = onView(withId(R.id.add_collection_button));
Expand Down Expand Up @@ -70,18 +73,24 @@ public void setUp() {
});
}

// Test whether the "Friends" button is displayed and contains the correct text
// Test whether the "Following" button is displayed and contains the correct text
@Test
public void testFollowingButton() {
followingButton.check(matches(isDisplayed()));
followingButton.check(matches(withText(R.string.following)));
followingButton.check(matches(withText("0 Following")));
}

// Test whether the "Edit" button is displayed and contains the correct text
// Test whether the "Followers" button is displayed and contains the correct text
@Test
public void testFollowersButton() {
followersButton.check(matches(isDisplayed()));
followersButton.check(matches(withText("0 Followers")));
}

// Test whether the "Edit" button is displayed
@Test
public void testEditButton() {
editButton.check(matches(isDisplayed()));
editButton.check(matches(withText("Edit")));
}

// Test whether the profile picture is displayed
Expand Down
46 changes: 33 additions & 13 deletions app/src/main/java/com/github/sdp/mediato/ProfileFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
Expand All @@ -21,11 +22,11 @@
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.github.sdp.mediato.data.CollectionsDatabase;
import com.github.sdp.mediato.data.UserDatabase;
import com.github.sdp.mediato.model.Review;
import com.github.sdp.mediato.model.media.Collection;
import com.github.sdp.mediato.ui.MyFollowersFragment;
import com.github.sdp.mediato.ui.MyFollowingFragment;
import com.github.sdp.mediato.ui.viewmodel.ProfileViewModel;
import com.github.sdp.mediato.utility.PhotoPicker;
Expand All @@ -43,8 +44,9 @@ public class ProfileFragment extends Fragment {

private ProfileViewModel viewModel;
private PhotoPicker photoPicker;
private Button editButton;
private ImageButton editButton;
private Button followingButton;
private Button followersButton;
private Button addCollectionButton;
private TextView usernameView;
private ImageView profileImage;
Expand Down Expand Up @@ -78,6 +80,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
// Get all UI components
editButton = view.findViewById(R.id.edit_button);
followingButton = view.findViewById(R.id.profile_following_button);
followersButton = view.findViewById(R.id.profile_followers_button);
addCollectionButton = view.findViewById(R.id.add_collection_button);
usernameView = view.findViewById(R.id.username_text);
profileImage = view.findViewById(R.id.profile_image);
Expand All @@ -86,17 +89,27 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
// Initialize components
photoPicker = setupPhotoPicker();
setupFollowingButton(followingButton);
setupFollowersButton(followersButton);
collectionlistAdapter = setupCollections(collectionListRecyclerView);
setupAddCollectionsButton(addCollectionButton);

// Observe the view model's live data to update UI components
observeUsername();
observeProfilePic();
observeCollections(collectionlistAdapter);
observeFollowingAndFollowersCount();
updateFollowingAndFollowersCount();

return view;
}

private void updateFollowingAndFollowersCount() {
UserDatabase.getUser(USERNAME).thenAccept(user -> {
viewModel.setFollowing(user.getFollowingCount());
viewModel.setFollowers(user.getFollowersCount());
});
}

private CollectionListAdapter setupCollections(RecyclerView recyclerView) {
// Check if a collection is already in the viewModel, if not create the default one
List<Collection> collections = viewModel.getCollections();
Expand Down Expand Up @@ -145,6 +158,15 @@ private void observeProfilePic() {
bitmap -> profileImage.setImageBitmap(bitmap));
}

private void observeFollowingAndFollowersCount() {
viewModel.getFollowersLiveData().observe(getViewLifecycleOwner(), followersCount -> {
followersButton.setText(followersCount + " " + getResources().getString(R.string.followers));
});
viewModel.getFollowingLiveData().observe(getViewLifecycleOwner(), followingCount -> {
followingButton.setText(followingCount + " " + getResources().getString(R.string.following));
});
}

private PhotoPicker setupPhotoPicker() {
PhotoPicker photoPicker = new PhotoPicker(this, profileImage);

Expand All @@ -160,14 +182,13 @@ private PhotoPicker setupPhotoPicker() {
);
return photoPicker;
}

private void setupFollowingButton(Button followingButton) {
followingButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openMyFollowingFragment();
}
});
followingButton.setOnClickListener(v -> switchFragment(new MyFollowingFragment()));
}

private void setupFollowersButton(Button followersButton) {
followersButton.setOnClickListener(v -> switchFragment(new MyFollowersFragment()));
}

private void showEnterCollectionNameDialog() {
Expand Down Expand Up @@ -235,15 +256,14 @@ private void downloadProfilePicWithRetry(String username) {
});
}

private void openMyFollowingFragment() {
MyFollowingFragment myFollowingFragment = new MyFollowingFragment();
private void switchFragment(Fragment fragment) {
Bundle args = new Bundle();
args.putString("username", USERNAME);
myFollowingFragment.setArguments(args);
fragment.setArguments(args);

FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.main_container, myFollowingFragment);
fragmentTransaction.replace(R.id.main_container, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
Expand Down
Loading

0 comments on commit ff30f85

Please sign in to comment.