package edu.washington.geopost.test;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import android.test.AndroidTestCase;
import android.util.Log;
import com.google.android.gms.maps.model.LatLng;
import com.parse.Parse;
import com.parse.ParseException;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import com.parse.ParseUser;
import edu.washington.geopost.DBStore;
import edu.washington.geopost.ParsePin;
import edu.washington.geopost.Pin;
/**
* DBStoreTest contains unit tests for the functionality of the DBStore class.
* @authors Neil Hinnant, Katie Madonna, Andrew Repp
*/
public class DBStoreTest extends AndroidTestCase {
private static final String APP_ID = "<INSERT ACTUAL PARSE APP ID HERE>";
private static final String CLIENT_KEY = "<INSERT ACTUAL PARSE CLIENT KEY HERE>";
// User login information
private static final String PARSE_USER_EMAIL = "parsetestuser@huehuehue.com";
private static final String PARSE_USERNAME = "Parse Test User";
private static final String PARSE_PASSWORD = "testPassword1234";
private static final String PARSE_USER_EMAIL_2 = "parsetestuser2@cse403.com";
private static final String PARSE_USERNAME_2 = "Parse Test User 2";
private static final String PARSE_PASSWORD_2 = "testPassword5678";
private static DBStore pinWriter;
private static List<ParseObject> createdObjs; // For removal of pins.
private static ParseQuery<ParsePin> query;
private static ParseUser testUser;
/**
* Sets up the test class for each individual test.
*/
@Override
public void setUp() throws Exception {
super.setUp();
Parse.initialize(getContext(), APP_ID, CLIENT_KEY);
ParseObject.registerSubclass(ParsePin.class);
pinWriter = new DBStore();
createdObjs = new ArrayList<ParseObject>();
query = ParseQuery.getQuery(ParsePin.class);
ParseUser.logOut();
testUser = new ParseUser();
testUser.setEmail(PARSE_USER_EMAIL);
testUser.setUsername(PARSE_USERNAME);
testUser.setPassword(PARSE_PASSWORD);
try {
testUser.signUp();
} catch (ParseException e) {
if (e.getCode() != ParseException.USERNAME_TAKEN) {
Log.d("DBStoreTest setUp", "error signing up user, but user"
+ "name not already taken");
throw e;
}
}
try {
ParseUser.logIn(PARSE_USERNAME, PARSE_PASSWORD);
} catch (ParseException e) {
Log.d("DBStoreTest setUp", "error logging in user");
throw e;
}
testUser = ParseUser.getCurrentUser();
}
/**
* Tears down the test class after each individual test.
*/
@Override
public void tearDown() throws Exception {
super.tearDown();
// Delete all the elements added to the database after the test ran.
try {
ParseObject.deleteAll(createdObjs);
} catch (ParseException e) {
Log.d("DBStoreTest tearDown", "Couldn't delete objects from the"
+ "database.");
e.printStackTrace();
}
}
/**
* Tests that adding a single pin to the database works correctly.
*/
@Test
public void testSinglePin() {
String message = "This is a test pin";
LatLng coord = new LatLng(35.445, 47.555);
Pin pin = pinWriter.postPin(coord, message, null);
// Add the created Pin to the list so it can be
// removed at the end of the test.
try {
createdObjs.add(query.get(pin.getPinId()));
} catch (ParseException e) {
e.printStackTrace();
}
assertNotNull(pin);
assertFalse(pin.isLocked());
assertEquals(coord, pin.getLocation());
assertEquals(testUser.getUsername(), pin.getUser());
assertEquals(message, pin.getMessage());
assertNull(pin.getPhoto());
}
/**
* Tests that adding multiple pins to the database in a row works
* correctly.
*/
@Test
public void testMultiPin() {
LatLng coord1 = new LatLng(25.225, 56.553);
LatLng coord2 = new LatLng(23.455, 57.898);
LatLng coord3 = new LatLng(26.999, 58.550);
Pin pin1 = pinWriter.postPin(coord1, "Pin1", null);
Pin pin2 = pinWriter.postPin(coord2, "Pin2", null);
Pin pin3 = pinWriter.postPin(coord3, "Pin3", null);
// Add the created Pins to the list so they can be
// removed at the end of the test.
try {
createdObjs.add(query.get(pin1.getPinId()));
createdObjs.add(query.get(pin2.getPinId()));
createdObjs.add(query.get(pin3.getPinId()));
} catch (ParseException e) {
e.printStackTrace();
}
assertNotNull(pin1);
assertFalse(pin1.isLocked());
assertEquals(coord1, pin1.getLocation());
assertEquals(testUser.getUsername(), pin1.getUser());
assertEquals("Pin1", pin1.getMessage());
assertNull(pin1.getPhoto());
assertNotNull(pin2);
assertFalse(pin2.isLocked());
assertEquals(coord2, pin2.getLocation());
assertEquals("Pin2", pin2.getMessage());
assertEquals(testUser.getUsername(), pin2.getUser());
assertNull(pin2.getPhoto());
assertNotNull(pin3);
assertFalse(pin3.isLocked());
assertEquals(coord3, pin3.getLocation());
assertEquals("Pin3", pin3.getMessage());
assertEquals(testUser.getUsername(), pin2.getUser());
assertNull(pin2.getPhoto());
}
/**
* Tests that saving two pins at the same coordinates works correctly.
*/
@Test
public void testDuplicatePin() {
LatLng coord = new LatLng(47.325, -18.25);
Pin first = pinWriter.postPin(coord, "First Message", null);
Pin second = pinWriter.postPin(coord, "Second Message", null);
// Add the created Pins to the list so they can be
// removed at the end of the test.
try {
createdObjs.add(query.get(first.getPinId()));
createdObjs.add(query.get(second.getPinId()));
} catch (ParseException e) {
e.printStackTrace();
}
assertNotNull(first);
assertFalse(first.isLocked());
assertEquals(coord, first.getLocation());
assertEquals("First Message", first.getMessage());
assertEquals(testUser.getUsername(), first.getUser());
assertNull(first.getPhoto());
assertNotNull(second);
assertFalse(second.isLocked());
assertEquals(coord, second.getLocation());
assertEquals("Second Message", second.getMessage());
assertEquals(testUser.getUsername(), second.getUser());
assertNull(second.getPhoto());
}
/**
* Tests that trying to post a pin with null coordinates fails.
*/
@Test
public void testNullCoord() {
Pin nullCoordPin = pinWriter.postPin(null, "Sooooo null", null);
assertNull(nullCoordPin);
}
/**
* Tests that trying to post a pin with a null message fails.
*/
@Test
public void testNullMessage() {
LatLng coord = new LatLng(53.22, 56.22);
Pin nullMessagePin = pinWriter.postPin(coord, null, null);
assertNull(nullMessagePin);
}
/**
* Tests that unlocking a single pin works correctly.
*/
@Test
public void testSingleUnlock() {
// Get a different user to post the Pin
ParseUser postUser = switchToPostUser();
assertNotNull(postUser);
// Create the Pin
String message = "Unlock Me!";
LatLng coord = new LatLng(38.55, -47.885);
Pin pin = pinWriter.postPin(coord, message, null);
assertNotNull(pin);
// Create a locked version for the test user to unlock
Pin lockedPin = getLockedVersionOfPin(pin);
// Add the created Pin to the list so it can be
// removed at the end of the test.
try {
createdObjs.add(query.get(pin.getPinId()));
} catch (ParseException e) {
e.printStackTrace();
}
// Switch back to the test user to unlock the pin
assertTrue(switchToTestUser());
// Check that the pin is locked
assertNotNull(lockedPin);
assertTrue(lockedPin.isLocked());
// Do the unlocking and check that it worked
Pin unlockedPin = pinWriter.unlockPin(lockedPin);
assertNotNull(unlockedPin);
assertFalse(unlockedPin.isLocked());
}
/**
* Tests that unlocking multiple pins in a row works correctly.
*/
@Test
public void testMultiUnlock() {
// Get a different user to post the Pin
ParseUser postUser = switchToPostUser();
assertNotNull(postUser);
// Create the Pins
LatLng coord1 = new LatLng(25.225, 56.553);
LatLng coord2 = new LatLng(23.455, 57.898);
LatLng coord3 = new LatLng(26.999, 58.550);
Pin pin1 = pinWriter.postPin(coord1, "Pin1", null);
Pin pin2 = pinWriter.postPin(coord2, "Pin2", null);
Pin pin3 = pinWriter.postPin(coord3, "Pin3", null);
assertNotNull(pin1);
assertNotNull(pin2);
assertNotNull(pin3);
// Create locked versions for the test user to unlock
Pin lockedPin1 = getLockedVersionOfPin(pin1);
Pin lockedPin2 = getLockedVersionOfPin(pin2);
Pin lockedPin3 = getLockedVersionOfPin(pin3);
// Add the created Pins to the list so they can be
// removed at the end of the test
try {
createdObjs.add(query.get(pin1.getPinId()));
createdObjs.add(query.get(pin2.getPinId()));
createdObjs.add(query.get(pin3.getPinId()));
} catch (ParseException e) {
e.printStackTrace();
}
// Switch back to the test user to unlock the pins
assertTrue(switchToTestUser());
// Check that the pins are locked
assertNotNull(lockedPin1);
assertTrue(lockedPin1.isLocked());
assertNotNull(lockedPin2);
assertTrue(lockedPin2.isLocked());
assertNotNull(lockedPin3);
assertTrue(lockedPin3.isLocked());
// Do the unlocking and check that it worked
Pin uPin1 = pinWriter.unlockPin(lockedPin1);
assertNotNull(uPin1);
assertFalse(uPin1.isLocked());
Pin uPin2 = pinWriter.unlockPin(lockedPin2);
assertNotNull(uPin2);
assertFalse(uPin2.isLocked());
Pin uPin3 = pinWriter.unlockPin(lockedPin3);
assertNotNull(uPin3);
assertFalse(uPin3.isLocked());
}
/**
* Tests that unlocking a null pin fails.
*/
@Test
public void testNullUnlock() {
assertNull(pinWriter.unlockPin(null));
}
/**
* Switches to a different user in order to have a different user post a
* Pin than the testUser.
* @return a user suitable for posting Pins (different from testUser)
*/
private ParseUser switchToPostUser() {
ParseUser.logOut();
ParseUser postUser = new ParseUser();
postUser.setEmail(PARSE_USER_EMAIL_2);
postUser.setUsername(PARSE_USERNAME_2);
postUser.setPassword(PARSE_PASSWORD_2);
try {
postUser.signUp();
} catch (ParseException e) {
if (e.getCode() != ParseException.USERNAME_TAKEN) {
e.printStackTrace();
return null;
}
}
try {
ParseUser.logIn(PARSE_USERNAME_2, PARSE_PASSWORD_2);
} catch (ParseException e) {
e.printStackTrace();
return null;
}
return postUser;
}
/**
* Logs out the current user and switches to the testUser.
* @return true if the testUser was successfully logged in, false otherwise
*/
private boolean switchToTestUser() {
ParseUser.logOut();
try {
ParseUser.logIn(PARSE_USERNAME, PARSE_PASSWORD);
} catch (ParseException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* Returns a locked version of the given Pin.
* @param pin The Pin to get a locked version of
* @return A copy of the given Pin marked as locked
*/
private Pin getLockedVersionOfPin(Pin pin) {
return new Pin(true, pin.getLocation(), pin.getUser(),
pin.getFacebookID(), pin.getPinId(), pin.getMessage(),
pin.getPhoto());
}
}