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

Commit

Permalink
Add new book api and fix movie api (#182)
Browse files Browse the repository at this point in the history
* Add some code

* Add some code

* Add some code

* Add ViewModel to search

* add some code

* Trending books working

* Add a lot of stuff

* Movie/Book Search and trending working and some tests

* Fix some code climate problem

* Fix some code climate problem

* Fix some code climate problem

* Fix some code climate problem

* Fix some code climate problem

* Fix a test

* Fix a test

* Fix tests

* Fix title

* Fix title

* Fix test

* Add room to the build.gradle
  • Loading branch information
sgueissa authored May 17, 2023
1 parent 9664cdb commit e85bb21
Show file tree
Hide file tree
Showing 39 changed files with 968 additions and 1,308 deletions.
4 changes: 3 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ android {

defaultConfig {
applicationId "com.github.sdp.mediato"
minSdk 24
minSdk 26
targetSdk 33
versionCode 1
versionName "1.0"
Expand Down Expand Up @@ -67,6 +67,7 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.8.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.room:room-common:2.4.2'

testImplementation 'junit:junit:4.13.2'
testImplementation 'com.squareup.okhttp3:mockwebserver:5.0.0-alpha.11'
Expand All @@ -81,6 +82,7 @@ dependencies {
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'

androidTestImplementation('com.adevinta.android:barista:4.2.0')
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.3' // Check for the latest version


implementation 'com.github.dhaval2404:imagepicker:2.1'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public void setUp() throws ExecutionException, InterruptedException, TimeoutExce

// Create a collection with one review for user1 and upload it to the database
Collection collection = new Collection(COLLECTION_NAME);
Movie movie = new Movie(MOVIE_TITLE, "summary", "url", "iconId", "id");
Movie movie = new Movie(MOVIE_TITLE, "summary", "url", 1);
Review review = new Review(MY_USERNAME, movie);
collection.addReview(review);
CollectionsDatabase.addCollection(user1.getUsername(), collection);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static com.adevinta.android.barista.interaction.BaristaClickInteractions.clickOn;
import static com.adevinta.android.barista.interaction.BaristaEditTextInteractions.typeTo;
import static com.adevinta.android.barista.interaction.BaristaKeyboardInteractions.closeKeyboard;
import static com.github.sdp.mediato.ui.NewItemFragment.MAX_REVIEW_LENGTH;

import android.app.Activity;
Expand Down Expand Up @@ -56,7 +59,6 @@ public class NewItemFragmentTest {
ViewInteraction seekBar = onView(withId(R.id.item_rating_slider));
ViewInteraction editText = onView(withId(R.id.item_review_edittext));
ViewInteraction seekBarIndicator = onView(withId(R.id.item_rating_slider_progress));
ViewInteraction errorText = onView(withId(R.id.new_item_review_error_msg));
NewItemFragment newItemFragment = new NewItemFragment();

ActivityScenario<MainActivity> scenario;
Expand Down Expand Up @@ -160,36 +162,6 @@ public void checkNoErrorsWhenAddingACorrectLengthComment() {
.check(matches(hasDescendant(withId(R.id.profile_header))));
}

// Test that error message is displayed after writing a comment exceeding MAX_REVIEW_LENGTH
@Test
public void checkErrorMessageWhenAddingAIncorrectLengthComment() {

editText.perform(typeText("a".repeat(MAX_REVIEW_LENGTH + 1)));
editText.perform(closeSoftKeyboard());

addItemButton.perform(click());

errorText.check(matches(withText(
String.format(Locale.ENGLISH, "Exceeded character limit: %d", MAX_REVIEW_LENGTH))));
}


// After the error message is displayed, it should disappears when user edits the comment to make it shorter
// It reappears if the length is still to long when adding the review
@Test
public void checkErrorMessageDisappearsWhenEditing() {
editText.perform(typeText("a".repeat(MAX_REVIEW_LENGTH + 1)));
editText.perform(closeSoftKeyboard());

addItemButton.perform(click());
//activity.addItem();

editText.perform(closeSoftKeyboard());
editText.perform(click(), closeSoftKeyboard());

errorText.check(matches(withText("")));
}

@After
public void after() {
release();
Expand Down
140 changes: 101 additions & 39 deletions app/src/androidTest/java/com/github/sdp/mediato/SearchFragmentTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static com.adevinta.android.barista.assertion.BaristaListAssertions.assertDisplayedAtPosition;
import static com.adevinta.android.barista.assertion.BaristaRecyclerViewAssertions.assertRecyclerViewItemCount;
import static com.adevinta.android.barista.assertion.BaristaVisibilityAssertions.assertContains;
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.BaristaClickInteractions.clickOn;
Expand Down Expand Up @@ -104,6 +105,8 @@ public void setUp() throws ExecutionException, InterruptedException, TimeoutExce
// Pass the username to the fragment like at profile creation
Bundle bundle = new Bundle();
bundle.putString("username", user1.getUsername());
bundle.putString("general_search", "true");
bundle.putString("collection", "Recently watched");
searchFragment.setArguments(bundle);
fragmentManager.beginTransaction().replace(R.id.main_container, searchFragment)
.commitAllowingStateLoss();
Expand All @@ -117,6 +120,8 @@ public static void cleanDatabase() {

@Test
public void testUserSearchWithEmptyString() {
clickOn(R.id.search_category_people);

clickOn(androidx.appcompat.R.id.search_button);
typeTo(androidx.appcompat.R.id.search_src_text, "user");
pressImeActionButton();
Expand All @@ -128,7 +133,7 @@ public void testUserSearchWithEmptyString() {

sleep(WAIT_TIME);

assertRecyclerViewItemCount(R.id.searchactivity_recyclerView, 0);
assertRecyclerViewItemCount(R.id.userSearch_recyclerView, 0);
}

@Test
Expand All @@ -139,7 +144,7 @@ public void testUserSearchWithUnknownUser() {

sleep(WAIT_TIME);

assertRecyclerViewItemCount(R.id.searchactivity_recyclerView, 0);
assertRecyclerViewItemCount(R.id.userSearch_recyclerView, 0);
}

@Test
Expand All @@ -150,7 +155,7 @@ public void testUserSearchWithKnownUser() {

sleep(WAIT_TIME);

assertDisplayedAtPosition(R.id.searchactivity_recyclerView, 0, R.id.userAdapter_userName, user2.getUsername());
assertDisplayedAtPosition(R.id.userSearch_recyclerView, 0, R.id.userAdapter_userName, user2.getUsername());
}

@Test
Expand All @@ -161,8 +166,8 @@ public void testUserSearchWithBeginningOfKnownUser() {

sleep(WAIT_TIME);

assertDisplayedAtPosition(R.id.searchactivity_recyclerView, 0, R.id.userAdapter_userName, user2.getUsername());
assertDisplayedAtPosition(R.id.searchactivity_recyclerView, 1, R.id.userAdapter_userName, user3.getUsername());
assertDisplayedAtPosition(R.id.userSearch_recyclerView, 0, R.id.userAdapter_userName, user2.getUsername());
assertDisplayedAtPosition(R.id.userSearch_recyclerView, 1, R.id.userAdapter_userName, user3.getUsername());
assertNotDisplayed(R.id.userAdapter_userName, user4.getUsername());
assertNotDisplayed(R.id.userAdapter_userName, user1.getUsername());
}
Expand All @@ -175,20 +180,20 @@ public void testFollowAndUnfollow() {

sleep(WAIT_TIME);

assertDisplayedAtPosition(R.id.searchactivity_recyclerView, 0, R.id.userAdapter_userName, user2.getUsername());
assertDisplayedAtPosition(R.id.searchactivity_recyclerView, 0, R.id.userAdapter_followButton, R.string.searchUser_follow);
clickListItemChild(R.id.searchactivity_recyclerView, 0, R.id.userAdapter_followButton);
assertDisplayedAtPosition(R.id.userSearch_recyclerView, 0, R.id.userAdapter_userName, user2.getUsername());
assertDisplayedAtPosition(R.id.userSearch_recyclerView, 0, R.id.userAdapter_followButton, R.string.searchUser_follow);
clickListItemChild(R.id.userSearch_recyclerView, 0, R.id.userAdapter_followButton);

sleep(WAIT_TIME);

assertDisplayedAtPosition(R.id.searchactivity_recyclerView, 0, R.id.userAdapter_userName, user2.getUsername());
assertDisplayedAtPosition(R.id.searchactivity_recyclerView, 0, R.id.userAdapter_unfollowButton, R.string.searchUser_unfollow);
clickListItemChild(R.id.searchactivity_recyclerView, 0, R.id.userAdapter_unfollowButton);
assertDisplayedAtPosition(R.id.userSearch_recyclerView, 0, R.id.userAdapter_userName, user2.getUsername());
assertDisplayedAtPosition(R.id.userSearch_recyclerView, 0, R.id.userAdapter_unfollowButton, R.string.searchUser_unfollow);
clickListItemChild(R.id.userSearch_recyclerView, 0, R.id.userAdapter_unfollowButton);

sleep(WAIT_TIME);

assertDisplayedAtPosition(R.id.searchactivity_recyclerView, 0, R.id.userAdapter_userName, user2.getUsername());
assertDisplayedAtPosition(R.id.searchactivity_recyclerView, 0, R.id.userAdapter_followButton, R.string.searchUser_follow);
assertDisplayedAtPosition(R.id.userSearch_recyclerView, 0, R.id.userAdapter_userName, user2.getUsername());
assertDisplayedAtPosition(R.id.userSearch_recyclerView, 0, R.id.userAdapter_followButton, R.string.searchUser_follow);
}

@Test
Expand All @@ -199,13 +204,13 @@ public void testClickOnCard() {

sleep(WAIT_TIME);

assertDisplayedAtPosition(R.id.searchactivity_recyclerView, 0, R.id.userAdapter_userName, user2.getUsername());
assertDisplayedAtPosition(R.id.searchactivity_recyclerView, 0, R.id.userAdapter_followButton, R.string.searchUser_follow);
clickListItemChild(R.id.searchactivity_recyclerView, 0, R.id.userAdapter_followButton);
assertDisplayedAtPosition(R.id.userSearch_recyclerView, 0, R.id.userAdapter_userName, user2.getUsername());
assertDisplayedAtPosition(R.id.userSearch_recyclerView, 0, R.id.userAdapter_followButton, R.string.searchUser_follow);
clickListItemChild(R.id.userSearch_recyclerView, 0, R.id.userAdapter_followButton);

sleep(WAIT_TIME);

clickListItem(R.id.searchactivity_recyclerView, 0);
clickListItem(R.id.userSearch_recyclerView, 0);

sleep(WAIT_TIME);

Expand All @@ -214,57 +219,114 @@ public void testClickOnCard() {
}

@Test
public void testMovieSearchWithEmptyString() {
clickOn(R.id.search_category_movie);
clickOn(androidx.appcompat.R.id.search_button);
typeTo(androidx.appcompat.R.id.search_src_text, "Potter");
public void testTrendingBooks() {
clickOn(R.id.search_category_books);

sleep(WAIT_TIME);
sleep(15 * WAIT_TIME);

clearText(androidx.appcompat.R.id.search_src_text);
assertDisplayed(R.id.bookTrending_recyclerView);
assertNotDisplayed(R.id.userSearch_recyclerView);
assertNotDisplayed(R.id.bookSearch_recyclerView);
assertNotDisplayed(R.id.movieSearch_recyclerView);
assertNotDisplayed(R.id.movieTrending_recyclerView);

assertRecyclerViewItemCount(R.id.bookTrending_recyclerView, 100);
}

@Test
public void testSearchBooks() {
clickOn(R.id.search_category_books);

clickOn(androidx.appcompat.R.id.search_button);
typeTo(androidx.appcompat.R.id.search_src_text, "Harry Potter and the Deathly Hallows");
pressImeActionButton();

sleep(WAIT_TIME);
sleep(15 * WAIT_TIME);

assertNotDisplayed(R.id.bookTrending_recyclerView);
assertNotDisplayed(R.id.userSearch_recyclerView);
assertDisplayed(R.id.bookSearch_recyclerView);
assertNotDisplayed(R.id.movieSearch_recyclerView);
assertNotDisplayed(R.id.movieTrending_recyclerView);

assertContains("Harry Potter and the Deathly Hallows");

assertRecyclerViewItemCount(R.id.searchactivity_recyclerView, 0);
clickOn(R.id.search_category_movie);
clickOn(R.id.search_category_books);

assertContains("Harry Potter and the Deathly Hallows");
}

@Test
public void testMovieSearchWithUnknownMovie() {
clickOn(R.id.search_category_movie);
public void testDisplayTrendingWhenEmptyQuery() {
clickOn(R.id.search_category_books);

clickOn(androidx.appcompat.R.id.search_button);
typeTo(androidx.appcompat.R.id.search_src_text, "jadvbipehsjdb");
typeTo(androidx.appcompat.R.id.search_src_text, "Harry Potter");
pressImeActionButton();

assertNotDisplayed(R.id.bookTrending_recyclerView);
assertNotDisplayed(R.id.userSearch_recyclerView);
assertDisplayed(R.id.bookSearch_recyclerView);
assertNotDisplayed(R.id.movieSearch_recyclerView);
assertNotDisplayed(R.id.movieTrending_recyclerView);

sleep(WAIT_TIME);

assertRecyclerViewItemCount(R.id.searchactivity_recyclerView, 0);
clickOn(androidx.appcompat.R.id.search_close_btn);

sleep(WAIT_TIME);

assertDisplayed(R.id.bookTrending_recyclerView);
assertNotDisplayed(R.id.userSearch_recyclerView);
assertNotDisplayed(R.id.bookSearch_recyclerView);
assertNotDisplayed(R.id.movieSearch_recyclerView);
assertNotDisplayed(R.id.movieTrending_recyclerView);
}

@Test
public void testMovieSearchWithKnownMovie() {
public void testMovieSearchWithEmptyString() {
clickOn(R.id.search_category_movie);

clickOn(androidx.appcompat.R.id.search_button);
typeTo(androidx.appcompat.R.id.search_src_text, "Harry Potter and the half blood prince");
typeTo(androidx.appcompat.R.id.search_src_text, "Harry Potter");
pressImeActionButton();

assertNotDisplayed(R.id.bookTrending_recyclerView);
assertNotDisplayed(R.id.userSearch_recyclerView);
assertNotDisplayed(R.id.bookSearch_recyclerView);
assertDisplayed(R.id.movieSearch_recyclerView);
assertNotDisplayed(R.id.movieTrending_recyclerView);

sleep(WAIT_TIME);

clickOn(androidx.appcompat.R.id.search_close_btn);

sleep(WAIT_TIME);
assertDisplayedAtPosition(R.id.searchactivity_recyclerView, 0, R.id.text_title, "Harry Potter and the Half-Blood Prince");

assertNotDisplayed(R.id.bookTrending_recyclerView);
assertNotDisplayed(R.id.userSearch_recyclerView);
assertNotDisplayed(R.id.bookSearch_recyclerView);
assertNotDisplayed(R.id.movieSearch_recyclerView);
assertDisplayed(R.id.movieTrending_recyclerView);
}

@Test
public void testClickOnMovieSearchResultOpensRatingScreen() {
public void testMovieSearchWithKnownMovie() {
clickOn(R.id.search_category_movie);

clickOn(androidx.appcompat.R.id.search_button);
typeTo(androidx.appcompat.R.id.search_src_text, "Harry Potter and the half blood prince");
pressImeActionButton();

sleep(WAIT_TIME);
assertDisplayedAtPosition(R.id.searchactivity_recyclerView, 0, R.id.text_title, "Harry Potter and the Half-Blood Prince");
sleep(5*WAIT_TIME);

onView(withId(R.id.searchactivity_recyclerView))
.perform(RecyclerViewActions.actionOnItemAtPosition(0, click()));
assertContains("Harry Potter and the Half-Blood Prince");

sleep(WAIT_TIME);
assertDisplayed(R.id.item_description_text);
clickOn(R.id.search_category_books);
clickOn(R.id.search_category_movie);

assertContains("Harry Potter and the Half-Blood Prince");
}

}
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/com/github/sdp/mediato/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ private void setDefaultFragment(String username) {

// 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");

searchFragment.setArguments(args);
myProfileFragment.setArguments(args);
Expand Down
11 changes: 2 additions & 9 deletions app/src/main/java/com/github/sdp/mediato/api/API.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,7 @@
import java.util.concurrent.CompletableFuture;

public interface API<T> {
CompletableFuture<T> searchItem(String s);
CompletableFuture<List<T>> searchItems(String s, int page);

CompletableFuture<List<T>> searchItems(String s, int count);

// Removed since the book API does not provide a trending feature. Might be added again later
// CompletableFuture<List<T>> trending(int count);

CompletableFuture<T> get(String id);

default void clearCache(){ }
CompletableFuture<List<T>> trending(int page);
}
Loading

0 comments on commit e85bb21

Please sign in to comment.