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

Commit

Permalink
Add my reviews (#196)
Browse files Browse the repository at this point in the history
* Add my reviews

* fix fragment title

* fix test

* fix tests
  • Loading branch information
MariemBaccari authored May 20, 2023
1 parent e85bb21 commit cc2515d
Show file tree
Hide file tree
Showing 8 changed files with 248 additions and 8 deletions.
13 changes: 13 additions & 0 deletions .idea/androidTestResultsUserPreferences.xml

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

Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ public void setUp() throws ExecutionException, InterruptedException, TimeoutExce
// Pass the username to the fragment
Bundle bundle = new Bundle();
bundle.putString("username", user1.getUsername());
bundle.putSerializable("feedType", FeedFragment.FeedType.FEED);
feedFragment.setArguments(bundle);
fragmentManager.beginTransaction().replace(R.id.main_container, feedFragment)
.commitAllowingStateLoss();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
package com.github.sdp.mediato;

import static androidx.test.espresso.Espresso.onView;
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.assertion.BaristaRecyclerViewAssertions.assertRecyclerViewItemCount;
import static com.adevinta.android.barista.interaction.BaristaListInteractions.clickListItemChild;
import static com.adevinta.android.barista.internal.matcher.HelperMatchers.atPosition;

import static org.hamcrest.Matchers.allOf;

import android.os.Bundle;

import androidx.fragment.app.FragmentManager;
import androidx.test.core.app.ActivityScenario;
import androidx.test.espresso.ViewInteraction;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import com.github.sdp.mediato.DatabaseTests.DataBaseTestUtil;
import com.github.sdp.mediato.data.CollectionsDatabase;
import com.github.sdp.mediato.data.UserDatabase;
import com.github.sdp.mediato.model.Location;
import com.github.sdp.mediato.model.Review;
import com.github.sdp.mediato.model.User;
import com.github.sdp.mediato.model.media.Collection;
import com.github.sdp.mediato.model.media.Media;
import com.github.sdp.mediato.model.media.MediaType;
import com.github.sdp.mediato.ui.FeedFragment;

import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

@RunWith(AndroidJUnit4.class)
public class MyReviewsFragmentTest {
private final static int STANDARD_USER_TIMEOUT = 10;
private User user1;
private User user2;
private User user3;
private Collection collection1;
private Collection collection2;
private Collection collection3;

ViewInteraction feedText = onView(withId(R.id.text_feed));

@Before
public void setUp() throws ExecutionException, InterruptedException, TimeoutException {
try {
DataBaseTestUtil.useEmulator();
} catch (Exception ignored) {
}

//Setup test data
createUsers();
createReviews();
addReviews();
Thread.sleep(1000);
UserDatabase.followUser(user1.getUsername(), user2.getUsername());
Thread.sleep(1000);

// Launch the MainActivity
ActivityScenario<MainActivity> scenario = ActivityScenario.launch(MainActivity.class);
// Set up the MainActivity to display the FeedFragment
scenario.onActivity(activity -> {
FragmentManager fragmentManager = activity.getSupportFragmentManager();
FeedFragment feedFragment = new FeedFragment();

// Pass the username to the fragment
Bundle bundle = new Bundle();
bundle.putString("username", user1.getUsername());
bundle.putSerializable("feedType", FeedFragment.FeedType.MY_REVIEWS);
feedFragment.setArguments(bundle);
fragmentManager.beginTransaction().replace(R.id.main_container, feedFragment)
.commitAllowingStateLoss();
});
}

@AfterClass
public static void cleanDatabase() {
DataBaseTestUtil.cleanDatabase();
}

// Test whether the feed text is displayed and contains the correct text
@Test
public void testFeedFragmentTextView() {
feedText.check(matches(isDisplayed()));
feedText.check(matches(withText("My Reviews")));
}

// Test that all the reviews from the followed users are displayed
// In this test, only user 2 is followed and they have 2 reviews
@Test
public void testItemCount() throws InterruptedException {
Thread.sleep(5000);
assertRecyclerViewItemCount(R.id.feed_posts, 2);
}

/**
* --------------Util functions--------------------
*/

//Helper function that creates users and adds them to the database
private void createUsers() throws ExecutionException, InterruptedException, TimeoutException {
//Create new sample users
user1 = new User.UserBuilder("uniqueId1")
.setUsername("user_myreviews_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_myreviews_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_myreviews_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);

}

//Helper function that creates reviews and adds them to the collections
private void createReviews() {
Media media1 = new Media(MediaType.MOVIE, "Harry Potter 1", "In the closet", "validUrl", 123);
Media media2 = new Media(MediaType.MOVIE, "Harry Potter 2", "In the WC", "validUrl", 1234);
Media media3 = new Media(MediaType.MOVIE, "Harry Potter 3", "In the prison", "validUrl", 12345);

Review review1 = new Review(user1.getUsername(), media1, 4, "Best movie in the world");
Review review2 = new Review(user1.getUsername(), media2, 5, "Pretty bad");
Review review3 = new Review(user1.getUsername(), media3, 6, "Really bad");

Map<String, Review> collection1Reviews = new HashMap<>();
collection1Reviews.put(review1.getMedia().getTitle(), review1);

Map<String, Review> collection2Reviews = new HashMap<>();
collection2Reviews.put(review2.getMedia().getTitle(), review2);

Map<String, Review> collection3Reviews = new HashMap<>();
collection3Reviews.put(review3.getMedia().getTitle(), review3);

collection1 = new Collection("The best", collection1Reviews);
collection2 = new Collection("The bad", collection2Reviews);
collection3 = new Collection("The worst", collection3Reviews);
}

//Helper function that adds the reviews to the database
private void addReviews() throws ExecutionException, InterruptedException, TimeoutException {
CollectionsDatabase.addCollection(user1.getUsername(), collection1);
CollectionsDatabase.addCollection(user1.getUsername(), collection2);
CollectionsDatabase.addCollection(user3.getUsername(), collection3);
Thread.sleep(1000);
}
}
19 changes: 15 additions & 4 deletions app/src/main/java/com/github/sdp/mediato/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,13 @@
import com.github.sdp.mediato.cache.AppCache;
import com.github.sdp.mediato.databinding.ActivityMainBinding;
import com.github.sdp.mediato.ui.ExploreFragment;
import com.github.sdp.mediato.model.Review;
import com.github.sdp.mediato.ui.FeedFragment;
import com.github.sdp.mediato.ui.MyProfileFragment;
import com.github.sdp.mediato.ui.ReadOnlyProfileFragment;
import com.github.sdp.mediato.ui.SearchFragment;
import com.github.sdp.mediato.ui.viewmodel.MyProfileViewModel;
import com.github.sdp.mediato.ui.viewmodel.ReadOnlyProfileViewModel;
import com.google.firebase.auth.FirebaseAuth;
import com.google.gson.Gson;

/**
* The main activity of the app that displays a bottom navigation bar and manages the navigation
Expand All @@ -37,6 +35,7 @@ public class MainActivity extends AppCompatActivity implements FragmentSwitcher
SearchFragment searchFragment;
ExploreFragment exploreFragment;
FeedFragment feedFragment;
FeedFragment myReviewsFragment;
private MyProfileViewModel myProfileViewModel;
private ReadOnlyProfileViewModel readOnlyProfileViewModel;
AppCache globalCache;
Expand Down Expand Up @@ -78,8 +77,9 @@ private boolean navigateFragments(int itemId) {
replaceFragment(myProfileFragment);
} else if (itemId == R.id.explore) {
replaceFragment(exploreFragment);
} else if (itemId == R.id.my_reviews) {
replaceFragment(myReviewsFragment);
}

return true;
}

Expand All @@ -102,18 +102,29 @@ private void setDefaultFragment(String username) {
searchFragment = new SearchFragment();
exploreFragment = new ExploreFragment();
feedFragment = new FeedFragment();
myReviewsFragment = new FeedFragment();

Bundle args = new Bundle();

Bundle argsFeed = new Bundle();
Bundle argsMyReviews = new Bundle();

// Give the username as an argument to the profile page and switch to it
args.putString("username", username);
args.putString("general_search", "true");
args.putString("collection", "Recently watched");

argsFeed.putString("username", username);
argsMyReviews.putString("username", username);

argsFeed.putSerializable("feedType", FeedFragment.FeedType.FEED);
argsMyReviews.putSerializable("feedType", FeedFragment.FeedType.MY_REVIEWS);

searchFragment.setArguments(args);
myProfileFragment.setArguments(args);
exploreFragment.setArguments(args);
feedFragment.setArguments(args);
feedFragment.setArguments(argsFeed);
myReviewsFragment.setArguments(argsMyReviews);

// Mark the profile item in the bottom bar as selected
binding.bottomNavigationView.setSelectedItemId(R.id.profile);
Expand Down
22 changes: 21 additions & 1 deletion app/src/main/java/com/github/sdp/mediato/ui/FeedFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class FeedFragment extends Fragment {
private FeedViewModel viewModel;
private FragmentFeedBinding binding;
private ReviewPostListAdapter adapter;
private FeedType feedType;


@Override
Expand All @@ -38,9 +39,12 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
USERNAME = getArguments().getString("username");
feedType = (FeedType) getArguments().getSerializable("feedType");

binding.textFeed.setText(feedType.toString());

viewModel = new ViewModelProvider(this).get(FeedViewModel.class);
viewModel.setUsername(USERNAME);
viewModel.setData(USERNAME, feedType);

adapter = new ReviewPostListAdapter();
adapter.setUsername(USERNAME);
Expand All @@ -51,4 +55,20 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
binding.feedPosts.setHasFixedSize(false);
viewModel.getPosts().observe(getViewLifecycleOwner(), adapter::submitList);
}

public enum FeedType {
MY_REVIEWS, FEED;

@Override
public String toString() {
switch (this) {
case MY_REVIEWS:
return "My Reviews";
case FEED:
return "Feed";
}
return "";
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.github.sdp.mediato.data.UserDatabase;
import com.github.sdp.mediato.model.User;
import com.github.sdp.mediato.model.post.ReviewPost;
import com.github.sdp.mediato.ui.FeedFragment;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -21,7 +22,6 @@ public class FeedViewModel extends AndroidViewModel {
Application application;
private final MutableLiveData<List<ReviewPost>> posts = new MutableLiveData<>(new ArrayList<>());
private String username;

public FeedViewModel (@NonNull Application application) {
super(application);
this.application = application;
Expand All @@ -31,9 +31,16 @@ public FeedViewModel (@NonNull Application application) {
* Sets the username of the user who is currently logged in and generates the list of posts
* @param username the username of the user who is currently logged in
*/
public void setUsername(String username) {
public void setData(String username, FeedFragment.FeedType feedType) {
this.username = username;
createFollowingsPosts();
switch (feedType) {
case MY_REVIEWS:
createMyPosts();
break;
case FEED:
createFollowingsPosts();
break;
}
}

/**
Expand All @@ -59,4 +66,13 @@ public void createFollowingsPosts() {
.thenAccept(posts::setValue);
}

/**
* Generates the list of posts from the current user
*/
public void createMyPosts() {
UserDatabase.getUser(username)
.thenApply(user -> user.fetchReviewPosts())
.thenAccept(posts::setValue);
}

}
5 changes: 5 additions & 0 deletions app/src/main/res/drawable/ic_my_reviews.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M14.43,10l-2.43,-8l-2.43,8l-7.57,0l6.18,4.41l-2.35,7.59l6.17,-4.69l6.18,4.69l-2.35,-7.59l6.17,-4.41z"/>
</vector>
4 changes: 4 additions & 0 deletions app/src/main/res/menu/bottom_menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
android:id="@+id/search"
android:title="Search"
android:icon="@drawable/ic_search"/>
<item
android:id="@+id/my_reviews"
android:title="My"
android:icon="@drawable/ic_my_reviews"/>
<item
android:id="@+id/profile"
android:title="Profile"
Expand Down

0 comments on commit cc2515d

Please sign in to comment.