Skip to content

Commit

Permalink
Merge pull request #233 from karimassi/fix/message-test
Browse files Browse the repository at this point in the history
Fix/message test
  • Loading branch information
celinecamacho authored Jun 3, 2020
2 parents cec85e0 + 475fabd commit 5c3b021
Show file tree
Hide file tree
Showing 12 changed files with 91 additions and 66 deletions.
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,33 @@
# BalelecBud

[![Build Status](https://api.cirrus-ci.com/github/karimassi/balelec-bud.svg)](https://cirrus-ci.com/github/karimassi/balelec-bud)
[![Maintainability](https://api.codeclimate.com/v1/badges/7d3c96ac0fb8ea059bf9/maintainability)](https://codeclimate.com/github/karimassi/balelec-bud/maintainability)
[![Test Coverage](https://api.codeclimate.com/v1/badges/7d3c96ac0fb8ea059bf9/test_coverage)](https://codeclimate.com/github/karimassi/balelec-bud/test_coverage)

BalelecBud is a companion app for the Balelec festival held annually at EPFL. Its purpose is to ease and augment the festival-goers' experience before, during and after the event.

## Features

The main features of the app are:

- Tracking your friends in realtime so you never lose them in the crowds
- Checking the line up, subscribing to concerts to be notified
- Checking the festival's general information
- Calling emergency services, declaring emergencies and asking for realtime help
- Seeing the festival's points of interests and the affluence around them
- Having a pocket map displaying all the spots' and friends' locations
- Playing the festival's Spotify playlist
- Taking and uploading pictures to the festival's photo wall
- Seeing realtime transportation information around the festival's site
- Ability to use the app without an internet connection (with reduced functionality)

## Authors

This project was developed in the scope of the Software Development Project course at EPFL. It has been written by:

- Karim Assi - [@karimassi](https://github.com/karimassi)
- Céline Camacho - [@celinecamacho](https://github.com/celinecamacho)
- Axel Marmet - [@axelmarmet](https://github.com/axelmarmet)
- Camille Montemagni - [@Cammonte](https://github.com/Cammonte)
- Gaspard Peduzzi - [@GaspardPeduzzi](https://github.com/gpeduzzi)
- Alexandre Pinazza - [@Pialex99](https://github.com/Pialex99)
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,6 @@ public void setup() {
NotificationMessageTest.clearNotifications(device);
}

@After
public void tearDown() {
NotificationMessageTest.clearNotifications(device);
}

@Test
public void onNewTokenTest() {
cloudMessagingService.onNewToken(token);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import androidx.test.rule.ActivityTestRule;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.Until;

import com.google.firebase.messaging.RemoteMessage;

Expand All @@ -31,6 +32,7 @@
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.testng.AssertJUnit.assertFalse;

@RunWith(AndroidJUnit4.class)
public class MessageTest {
Expand Down Expand Up @@ -70,11 +72,6 @@ public void setup() {
mockMessagingService.setContext(mActivityRule.getActivity());
}

@After
public void tearDown() {
NotificationMessageTest.clearNotifications(device);
}

@Test
public void sendFriendshipMessageNullType() {
Message.sendFriendshipMessage(friend, user.getUid(), null);
Expand Down Expand Up @@ -114,23 +111,21 @@ public void sendAcceptRequestMessageWithoutToken() {
public void sendMessageToUserWithToken() {
Message message = new Message(title, body, getAppContext().getString(R.string.message_type_general));
message.sendMessage(user.getUid());
NotificationMessageTest.verifyNotification(device, title, body);
NotificationMessageTest.verifyNotification(device, title);
}

@Test
public void sendMessageToUserWithoutToken() {
Message message = new Message(title, body, getAppContext().getString(R.string.message_type_general));
message.sendMessage(MockDatabase.axel.getUid());
device.openNotification();
assertNull(device.findObject(By.text(title)));
assertFalse(device.wait(Until.hasObject(By.textStartsWith(title)), 5_000));
}

@Test
public void sendNullMessageTest() {
Message message = new Message(null, null, getAppContext().getString(R.string.message_type_general));
message.sendMessage(user.getUid());
device.openNotification();
assertNull(device.findObject(By.text(title)));
assertFalse(device.wait(Until.hasObject(By.textStartsWith(title)), 5_000));
}

@Test
Expand All @@ -154,7 +149,6 @@ public void extractEmptyMessageTest() {

private void sendFriendshipMessageTest(Message.Type type, String title, String body) {
Message.sendFriendshipMessage(friend, user.getUid(), type);
NotificationMessageTest.verifyNotification(device, title,
friend.getDisplayName() + body);
NotificationMessageTest.verifyNotification(device, title);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,7 @@ private void checkPermissionAfterResult(String[] permissions, int[] permissionSt
LocationUtils.LOCATION_PERMISSIONS_REQUEST_CODE,
permissions,
permissionStatus);
if (b) {
checkDisplayed(LOCATION_ENABLE_TITLE);
} else {
checkDisplayed(LOCATION_INFO_TITLE);
}
checkDisplayed(b ? LOCATION_ENABLE_TITLE : LOCATION_INFO_TITLE);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import ch.epfl.balelecbud.R;
import ch.epfl.balelecbud.RootActivity;
import ch.epfl.balelecbud.model.Slot;
import ch.epfl.balelecbud.utility.authentication.MockAuthenticator;
import ch.epfl.balelecbud.utility.database.Database;
import ch.epfl.balelecbud.utility.database.MockDatabase;
import ch.epfl.balelecbud.utility.location.LocationClient;
Expand All @@ -56,7 +57,9 @@
@RunWith(AndroidJUnit4.class)
public class ConcertNotificationTest {

private final MockDatabase mock = MockDatabase.getInstance();
private final MockDatabase mockDatabase = MockDatabase.getInstance();
private final MockAuthenticator mockAuth = MockAuthenticator.getInstance();

@Rule
public final ActivityTestRule<RootActivity> mActivityRule =
new ActivityTestRule<RootActivity>(RootActivity.class) {
Expand All @@ -73,7 +76,10 @@ public void requestLocationUpdates(LocationRequest lr, PendingIntent intent) {
public void removeLocationUpdates(PendingIntent intent) {
}
});
BalelecbudApplication.setAppDatabase(mock);
BalelecbudApplication.setAppDatabase(mockDatabase);
BalelecbudApplication.setAppAuthenticator(mockAuth);
mockAuth.signOut();
mockAuth.setCurrentUser(MockDatabase.celine);
}
};
private final Slot s = new Slot(0, "Le nom de mon artiste", "Scene 3", "path1",
Expand All @@ -91,7 +97,7 @@ public void setup() {
// quit the notifications center if it happens to be open
NotificationMessageTest.clearNotifications(device);

mock.resetDocument(Database.CONCERT_SLOTS_PATH);
mockDatabase.resetDocument(Database.CONCERT_SLOTS_PATH);
SlotData.setIntentLauncher(null);
this.db = Room.inMemoryDatabaseBuilder(
getApplicationContext(),
Expand All @@ -110,7 +116,7 @@ public void tearDown() {
public void subscribeToAConcertScheduleANotification() throws Throwable {
checkSwitchAfter(() -> {
checkNotification();
device.waitForWindowUpdate(null, 10000);
device.waitForWindowUpdate(null, 10_000);
openScheduleActivityFrom(R.id.root_activity_drawer_layout, R.id.root_activity_nav_view);
Log.v("mySuperTag", "executed subscribeToAConcertScheduleANotification");
}, s, false);
Expand Down Expand Up @@ -147,7 +153,7 @@ public void unsubscribeToAConcertCancelNotification() throws Throwable {
Slot s1 = new Slot(0, "Le nom de mon artiste", "Scene 3", "path1",
new Timestamp(cal.getTime()), new Timestamp(cal.getTime()));

mock.storeDocument(Database.CONCERT_SLOTS_PATH, s1);
mockDatabase.storeDocument(Database.CONCERT_SLOTS_PATH, s1);

openScheduleActivityFrom(R.id.root_activity_drawer_layout, R.id.root_activity_nav_view);

Expand All @@ -167,7 +173,7 @@ public void unsubscribeToAConcertCancelNotification() throws Throwable {

private void checkSwitchAfter(Runnable runnable, Slot s, boolean switchStateAfter) throws Throwable {

mock.storeDocument(Database.CONCERT_SLOTS_PATH, s);
mockDatabase.storeDocument(Database.CONCERT_SLOTS_PATH, s);

openScheduleActivityFrom(R.id.root_activity_drawer_layout, R.id.root_activity_nav_view);

Expand All @@ -185,7 +191,11 @@ private void checkNotification() {
String expectedTitle = mActivityRule.getActivity().getString(R.string.concert_soon_notification_title);
String expectedText = "Le nom de mon artiste starts in 15 minutes on Scene 3";

UiObject2 title = NotificationMessageTest.verifyNotification(device, expectedTitle, expectedText);
device.openNotification();
assertNotNull(device.wait(Until.hasObject(By.textStartsWith(expectedTitle)), 10_000));
UiObject2 title = device.findObject(By.text(expectedTitle));
assertNotNull(title);
assertNotNull(device.findObject(By.text(expectedText)));

title.click();
}
Expand All @@ -202,13 +212,13 @@ private void clickItemFrom(int itemId, int nav_id) {
private void openScheduleActivityFrom(int layout_id, int nav_id) {
openDrawerFrom(layout_id, nav_id);
clickItemFrom(R.id.fragment_main_drawer_schedule, nav_id);
device.waitForIdle(10000);
device.waitForIdle(10_000);
}

private void openInfoActivityFrom(int layout_id, int nav_id) {
openDrawerFrom(layout_id, nav_id);
clickItemFrom(R.id.fragment_main_drawer_info, nav_id);
device.waitForIdle(10000);
device.waitForIdle(10_000);
}

private void refreshRecyclerView() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,7 @@ protected void beforeActivityLaunched() {
@Before
public void setup() {
device = UiDevice.getInstance(getInstrumentation());
NotificationMessageTest.clearNotifications(device);
}

@After
public void tearDown() {
NotificationMessageTest.clearNotifications(device);
clearNotifications(device);
}

@Test
Expand All @@ -66,22 +61,21 @@ public void scheduleSocialNotificationTest() {
private void scheduleNotificationTest(String type) {
Map<String, String> message = Message.createMessage(title, body, type);
NotificationMessage.getInstance().scheduleNotification(mActivityRule.getActivity(), message);
verifyNotification(device, title, body);
verifyNotification(device, title);
}

public static UiObject2 verifyNotification(UiDevice device, String title, String body) {
device.openNotification();
assertNotNull(device.wait(Until.hasObject(By.textStartsWith(title)), 30_000));
UiObject2 titleFound = device.findObject(By.text(title));
assertNotNull(titleFound);
assertNotNull(device.findObject(By.text(body)));
return titleFound;
public static void verifyNotification(UiDevice device, String title) {
assertNotNull(device.wait(Until.hasObject(By.textStartsWith(title)), 10_000));
clearNotifications(device);
}

public static void clearNotifications(UiDevice device) {
device.openNotification();
UiObject2 button = device.findObject(By.text("CLEAR ALL"));
if (button != null) button.click();
device.pressBack();
UiObject2 button = device.wait(Until.findObject(By.text("CLEAR ALL")), 10_000);
if (button != null) {
button.click();
} else {
device.pressBack();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,15 @@

import java.util.Calendar;

import ch.epfl.balelecbud.BalelecbudApplication;
import ch.epfl.balelecbud.R;
import ch.epfl.balelecbud.RootActivity;
import ch.epfl.balelecbud.model.Slot;
import ch.epfl.balelecbud.utility.authentication.MockAuthenticator;
import ch.epfl.balelecbud.utility.database.MockDatabase;
import ch.epfl.balelecbud.utility.location.LocationClient;
import ch.epfl.balelecbud.utility.location.LocationUtils;
import ch.epfl.balelecbud.utility.notifications.NotificationMessageTest;

import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static junit.framework.TestCase.assertEquals;
Expand All @@ -34,12 +37,23 @@
@RunWith(AndroidJUnit4.class)
public class ConcertSoonNotificationTest {

private final MockAuthenticator mockAuth = MockAuthenticator.getInstance();

@Rule
public final ActivityTestRule<RootActivity> mActivityRule = new ActivityTestRule<RootActivity>(RootActivity.class);
public final ActivityTestRule<RootActivity> mActivityRule =
new ActivityTestRule<RootActivity>(RootActivity.class) {
@Override
protected void beforeActivityLaunched() {
super.beforeActivityLaunched();
MockDatabase.getInstance().resetDatabase();
BalelecbudApplication.setAppAuthenticator(mockAuth);
mockAuth.signOut();
mockAuth.setCurrentUser(MockDatabase.celine);
}
};

@Before
public void setup() {
MockDatabase.getInstance().resetDatabase();
LocationUtils.setLocationClient(new LocationClient() {
@Override
public void requestLocationUpdates(LocationRequest lr, PendingIntent intent) {
Expand All @@ -56,13 +70,7 @@ public void removeLocationUpdates(PendingIntent intent) {
device.findObject(By.text("ALLOW")).click();
device.waitForWindowUpdate(null, 1000);
}
device.openNotification();
UiObject2 button = device.findObject(By.text("CLEAR ALL"));
if (button != null) {
button.click();
} else {
device.pressBack();
}
NotificationMessageTest.clearNotifications(device);
}

@Test
Expand All @@ -78,7 +86,7 @@ public void scheduleNotificationWorksCorrectly(){

UiDevice device = UiDevice.getInstance(getInstrumentation());
device.openNotification();
device.wait(Until.hasObject(By.textStartsWith(expectedTitle)), 30_000);
device.wait(Until.hasObject(By.textStartsWith(expectedTitle)), 10_000);

UiObject2 title = device.findObject(By.text(expectedTitle));
assertEquals(title.getText(), expectedTitle);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import androidx.test.rule.GrantPermissionRule;

import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
Expand Down Expand Up @@ -160,6 +161,7 @@ public void buttonIsDisplayed() {
onView(withId(R.id.fab_upload_picture)).check(matches(isDisplayed()));
}

@Ignore("Testing that the file is stored locally is not pertinent")
@Test
public void cameraIsSavingImageToLocalStorage() throws InterruptedException {
TestAsyncUtils sync = new TestAsyncUtils();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
*/
public final class FriendshipUtils {

//TODO Consider displaying freshness for the social tab
public static void requestFriend(User friend) {
Map<String, Boolean> toStore = new HashMap<>();
toStore.put(getAppAuthenticator().getCurrentUser().getUid(), true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ public final class PointOfInterestData extends RecyclerViewData<PointOfInterest,
this.activity = activity;
}

//TODO change to not have rv flicker at some point
@Override
public CompletableFuture<Long> reload(InformationSource preferredSource) {
MyQuery query = new MyQuery(Database.POINT_OF_INTEREST_PATH, new LinkedList<>(), preferredSource);
Expand Down
10 changes: 5 additions & 5 deletions app/src/main/res/raw/help_page.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,27 @@
{
"imageName": "page_welcome",
"title": "Welcome to BalelecBud!",
"description": "BalelecBud is a companion app for the best festival at EPFL. You can see the information about the festival, the transports near EPFL and take pictures all in the same app. You can open the menu and discover the app or swipe left to learn more about BalelecBud!"
"description": "BalelecBud is a companion app for the best festival at EPFL. You can see information about the festival, transports near EPFL and take pictures all in the same app. You can open the menu and discover the app or swipe left to learn more about BalelecBud!"
},
{
"imageName": "page_schedule",
"title": "Concert Schedule",
"description": "Don't you hate it when you miss the concert of your favorite band? Fear no more, BalelecBud is here to remind you of the performances you don't want!"
"description": "Don't you hate it when you miss the concert of your favorite band? Fear no more, BalelecBud is here to remind you of the performances you don't want to miss!"
},
{
"imageName": "page_social",
"title": "Social Network",
"description": "Balelec is not the same without your friends, so why don't you invite them? You can create an account or in Settings and send friend requests to all the other users of the app."
"description": "Balelec is not the same without your friends, so why don't you invite them? You can create an account in Settings and send friend requests to the other users of the app."
},
{
"imageName": "page_map",
"title": "Friends and Map",
"description": "Something that we can all relate is losing our friends at the festival. But now with BalelecBud you can know the location of your friends, you just need to make sure to allow your location in Settings."
"description": "Something we can all relate to is losing our friends at the festival. With BalelecBud, you can now know the location of your friends. All you need to do is allow your location in Settings."
},
{
"imageName": "page_poi",
"title": "Points of Interest",
"description": "Want to buy a beer but don't know which bar is the less crowded? BalelecBud is here to help you, you can go to Point of Interest and find out the affluence for each point. You can also see the points in the map to find them quickly."
"description": "Want to buy a beer but don't know which bar is the less crowded? BalelecBud is here to help you, you can go to Points of Interest and find out the affluence for each spot. You can also see the points in the map to find them quickly."
},
{
"imageName": "page_playlist",
Expand Down
Loading

0 comments on commit 5c3b021

Please sign in to comment.