GenericSyncService { public T sync(T model, String syncPath) throws IOException, JSONException { try { Map<String, String> requestParameters = new HashMap<String, String>(); mediaSyncHelper.addMultiMediaFilesToTheRequestParameters(model, requestParameters); removeUnusedParametersBeforeSync(model); model = model.isNew() ? entityHttpDao.create(model, syncPath, requestParameters) : entityHttpDao.update(model, syncPath, requestParameters); setAttributes(model); model.remove(History.HISTORIES); repository.createOrUpdateWithoutHistory(model); setMedia(model); } catch (Exception e) { model.setSynced(false); model.setSyncLog(e.getMessage()); model.put("photo_keys", photoKeys); model.put("audio_attachments", audioAttachments); repository.createOrUpdateWithoutHistory(model); repository.close(); throw new SyncFailedException(e.getMessage()); } return model; } GenericSyncService(MediaSyncHelper mediaSyncHelper, EntityHttpDao<T> entityHttpDao, Repository<T> repository); T sync(T model, String syncPath); static void setAttributes(BaseModel model);  }
@Test public void shouldMarkChildAsSyncedWhenSyncing() throws IOException, JSONException, GeneralSecurityException { getFakeHttpLayer().setDefaultHttpResponse(201, "{}"); Child child = genericSyncService.sync(new Child(), ""); assertThat(child.isSynced(), is(true)); }
@Test public void shouldCreateOrUpdateChildWithoutHistoryWhenSyncing() throws IOException, JSONException, GeneralSecurityException { getFakeHttpLayer().setDefaultHttpResponse(201, "{}"); Child child = genericSyncService.sync(new Child(), ""); verify(repository).createOrUpdateWithoutHistory(child); }
@Test(expected = SyncFailedException.class) public void shouldThrowSyncFailedExceptionWhenSyncFailure() throws Exception { Child child = new Child(); getFakeHttpLayer().setDefaultHttpResponse(503, "error"); genericSyncService.sync(child, ""); }
@Test public void shouldSyncUsingTheProvidedPath() throws Exception { Child child = new Child("id1", "user1", "{ 'test1' : 'value1' }"); child.put(Database.ChildTableColumn.internal_id.getColumnName(), "xyz"); getFakeHttpLayer().addHttpResponseRule("http: genericSyncService.sync(child, "/api/children/xyz"); }
@Test public void shouldCreateNewChildIfThereIsNoID() throws Exception { Child child = new Child("id1", "user1", "{ 'test1' : 'value1' }"); getFakeHttpLayer().addHttpResponseRule("http: child = genericSyncService.sync(child, "/api/children"); verify(repository).createOrUpdateWithoutHistory(child); }
@Test public void shouldAddPhotoKeysToParam() throws JSONException, IOException, GeneralSecurityException, HttpException { getFakeHttpLayer().setDefaultHttpResponse(201, RESPONSE); List<String> photoKeysList = Arrays.asList("photo-998877", "photo-998547", "abcd123", "1234ABC"); Child child = new Child("id1", "user1", String.format("{ '_id' : 'abcdef', 'name' : 'child1', 'test2' : 0, 'current_photo_key' : '1234ABC', 'photo_keys' : %s}", new JSONArray(photoKeysList).toString())); EntityHttpDao<Child> httpDao = new EntityHttpDao<Child>(application, "", "", "child"); EntityHttpDao<Child> spyHttpDao = spy(httpDao); doReturn(child).when(spyHttpDao).update(any(Child.class), any(String.class), any(Map.class)); new GenericSyncService<Child>(mediaSyncHelper, spyHttpDao, repository).sync(child, ""); verify(spyHttpDao).update(any(Child.class), any(String.class), argThat(new ContainsPhotoKeysParams("abcd123", "1234ABC"))); }
@Test public void shouldNotAddPhotoParamIfThePhotoNameIsPresentInPhotoKeys() throws JSONException, IOException, GeneralSecurityException { RapidFtrApplication context = mockContext(); String photoKeys = new JSONArray(Arrays.asList("photo-998877", "photo-998547", "1234ABC")).toString(); String childDetails = String.format("{ 'name' : 'child1', 'test2' : 0, 'current_photo_key' : '1234ABC', 'photo_keys' : %s}", photoKeys); Child child = new Child("id1", "user1", childDetails); AudioCaptureHelper audioCaptureHelper = new AudioCaptureHelper(context); audioCaptureHelper.saveAudio(child, new ByteArrayInputStream("OK".getBytes())); byte[] content = "Testing".getBytes(); PhotoCaptureHelper photoCaptureHelper = new PhotoCaptureHelper(context); photoCaptureHelper.savePhoto(BitmapFactory.decodeByteArray(content, 0, content.length), 10, "photo-998877"); photoCaptureHelper.savePhoto(BitmapFactory.decodeByteArray(content, 0, content.length), 10, "photo-998547"); photoCaptureHelper.savePhoto(BitmapFactory.decodeByteArray(content, 0, content.length), 10, "1234ABC"); getFakeHttpLayer().addHttpResponseRule("http: getFakeHttpLayer().hasRequestMatchingRule(new FakeHttpLayer.RequestMatcherBuilder().param("current_photo_key", "1234ABC")); genericSyncService.sync(child, "api/children"); }
@Test public void shouldAddAudioRecordedIfCreatedOnTheMobile() throws JSONException, IOException { RapidFtrApplication context = mockContext(); String response = "{'_id': 'testing', 'name' : 'child1', 'recorded_audio' : '123456'}"; Child child = new Child("id", "user", "{'name' : 'child1', 'recorded_audio' : '123455'}"); getFakeHttpLayer().addHttpResponseRule("http: getFakeHttpLayer().addHttpResponseRule("http: AudioCaptureHelper audioCaptureHelper = new AudioCaptureHelper(context); audioCaptureHelper.saveAudio(child, new ByteArrayInputStream("OK".getBytes())); genericSyncService.sync(child, "api/children"); File file = audioCaptureHelper.getFile("123456", ""); String fileContent = CharStreams.toString(new InputStreamReader(new FileInputStream(file))); assertEquals("RECEIVED", fileContent); }
@Test public void shouldNotAddAudioRecordedToTheRequestIfItsAlreadyPresentInServer() throws JSONException, IOException, HttpException { getFakeHttpLayer().setDefaultHttpResponse(201, RESPONSE); Child child = new Child("id", "user", "{'_id' : 'abcd123488', 'name' : 'child1', 'recorded_audio' : '123455', 'audio_attachments' : {'original' : '123455', 'amr':'123455'}}"); EntityHttpDao<Child> httpDao = new EntityHttpDao<Child>(application, "", "", "child"); EntityHttpDao<Child> spyHttpDao = spy(httpDao); doReturn(child).when(spyHttpDao).update(any(Child.class), any(String.class), any(Map.class)); new GenericSyncService<Child>(mediaSyncHelper, spyHttpDao, repository).sync(child, "api/children"); verify(spyHttpDao).update(any(Child.class), any(String.class), argThat(new DoesntContainAudioKeyParams())); }
@Test public void shouldRemoveUnusedParametersBeforeSync() throws JSONException, IOException, GeneralSecurityException { RapidFtrApplication context = mockContext(); String photoKeys = new JSONArray(Arrays.asList("photo-998877", "photo-998547", "1234ABC")).toString(); String childDetails = String.format("{ 'name' : 'child1', 'test2' : 0, 'current_photo_key' : '1234ABC', 'recorded_audio' : '123455', 'audio_attachments' : {'original' : '123455', 'amr':'123455'}, 'photo_keys' : %s}", photoKeys); Child child = new Child("id", "user", childDetails); AudioCaptureHelper audioCaptureHelper = new AudioCaptureHelper(context); audioCaptureHelper.saveAudio(child, new ByteArrayInputStream("OK".getBytes())); byte[] content = "Testing".getBytes(); PhotoCaptureHelper photoCaptureHelper = new PhotoCaptureHelper(context); photoCaptureHelper.savePhoto(BitmapFactory.decodeByteArray(content, 0, content.length), 10, "photo-998877"); photoCaptureHelper.savePhoto(BitmapFactory.decodeByteArray(content, 0, content.length), 10, "photo-998547"); photoCaptureHelper.savePhoto(BitmapFactory.decodeByteArray(content, 0, content.length), 10, "1234ABC"); getFakeHttpLayer().addHttpResponseRule("http: genericSyncService.sync(child, "api/children"); assertThat(child.optString("photo_keys"), is("")); assertThat(child.optString("audio_attachments"), is("")); assertThat(child.optString("synced"), is("")); }
@Test public void shouldUpdateChildAttributesAfterSync() throws IOException, JSONException { RapidFtrApplication context = mockContext(); String response = "{\"separation_place\":\"\",\"wishes_address_3\":\"\",\"care_arrangments_name\":\"\",\"other_family\":\"\",\"care_arrangements_knowsfamily\":\"\",\"created_at\":\"2012-12-14 10:57:39UTC\",\"wishes_contacted_details\":\"\",\"posted_from\":\"Browser\",\"care_arrangements_relationship\":\"\",\"interviewer\":\"\",\"birthplace\":\"\",\"father_death_details\":\"\",\"mothers_name\":\"\",\"name\":\"kavitha working\",\"other_child_2_relationship\":\"\",\"other_child_1\":\"\",\"other_child_1_dob\":\"\",\"other_child_2_telephone\":\"\",\"caregivers_name\":\"\",\"other_child_3_dob\":\"\",\"concerns_medical_case\":\"\",\"names_origin\":\"\",\"gender\":\"\",\"unique_identifier\":\"8a126c33-d2e3-4802-8698-19c06f52d5d1\",\"is_caregiver_alive\":\"\",\"wishes_contacted\":\"\",\"other_child_3_address\":\"\",\"evacuation_from\":\"\",\"photo_keys\":[],\"address\":\"\",\"disclosure_other_orgs\":\"\",\"concerns_other\":\"\",\"histories\":[],\"wishes_wants_contact\":\"\",\"wishes_telephone_1\":\"\",\"posted_at\":\"2012-12-14 10:57:39UTC\",\"other_child_1_address\":\"\",\"other_child_3_birthplace\":\"\",\"other_child_3_relationship\":\"\",\"languages\":\"\",\"concerns_followup_details\":\"\",\"other_org_interview_status\":\"\",\"concerns_further_info\":\"\",\"concerns_needs_followup\":\"\",\"disclosure_public_photo\":\"\",\"wishes_name_1\":\"\",\"created_by\":\"rapidftr\",\"other_org_date\":\"\",\"wishes_address_1\":\"\",\"is_mother_alive\":\"\",\"other_child_1_relationship\":\"\",\"other_child_1_telephone\":\"\",\"interview_place\":\"\",\"evacuation_date\":\"\",\"evacuation_status\":\"\",\"other_child_2\":\"\",\"c206ec4e\":\"\",\"other_child_2_dob\":\"\",\"interviewers_org\":\"\",\"dob_or_age\":\"\",\"id_document\":\"\",\"care_arrangements_arrival_date\":\"\",\"rc_id_no\":\"\",\"care_arrangements_came_from\":\"\",\"protection_status\":\"\",\"other_org_place\":\"\",\"separation_date\":\"\",\"created_organisation\":\"N/A\",\"mother_death_details\":\"\",\"concerns_girl_mother\":\"\",\"e96c289e\":\"\",\"orther_org_reference_no\":\"\",\"_rev\":\"1-ec347c93b262e7db0e306b77f22c2e19\",\"evacuation_to\":\"\",\"disclosure_authorities\":\"\",\"c9fc0344\":\"\",\"wishes_telephone_2\":\"\",\"interview_date\":\"\",\"telephone\":\"\",\"evacuation_agent\":\"\",\"additional_tracing_info\":\"\",\"couchrest-type\":\"Child\",\"care_arrangements\":\"\",\"other_child_2_birthplace\":\"\",\"disclosure_public_relatives\":\"\",\"other_child_2_address\":\"\",\"wishes_name_2\":\"\",\"current_photo_key\":\"\",\"disclosure_public_name\":\"\",\"separation_details\":\"\",\"interview_subject_details\":\"\",\"wishes_address_2\":\"\",\"concerns_abuse_situation\":\"\",\"063c3784\":\"\",\"concerns_street_child\":\"\",\"other_child_3\":\"\",\"interview_subject\":\"\",\"care_arrangements_address\":\"\",\"documents\":\"\",\"other_child_1_birthplace\":\"\",\"fef83a5e\":\"\",\"is_father_alive\":\"\",\"created_by_full_name\":\"RapidFTR\",\"characteristics\":\"\",\"care_arrangements_familyinfo\":\"\",\"disclosure_deny_details\":\"\",\"other_org_name\":\"\",\"nationality\":\"\",\"short_id\":\"f52d5d1\",\"concerns_chh\":\"\",\"concerns_vulnerable_person\":\"\",\"wishes_telephone_3\":\"\",\"concerns_disabled\":\"\",\"fathers_name\":\"\",\"_id\":\"0369c92c8e2245e680dc9a580202e285\",\"other_org_country\":\"\",\"ethnicity_or_tribe\":\"\",\"care_arrangements_other\":\"\",\"wishes_name_3\":\"\"}"; getFakeHttpLayer().setDefaultHttpResponse(200, response); Child child = new Child("id", "user", "{ 'name' : 'child1'}"); Child syncedChild = genericSyncService.sync(child, ""); assertThat(syncedChild.isSynced(), is(true)); assertThat(syncedChild.getString("last_synced_at"), not(is(nullValue()))); assertThat(syncedChild.getString("_attachments"), is(nullValue())); }
@Test public void shouldSetMediaIfNotAlreadyExistingOnTheMobile() throws JSONException, IOException { RapidFtrApplication context = mockContext(); String response = "{\"recorded_audio\":\"audio-12321\",\"photo_keys\": [\"photo-998\",\"photo-888\", \"photo-777\"],\"_id\":\"abcd\",\"current_photo_key\": \"photo-888\",\"separation_place\":\"\",\"wishes_address_3\":\"\",\"care_arrangments_name\":\"\",\"other_family\":\"\",\"care_arrangements_knowsfamily\":\"\",\"created_at\":\"2012-12-14 10:57:39UTC\",\"wishes_contacted_details\":\"\",\"posted_from\":\"Browser\"}"; MediaSyncHelper spyMediaHelper = spy(new MediaSyncHelper(childHttpDao, context)); GenericSyncService syncService = new GenericSyncService<Child>(spyMediaHelper, childHttpDao, repository); getFakeHttpLayer().setDefaultHttpResponse(200, response); Child child = new Child("id", "user", "{ 'name' : 'child1'}"); doNothing().when(spyMediaHelper).getPhotoFromServer(Matchers.any(Child.class), Matchers.any(PhotoCaptureHelper.class), eq("photo-998")); doNothing().when(spyMediaHelper).getPhotoFromServer(Matchers.any(Child.class), Matchers.any(PhotoCaptureHelper.class), eq("photo-888")); doNothing().when(spyMediaHelper).getPhotoFromServer(Matchers.any(Child.class), Matchers.any(PhotoCaptureHelper.class), eq("photo-777")); syncService.sync(child, ""); verify(spyMediaHelper).getPhotoFromServer(Matchers.any(Child.class), Matchers.any(PhotoCaptureHelper.class), eq("photo-888")); verify(spyMediaHelper).getPhotoFromServer(Matchers.any(Child.class), Matchers.any(PhotoCaptureHelper.class), eq("photo-998")); verify(spyMediaHelper).getPhotoFromServer(Matchers.any(Child.class), Matchers.any(PhotoCaptureHelper.class), eq("photo-777")); }
@Test public void shouldMarkUnverifiedChildAsSyncedOnceSuccessfullySynced() throws Exception { getFakeHttpLayer().addHttpResponseRule("http: Child child = new Child(); given(currentUser.isVerified()).willReturn(false); child = genericSyncService.sync(child, "api/children/unverified"); assertThat(child.isSynced(), is(true)); }
@Test public void shouldRemoveHistoriesAfterSuccessfulSync() throws Exception { Child childSpy = spy(new Child("{\"_id\" : \"couch_id\", \"child_name\":\"subhas\",\"unique_identifier\":\"78223s4h1e468f5200edc\"}")); doReturn(false).when(childSpy).isNew(); childHttpDao = mock(EntityHttpDao.class); doReturn(childSpy).when(childHttpDao).update(eq(childSpy), anyString(), any(Map.class)); GenericSyncService<Child> syncService = new GenericSyncService<Child>(mediaSyncHelper, childHttpDao, repository); syncService.sync(childSpy, ""); verify(childSpy).remove(History.HISTORIES); }
@Test(expected = SyncFailedException.class) public void shouldNotRemoveHistoriesAfterFailedSync() throws Exception { Child childSpy = spy(new Child("{\"_id\" : \"couch_id\", \"child_name\":\"subhas\",\"unique_identifier\":\"78223s4h1e468f5200edc\"}")); doReturn(false).when(childSpy).isNew(); childHttpDao = mock(EntityHttpDao.class); doThrow(new HTTPException(404)).when(childHttpDao).update(eq(childSpy), anyString(), any(Map.class)); new GenericSyncService<Child>(mediaSyncHelper, childHttpDao, repository).sync(childSpy, ""); verify(childSpy, never()).remove(History.HISTORIES); }