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

Add multiple collections #90

Merged
merged 23 commits into from
Mar 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7600a0e
added Adapter class to handle list of collection
simone-kalbermatter Mar 29, 2023
3b1bc35
add new collection works
simone-kalbermatter Mar 29, 2023
3a4e4db
list of collections is scrollable
simone-kalbermatter Mar 29, 2023
7ecd7f9
bottom bar does not cover collections
simone-kalbermatter Mar 29, 2023
a99b87d
added padding
simone-kalbermatter Mar 29, 2023
3985dba
fixed Friends button position
simone-kalbermatter Mar 29, 2023
f8bddf1
fix bottom bar covering view (this time really pls)
simone-kalbermatter Mar 29, 2023
56c1ec9
Fix collection having only one element
MeKHell Mar 29, 2023
29aa90a
changed button
simone-kalbermatter Mar 29, 2023
7ec8020
changed name to CollectionListAdapter
simone-kalbermatter Mar 29, 2023
6e9ccdb
add dialog to enter collection name
simone-kalbermatter Mar 29, 2023
bbfe441
refactored and handle empty and duplicate collection names
simone-kalbermatter Mar 29, 2023
77fcf9b
add comments
simone-kalbermatter Mar 29, 2023
1733876
upload to db
simone-kalbermatter Mar 29, 2023
2d00ab1
add callback to main
simone-kalbermatter Mar 30, 2023
4cf4927
update DB
simone-kalbermatter Mar 30, 2023
4599914
update comments
simone-kalbermatter Mar 30, 2023
38e6698
add tests
simone-kalbermatter Mar 30, 2023
35d9737
remove xml
simone-kalbermatter Mar 30, 2023
05bafeb
address mariem's comments
simone-kalbermatter Mar 30, 2023
0b91215
refactor tests
simone-kalbermatter Mar 30, 2023
34feda1
use db emulator
simone-kalbermatter Mar 30, 2023
5b5ecd2
fix bug
simone-kalbermatter Mar 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions .idea/androidTestResultsUserPreferences.xml

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

2 changes: 2 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ dependencies {
androidTestImplementation 'androidx.test:rules:1.5.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.5.1'
androidTestImplementation 'com.adevinta.android:barista:4.2.0'
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'

androidTestImplementation('com.adevinta.android:barista:4.2.0')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
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 org.junit.Assert.fail;

import android.os.Bundle;
import android.view.View;
Expand All @@ -16,6 +17,12 @@
import androidx.test.espresso.ViewInteraction;
import androidx.test.espresso.matcher.BoundedMatcher;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.UiObject;
import androidx.test.uiautomator.UiObjectNotFoundException;
import androidx.test.uiautomator.UiSelector;
import com.github.sdp.mediato.data.Database;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.Before;
Expand All @@ -26,12 +33,29 @@
public class ProfileFragmentTest {

ActivityScenario<TestingActivity> scenario;
ViewInteraction outerRecyclerView = onView(withId(R.id.collection_list_recycler_view));
ViewInteraction collectionRecyclerView = onView(withId(R.id.collection_recycler_view));
ViewInteraction recyclerView = onView(withId(R.id.collection_recycler_view));
ViewInteraction userNameText = onView(withId(R.id.username_text));
ViewInteraction editButton = onView(withId(R.id.edit_button));
ViewInteraction friendsButton = onView(withId(R.id.friends_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));
ViewInteraction profilePic = onView(withId(R.id.profile_image));


@Before
public void setUp() {
// Launch the TestingActivity
scenario = ActivityScenario.launch(TestingActivity.class);

// Use Database emulator
try {
Database.database.useEmulator("10.0.2.2", 9000);
} catch (Exception ignored) {
}

// Set up the TestingActivity to display the ProfileFragment
scenario.onActivity(activity -> {
FragmentManager fragmentManager = activity.getSupportFragmentManager();
Expand All @@ -49,38 +73,33 @@ public void setUp() {
// Test whether the "Friends" button is displayed and contains the correct text
@Test
public void testFriendsButton() {
ViewInteraction friendsButton = onView(withId(R.id.friends_button));
friendsButton.check(matches(isDisplayed()));
friendsButton.check(matches(withText("Friends")));
}

// Test whether the "Edit" button is displayed and contains the correct text
@Test
public void testEditButton() {
ViewInteraction editButton = onView(withId(R.id.edit_button));
editButton.check(matches(isDisplayed()));
editButton.check(matches(withText("Edit")));
}

// Test whether the profile picture is displayed
@Test
public void testProfilePicture() {
onView(withId(R.id.profile_image)).check(matches(isDisplayed()));
profilePic.check(matches(isDisplayed()));
}

// Test whether the username text is displayed and contains the correct text
@Test
public void testUsername() {
ViewInteraction userNameText = onView(withId(R.id.username_text));
userNameText.check(matches(isDisplayed()));
userNameText.check(matches(withText("myUsername")));
}

// Test the initial state of the default collection after profile creation
@Test
public void testInitialDefaultCollectionState() {
ViewInteraction defaultCollection = onView(withId(R.id.default_collection));
ViewInteraction recyclerView = onView(withId(R.id.collection_recycler_view));

// Check that the default collection is displayed
defaultCollection.check(matches(isDisplayed()));
Expand All @@ -101,16 +120,69 @@ public void testInitialDefaultCollectionState() {
// Test that an item is added to the collection on click of the AddMediaButton
@Test
public void testAddMediaButton() {
ViewInteraction collectionRecyclerView = onView(withId(R.id.collection_recycler_view));
ViewInteraction addMediaButton = onView(withId(R.id.add_media_button));

int initialItemCount = getRecyclerViewItemCount(R.id.collection_recycler_view);

collectionRecyclerView.check(matches(hasItemCount(initialItemCount)));
addMediaButton.perform(click());
collectionRecyclerView.check(matches(hasItemCount(initialItemCount + 1)));
}

// Test the initial state of the list of collections after profile creation
@Test
public void testInitialOuterRecyclerViewState() {
outerRecyclerView.check(matches(isDisplayed()));
// Check that the outer RecyclerView initially has one item (default collection)
outerRecyclerView.check(matches(hasItemCount(1)));
}

// Check that a new collection has been added to the outer RecyclerView if the user chooses a valid collection name
@Test
public void testAddValidCollection() throws UiObjectNotFoundException {
int initialItemCount = getRecyclerViewItemCount(R.id.collection_list_recycler_view);

outerRecyclerView.check(matches(hasItemCount(initialItemCount)));
addCollectionButton.perform(click());
enterTextInAlertBoxAndClickAdd("valid");
outerRecyclerView.check(matches(hasItemCount(initialItemCount + 1)));
}

// Check that no new collection has been added to the outer RecyclerView if the user enters an empty collection name
@Test
public void testEmptyCollectionNameNotAdded() throws UiObjectNotFoundException {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is valid for all the tests: Are you updating the collections in the database in the code that you're testing here ? If so, you could use the emulator in this class like in the DatabaseTests classes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code storing the collection in the database will be run, however these tests don't verify the upload to the database but only the ProfileFragment UI. The database functions should probably be tested outside of this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The database functions are already tested in another class but we should still use the emulator to avoid spamming the "production" database with test values.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I just start the database emulator before testing it won't upload to the actual database? Even if it is not in a database test?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes you can just copy the setup method from the database tests (just the part where you use the emulator ofc).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay thanks, done!

int initialItemCount = getRecyclerViewItemCount(R.id.collection_list_recycler_view);

outerRecyclerView.check(matches(hasItemCount(initialItemCount)));
addCollectionButton.perform(click());
enterTextInAlertBoxAndClickAdd("");
outerRecyclerView.check(matches(hasItemCount(initialItemCount)));
}

// Check that only one collection gets added if the user tries to add a collection with the same username twice
@Test
public void testDuplicateCollectionNameNotAdded() throws UiObjectNotFoundException {
int initialItemCount = getRecyclerViewItemCount(R.id.collection_list_recycler_view);

outerRecyclerView.check(matches(hasItemCount(initialItemCount)));
addCollectionButton.perform(click());
enterTextInAlertBoxAndClickAdd("duplicate");
addCollectionButton.perform(click());
enterTextInAlertBoxAndClickAdd("duplicate");
outerRecyclerView.check(matches(hasItemCount(initialItemCount + 1)));
}

// Check that only one collection gets added if the user tries to add a collection with the same username twice
@Test
public void testEnterValidCollectionAndCancelDoesNotAddCollection()
throws UiObjectNotFoundException {
int initialItemCount = getRecyclerViewItemCount(R.id.collection_list_recycler_view);

outerRecyclerView.check(matches(hasItemCount(initialItemCount)));
addCollectionButton.perform(click());
enterTextInAlertBoxAndClickCancel("duplicate");
outerRecyclerView.check(matches(hasItemCount(initialItemCount)));
}


/**
* A matcher to check if a RecyclerView has a certain amount of items.
*
Expand Down Expand Up @@ -147,6 +219,50 @@ private int getRecyclerViewItemCount(int id) {
return itemCount[0];
}

/**
* Used to interact with the AlertDialog to enter the collection name
*
* @param enterText the text to enter into the dialog box
*/
private void enterTextInAlertBoxAndClickAdd(String enterText) {
try {
UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
UiObject inputField = device.findObject(
new UiSelector().resourceId("com.github.sdp.mediato:id/collection_name_input"));
inputField.setText(enterText);

UiObject addButton = device.findObject(
// In case the text of the button is ever changed: this is case sensitive!
// If the string resource says Add but the button text is displayed in capital letters, only ADD works!
new UiSelector().text("ADD"));
addButton.click();
} catch (UiObjectNotFoundException e) {
fail();
}
}

/**
* Used to interact with the AlertDialog to enter the collection name
*
* @param enterText the text to enter into the dialog box
*/
private void enterTextInAlertBoxAndClickCancel(String enterText) {
try {
UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
UiObject inputField = device.findObject(
new UiSelector().resourceId("com.github.sdp.mediato:id/collection_name_input"));
inputField.setText(enterText);

UiObject addButton = device.findObject(
// In case the text of the button is ever changed: this is case sensitive!
// If the string resource says Cancel but the button text is displayed in capital letters, only CANCEL works!
new UiSelector().text("CANCEL"));
addButton.click();
} catch (UiObjectNotFoundException e) {
fail();
}
}

}


Loading