package com.rapidftr.repository;
import android.content.ContentValues;
import android.database.Cursor;
import com.rapidftr.CustomTestRunner;
import com.rapidftr.RapidFtrApplication;
import com.rapidftr.database.Database;
import com.rapidftr.database.DatabaseSession;
import com.rapidftr.database.ShadowSQLiteHelper;
import com.rapidftr.model.Child;
import com.rapidftr.model.Enquiry;
import com.rapidftr.model.History;
import com.rapidftr.model.User;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.skyscreamer.jsonassert.JSONAssert;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import static com.rapidftr.model.History.HISTORIES;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@RunWith(CustomTestRunner.class)
public class EnquiryRepositoryTest {
private DatabaseSession session;
private EnquiryRepository enquiryRepository;
private String user = "field worker";
private RapidFtrApplication rapidFtrApplication;
@Before
public void setUp() {
rapidFtrApplication = (RapidFtrApplication) Robolectric.getShadowApplication().getApplicationContext();
rapidFtrApplication.setCurrentUser(new User("userName", "password", true, "http://1.2.3.4"));
session = new ShadowSQLiteHelper("test_database").getSession();
enquiryRepository = new EnquiryRepository(user, session, rapidFtrApplication);
}
@Ignore
public void shouldCreateAnEnquiryInTheDatabase() throws JSONException, SQLException {
Enquiry enquiry = new Enquiry("{\"age\":14,\"name\":\"Subhas\"}", user);
enquiryRepository.createOrUpdate(enquiry);
assertEquals(1, enquiryRepository.size());
final Cursor cursor = session.rawQuery("SELECT criteria FROM enquiry WHERE id = ?", new String[]{enquiry.getUniqueId()});
cursor.moveToNext();
JSONObject criteria = new JSONObject(cursor.getString(0));
assertThat(criteria.length(), is(2));
assertThat(criteria.getInt("age"), is(14));
assertThat(criteria.getString("name"), is("Subhas"));
}
@Test
public void shouldCreateChildRecordAndSetCreatedAtHistory() throws Exception {
Enquiry enquiry = new Enquiry("{\"age\":14,\"name\":\"Subhas\"}", user);
enquiryRepository.createOrUpdate(enquiry);
JSONObject enquiryJsonValues = enquiryRepository.get(enquiry.getUniqueId()).values();
JSONArray histories = (JSONArray) enquiryJsonValues.get(History.HISTORIES);
JSONObject changes = (JSONObject) ((JSONObject) histories.get(0)).get("changes");
assert(((JSONObject) changes.get("enquiry")).has(History.CREATED));
}
@Test
public void shouldReturnAllEnquiries() throws Exception {
String enquiryJSON1 = "{\"enquirer_name\":\"sam fisher\",\"name\":\"foo bar\",\"nationality\":\"ugandan\"," +
"\"created_by\":\"Tom Reed\",\"synced\":\"false\", \"created_organisation\":\"TW\"}";
String enquiryJSON2 = "{\"enquirer_name\":\"fisher sam\",\"name\":\"bar foo\",\"nationality\":\"ugandan\"," +
"\"created_by\":\"Tom Reed\",\"synced\":\"false\", \"created_organisation\":\"TW\"}";
Enquiry enquiry1 = new Enquiry(enquiryJSON1);
enquiryRepository.createOrUpdate(enquiry1);
Enquiry enquiry2 = new Enquiry(enquiryJSON2);
enquiryRepository.createOrUpdate(enquiry2);
List<Enquiry> enquiries = enquiryRepository.all();
assertEquals(2, enquiryRepository.size());
compareEnquiries(enquiry1, enquiries.get(0));
compareEnquiries(enquiry2, enquiries.get(1));
}
@Test
public void shouldReturnAllEnquiriesCreatedByUser() throws JSONException {
String enquiryJSON1 = "{\"enquirer_name\":\"sam fisher\",\"name\":\"foo bar\",\"nationality\":\"ugandan\"," +
"\"created_by\":\"field worker\",\"synced\":\"false\", \"created_organisation\":\"TW\"}";
String enquiryJSON2 = "{\"enquirer_name\":\"fisher sam\",\"name\":\"bar foo\",\"nationality\":\"ugandan\"," +
"\"created_by\":\"Tom Reed\",\"synced\":\"false\", \"created_organisation\":\"TW\"}";
Enquiry enquiry1 = new Enquiry(enquiryJSON1);
enquiryRepository.createOrUpdate(enquiry1);
Enquiry enquiry2 = new Enquiry(enquiryJSON2);
enquiryRepository.createOrUpdate(enquiry2);
List<Enquiry> enquiries = enquiryRepository.allCreatedByCurrentUser();
assertEquals(2, enquiryRepository.size());
compareEnquiries(enquiry1, enquiries.get(0));
}
private void compareEnquiries(Enquiry enquiry1, Enquiry enquiry2) throws JSONException {
assertThat(enquiry1.getUniqueId(), is(enquiry2.getUniqueId()));
assertThat(enquiry1.getCreatedBy(), is(enquiry2.getCreatedBy()));
assertThat(enquiry1.getCreatedAt(), is(enquiry2.getCreatedAt()));
}
@Test
public void getShouldReturnEnquiryForId() throws Exception {
Enquiry enquiry1 = new Enquiry("{age:14,name:Subhas}", user);
String enquiryId = enquiry1.getUniqueId();
enquiryRepository.createOrUpdate(enquiry1);
Enquiry savedEnquiry = enquiryRepository.get(enquiryId);
savedEnquiry.remove("id");
JSONAssert.assertEquals(savedEnquiry.toString(), enquiry1.toString(), false);
}
@Test
public void toBeSyncedShouldReturnAListOfEnquiriesWithSyncedStatusFalse() throws Exception {
Enquiry enquiry1 = new Enquiry("{age:14,name:Subhas}", user);
enquiry1.setSynced(false);
enquiryRepository.createOrUpdate(enquiry1);
Enquiry enquiry2 = new Enquiry("{age:14,name:Subhas}", "field worker 2");
enquiry2.setSynced(true);
enquiryRepository.createOrUpdate(enquiry2);
final List<Enquiry> enquiries = enquiryRepository.toBeSynced();
assertThat(enquiries.size(), is(1));
assertThat(enquiries.get(0).getUniqueId(), is(enquiry1.getUniqueId()));
}
@Test
public void existsShouldReturnTrueGivenAnIdOfAnEnquiryThatAlreadyExists() throws Exception {
Enquiry enquiry1 = new Enquiry("{age:14,name:Subhas}", user);
enquiryRepository.createOrUpdate(enquiry1);
assertTrue(enquiryRepository.exists(enquiry1.getUniqueId()));
assertFalse(enquiryRepository.exists("100"));
}
@Test
public void getAllIdsAndRevs_shouldReturnIdsAndRevsForAllEnquiries() throws Exception {
Enquiry enquiry1 = new Enquiry("{age:14,name:Subhas}", user);
String enquiry1CouchId = UUID.randomUUID().toString();
String enquiry1CouchRev = UUID.randomUUID().toString();
enquiry1.put("_id", enquiry1CouchId);
enquiry1.put("_rev", enquiry1CouchRev);
enquiryRepository.createOrUpdate(enquiry1);
Enquiry enquiry2 = new Enquiry("{age:14,name:Subhas}", "field worker 2");
String enquiry2CouchId = UUID.randomUUID().toString();
String enquiry2CouchRev = UUID.randomUUID().toString();
enquiry2.put("_id", enquiry2CouchId);
enquiry2.put("_rev", enquiry2CouchRev);
enquiryRepository.createOrUpdate(enquiry2);
final HashMap<String, String> allIdsAndRevs = enquiryRepository.getAllIdsAndRevs();
assertThat(allIdsAndRevs.size(), is(2));
assertThat(allIdsAndRevs.get(enquiry1CouchId), is(enquiry1CouchRev));
assertThat(allIdsAndRevs.get(enquiry2CouchId), is(enquiry2CouchRev));
}
@Test
public void updateShouldUpdateTheFieldsOfAnEnquiry() throws Exception {
String enquiryJSON = "{\n" +
"\"createdBy\":\"user\",\n" +
"\"enquirer_name\":\"faris\",\n" +
"\"criteria\":{\"age\":14, \"name\": \"Subhas\"},\n" +
"\"synced\":\"true\",\n" +
"\"created_by\":\"some guy\"" +
"}";
Enquiry enquiry = new Enquiry(enquiryJSON);
enquiryRepository.createOrUpdate(enquiry);
assertThat(enquiryRepository.all().size(), is(1));
enquiry.put("enquirer_name", "New Reporter Name");
enquiry.setCreatedBy("NEW USER");
enquiry.setSynced(true);
enquiry.put(Database.EnquiryTableColumn.internal_id.getColumnName(), "new internal id");
enquiry.put(Database.EnquiryTableColumn.internal_rev.getColumnName(), "new internal revision");
enquiryRepository.createOrUpdateWithoutHistory(enquiry);
Enquiry retrieved = enquiryRepository.all().get(0);
assertThat(retrieved.optString("enquirer_name"), is("New Reporter Name"));
assertThat(retrieved.getCreatedBy().toString(), is("NEW USER"));
assertTrue(retrieved.isSynced());
assertThat(retrieved.getString(Database.EnquiryTableColumn.internal_id.getColumnName()), is("new internal id"));
assertThat(retrieved.getString(Database.EnquiryTableColumn.internal_rev.getColumnName()), is("new internal revision"));
}
@Test
public void createOrUpdateShouldAddHistory() throws Exception {
Enquiry enquiry = new Enquiry("{\n" +
"\"createdBy\":\"user\",\n" +
"\"enquirer_name\":\"faris\",\n" +
"\"criteria\":{\"age\":14, \"name\": \"Subhas\"},\n" +
"\"synced\":\"true\",\n" +
"\"created_by\":\"some guy\"" +
"}");
enquiryRepository.createOrUpdate(enquiry);
enquiry.put("enquirer_name", "New Reporter Name");
enquiryRepository.createOrUpdate(enquiry);
JSONObject enquiryJsonValues = enquiryRepository.get(enquiry.getUniqueId()).values();
assertTrue(enquiryJsonValues.has(History.HISTORIES));
}
@Test
public void updateShouldAddHistory() throws Exception {
Enquiry enquiry = new Enquiry("{\n" +
"\"createdBy\":\"user\",\n" +
"\"enquirer_name\":\"faris\",\n" +
"\"criteria\":{\"age\":14, \"name\": \"Subhas\"},\n" +
"\"synced\":\"true\",\n" +
"\"created_by\":\"some guy\"" +
"}");
enquiryRepository.createOrUpdate(enquiry);
enquiry.put("enquirer_name", "New Reporter Name");
enquiryRepository.createOrUpdate(enquiry);
JSONObject enquiryJsonValues = enquiryRepository.get(enquiry.getUniqueId()).values();
assertTrue(enquiryJsonValues.has(History.HISTORIES));
}
@Test(expected = android.database.SQLException.class)
public void shouldReturnFailedToSaveEnquiryExceptionWhenSavingEnquiryWithData() throws
SQLException, JSONException {
String enquiryJSON = "{\n" +
"\"created_by\":\"user\",\n" +
"\"synced\":\"true\",\n" +
"}";
ContentValues contentValues = new ContentValues();
contentValues.put("created_by", "some user");
Enquiry enquiry = new Enquiry(enquiryJSON);
EnquiryRepository enquiryRepository1 = spy(enquiryRepository);
when(enquiryRepository1.getContentValuesFrom(enquiry)).thenReturn(contentValues);
enquiryRepository1.createOrUpdate(enquiry);
}
@Test
public void shouldAnEnquiryUsingInternalIds() throws JSONException {
String enquiryJSON = "{\n" +
"\"synced\":\"true\",\n" +
"\"_id\":\"enquiry_id_1\",\n" +
"\"created_by\":\"some guy\"" +
"}";
Enquiry enquiry = new Enquiry(enquiryJSON);
enquiryRepository.createOrUpdate(enquiry);
List<String> ids = new ArrayList<String>();
ids.add("enquiry_id_1");
List<Enquiry> enquiries = enquiryRepository.getAllWithInternalIds(ids);
assertThat(enquiries.size(), is(1));
assertThat(enquiries.get(0).getUniqueId(), is(enquiry.getUniqueId()));
}
@Test
public void shouldReturnAllWithInternalIds() throws JSONException {
String enquiryJSON = "{\n" +
"\"synced\":\"true\",\n" +
"\"_id\":\"enquiry_id_1\",\n" +
"\"created_by\":\"some guy\"" +
"}";
Enquiry enquiry1 = new Enquiry(enquiryJSON);
enquiryRepository.createOrUpdate(enquiry1);
String enquiryJSON2 = "{\n" +
"\"synced\":\"true\",\n" +
"\"_id\":\"enquiry_id_2\",\n" +
"\"created_by\":\"some guy\"" +
"}";
Enquiry enquiry2 = new Enquiry(enquiryJSON2);
enquiryRepository.createOrUpdate(enquiry2);
String enquiryJSON3 = "{\n" +
"\"synced\":\"true\",\n" +
"\"_id\":\"enquiry_id_3\",\n" +
"\"created_by\":\"some guy\"" +
"}";
Enquiry enquiry3 = new Enquiry(enquiryJSON3);
enquiryRepository.createOrUpdate(enquiry3);
List<String> ids = new ArrayList<String>();
ids.add("enquiry_id_1");
ids.add("enquiry_id_3");
List<Enquiry> enquiries = enquiryRepository.getAllWithInternalIds(ids);
assertThat(enquiries.size(), is(2));
assertThat(enquiries.get(0).getUniqueId(), is(enquiry1.getUniqueId()));
assertThat(enquiries.get(1).getUniqueId(), is(enquiry3.getUniqueId()));
}
@Test
public void shouldCreateNewEnquiryWithoutHistory() throws JSONException {
Enquiry enquiry = new Enquiry("{\n" +
"\"synced\":\"true\",\n" +
"\"_id\":\"enquiry_id_3\",\n" +
"\"created_by\":\"some guy\"" +
"}");
enquiryRepository.createOrUpdateWithoutHistory(enquiry);
Enquiry savedEnquiry = enquiryRepository.get(enquiry.getUniqueId());
assertNotNull(savedEnquiry);
assertFalse(savedEnquiry.has(HISTORIES));
}
@Test
public void shouldUpdateExistingChildWithoutHistory() throws JSONException {
Enquiry enquiry = new Enquiry("{\n" +
"\"synced\":\"true\",\n" +
"\"_id\":\"enquiry_id_3\",\n" +
"\"created_by\":\"some guy\"" +
"}"); enquiryRepository.createOrUpdateWithoutHistory(enquiry);
enquiry.put("more_stuff", "some_more_stuff");
enquiryRepository.createOrUpdateWithoutHistory(enquiry);
Enquiry savedEnquiry = enquiryRepository.get(enquiry.getUniqueId());
assertNotNull(savedEnquiry);
assertFalse(savedEnquiry.has(HISTORIES));
assertEquals("some_more_stuff", savedEnquiry.get("more_stuff"));
}
@Test
public void shouldReturnFirstPage() throws JSONException {
session = mock(DatabaseSession.class);
enquiryRepository = spy(new EnquiryRepository("user1", session, rapidFtrApplication));
doReturn(new ArrayList<Child>()).when(enquiryRepository).toEnquiries(any(Cursor.class));
enquiryRepository.getRecordsForFirstPage();
String sql = "SELECT enquiry_json, synced FROM enquiry WHERE created_by ='user1' ORDER BY id LIMIT 30";
verify(session, times(1)).rawQuery(sql, null);
}
@Test
public void shouldReturnRecordsBetweenSpecifiedLimits() throws JSONException {
session = mock(DatabaseSession.class);
enquiryRepository = spy(new EnquiryRepository("user1", session, rapidFtrApplication));
doReturn(new ArrayList<Child>()).when(enquiryRepository).toEnquiries(any(Cursor.class));
enquiryRepository.getRecordsBetween(1, 10);
String sql = "SELECT enquiry_json, synced FROM enquiry WHERE created_by='user1' ORDER BY id LIMIT 9 OFFSET 10";
verify(session, times(1)).rawQuery(sql, null);
}
}