Skip to content
This repository was archived by the owner on May 5, 2021. It is now read-only.

Commit 828225d

Browse files
author
FredrikSchäferVitagroup
committed
SORMAS-Foundation#3294 Fix ExternalJournalServiceTest
1 parent 161583b commit 828225d

6 files changed

Lines changed: 141 additions & 71 deletions

File tree

sormas-api/src/main/java/de/symeda/sormas/api/person/JournalPersonDto.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import java.io.Serializable;
88
import java.util.Date;
9+
import java.util.Objects;
910

1011
import de.symeda.sormas.api.utils.PersonalData;
1112
import de.symeda.sormas.api.utils.SensitiveData;
@@ -132,4 +133,33 @@ public FollowUpStatus getFollowUpStatus() {
132133
public void setFollowUpStatus(FollowUpStatus followUpStatus) {
133134
this.followUpStatus = followUpStatus;
134135
}
136+
137+
@Override
138+
public String toString() {
139+
return uuid + ' ' + firstName + ' ' + lastName;
140+
}
141+
142+
@Override
143+
public boolean equals(Object o) {
144+
if (this == o) return true;
145+
if (o == null || getClass() != o.getClass()) return false;
146+
JournalPersonDto that = (JournalPersonDto) o;
147+
return pseudonymized == that.pseudonymized &&
148+
Objects.equals(uuid, that.uuid) &&
149+
Objects.equals(firstName, that.firstName) &&
150+
Objects.equals(lastName, that.lastName) &&
151+
Objects.equals(emailAddress, that.emailAddress) &&
152+
Objects.equals(phone, that.phone) &&
153+
Objects.equals(birthdateDD, that.birthdateDD) &&
154+
Objects.equals(birthdateMM, that.birthdateMM) &&
155+
Objects.equals(birthdateYYYY, that.birthdateYYYY) &&
156+
sex == that.sex &&
157+
Objects.equals(latestFollowUpEndDate, that.latestFollowUpEndDate) &&
158+
followUpStatus == that.followUpStatus;
159+
}
160+
161+
@Override
162+
public int hashCode() {
163+
return Objects.hash(uuid, pseudonymized, firstName, lastName, emailAddress, phone, birthdateDD, birthdateMM, birthdateYYYY, sex, latestFollowUpEndDate, followUpStatus);
164+
}
135165
}

sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactFacadeEjb.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import javax.persistence.criteria.Subquery;
6060
import javax.validation.constraints.NotNull;
6161

62+
import de.symeda.sormas.api.person.JournalPersonDto;
6263
import org.apache.commons.collections.CollectionUtils;
6364
import org.slf4j.Logger;
6465
import org.slf4j.LoggerFactory;
@@ -323,8 +324,8 @@ private void handleExternalJournalPerson(ContactDto updatedContact) {
323324
* The .getPersonForJournal(...) here gets the person in the state it is (most likely) known to an external journal.
324325
* Changes of related data is assumed to be not yet persisted in the database.
325326
*/
326-
Runnable notify =
327-
() -> externalJournalService.notifyExternalJournalPersonUpdate(personFacade.getPersonForJournal(updatedContact.getPerson().getUuid()));
327+
JournalPersonDto existingPerson = personFacade.getPersonForJournal(updatedContact.getPerson().getUuid());
328+
Runnable notify = () -> externalJournalService.notifyExternalJournalPersonUpdate(existingPerson);
328329
executorService.schedule(notify, 5, TimeUnit.SECONDS);
329330
}
330331

sormas-backend/src/main/java/de/symeda/sormas/backend/externaljournal/ExternalJournalService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,8 @@ public void notifyExternalJournalFollowUpUntilUpdate(ContactDto contact, Date pr
201201
* @return true if the person data change was considered relevant for external journals, false otherwise.
202202
*
203203
*/
204-
public void notifyExternalJournalPersonUpdate(JournalPersonDto existingJournalPerson) {
204+
public boolean notifyExternalJournalPersonUpdate(JournalPersonDto existingJournalPerson) {
205+
boolean shouldNotify = shouldNotify(existingJournalPerson);
205206
if (shouldNotify(existingJournalPerson)) {
206207
if (configFacade.getSymptomJournalConfig().getUrl() != null) {
207208
notifySymptomJournal(existingJournalPerson.getUuid());

sormas-backend/src/main/java/de/symeda/sormas/backend/person/PersonFacadeEjb.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,6 @@
5252
import de.symeda.sormas.api.caze.CaseOutcome;
5353
import de.symeda.sormas.api.contact.FollowUpStatus;
5454
import de.symeda.sormas.api.contact.FollowUpStatusDto;
55-
import de.symeda.sormas.api.externaljournal.ExternalPersonValidation;
56-
import de.symeda.sormas.api.followup.FollowUpDto;
5755
import de.symeda.sormas.api.externaljournal.PatientDiaryPersonValidation;
5856
import de.symeda.sormas.api.i18n.I18nProperties;
5957
import de.symeda.sormas.api.i18n.Validations;
@@ -65,7 +63,6 @@
6563
import de.symeda.sormas.api.person.PersonFacade;
6664
import de.symeda.sormas.api.person.PersonFollowUpEndDto;
6765
import de.symeda.sormas.api.person.PersonNameDto;
68-
import de.symeda.sormas.api.person.PersonQuarantineEndDto;
6966
import de.symeda.sormas.api.person.PersonReferenceDto;
7067
import de.symeda.sormas.api.person.PersonSimilarityCriteria;
7168
import de.symeda.sormas.api.person.PresentCondition;
@@ -338,7 +335,8 @@ private void handleExternalJournalPerson(PersonDto existingPerson, PersonDto upd
338335
* The .getPersonForJournal(...) here gets the person in the state it is (most likely) known to an external journal.
339336
* Changes of related data is assumed to be not yet persisted in the database.
340337
*/
341-
Runnable notify = () -> externalJournalService.notifyExternalJournalPersonUpdate(getPersonForJournal(existingPerson.getUuid()));
338+
JournalPersonDto existingJournalPerson = getPersonForJournal(existingPerson.getUuid());
339+
Runnable notify = () -> externalJournalService.notifyExternalJournalPersonUpdate(existingJournalPerson);
342340
executorService.schedule(notify, 5, TimeUnit.SECONDS);
343341
}
344342

@@ -820,6 +818,11 @@ public static PersonDto toDto(Person source) {
820818
return target;
821819
}
822820

821+
// needed for tests
822+
public void setExternalJournalService(ExternalJournalService externalJournalService) {
823+
this.externalJournalService = externalJournalService;
824+
}
825+
823826
@LocalBean
824827
@Stateless
825828
public static class PersonFacadeEjbLocal extends PersonFacadeEjb {

sormas-backend/src/test/java/de/symeda/sormas/backend/AbstractBeanTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@
2323
import javax.persistence.EntityManager;
2424
import javax.persistence.Query;
2525

26-
import de.symeda.sormas.api.region.CountryFacade;
27-
import de.symeda.sormas.backend.region.CountryFacadeEjb;
28-
import de.symeda.sormas.backend.region.CountryService;
29-
import de.symeda.sormas.backend.externaljournal.ExternalJournalService;
3026
import org.junit.Before;
3127

3228
import de.symeda.sormas.api.ConfigFacade;
@@ -60,6 +56,7 @@
6056
import de.symeda.sormas.api.outbreak.OutbreakFacade;
6157
import de.symeda.sormas.api.person.PersonFacade;
6258
import de.symeda.sormas.api.region.CommunityFacade;
59+
import de.symeda.sormas.api.region.CountryFacade;
6360
import de.symeda.sormas.api.region.DistrictFacade;
6461
import de.symeda.sormas.api.region.GeoShapeProvider;
6562
import de.symeda.sormas.api.region.RegionFacade;
@@ -106,6 +103,7 @@
106103
import de.symeda.sormas.backend.event.EventParticipantFacadeEjb.EventParticipantFacadeEjbLocal;
107104
import de.symeda.sormas.backend.event.EventParticipantService;
108105
import de.symeda.sormas.backend.event.EventService;
106+
import de.symeda.sormas.backend.externaljournal.ExternalJournalService;
109107
import de.symeda.sormas.backend.facility.FacilityFacadeEjb.FacilityFacadeEjbLocal;
110108
import de.symeda.sormas.backend.facility.FacilityService;
111109
import de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb.FeatureConfigurationFacadeEjbLocal;
@@ -120,6 +118,8 @@
120118
import de.symeda.sormas.backend.person.PersonService;
121119
import de.symeda.sormas.backend.region.CommunityFacadeEjb.CommunityFacadeEjbLocal;
122120
import de.symeda.sormas.backend.region.CommunityService;
121+
import de.symeda.sormas.backend.region.CountryFacadeEjb;
122+
import de.symeda.sormas.backend.region.CountryService;
123123
import de.symeda.sormas.backend.region.DistrictFacadeEjb.DistrictFacadeEjbLocal;
124124
import de.symeda.sormas.backend.region.DistrictService;
125125
import de.symeda.sormas.backend.region.GeoShapeProviderEjb.GeoShapeProviderEjbLocal;

sormas-backend/src/test/java/de/symeda/sormas/backend/externaljournal/ExternalJournalServiceTest.java

Lines changed: 95 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,60 @@
11
package de.symeda.sormas.backend.externaljournal;
22

3-
import de.symeda.sormas.api.externaljournal.PatientDiaryPersonQueryResponse;
4-
import de.symeda.sormas.api.person.PersonDto;
3+
import static org.junit.Assert.assertFalse;
4+
import static org.junit.Assert.assertTrue;
5+
import static org.mockito.Mockito.doReturn;
6+
import static org.mockito.Mockito.when;
57

6-
import de.symeda.sormas.api.person.Sex;
7-
import de.symeda.sormas.api.person.SymptomJournalStatus;
8-
import de.symeda.sormas.api.utils.DataHelper;
9-
import de.symeda.sormas.backend.AbstractBeanTest;
8+
import java.lang.reflect.InvocationTargetException;
9+
import java.lang.reflect.Method;
10+
import java.util.HashMap;
11+
import java.util.Optional;
1012

13+
import javax.persistence.EntityManager;
14+
import javax.persistence.EntityTransaction;
15+
16+
import de.symeda.sormas.api.person.JournalPersonDto;
1117
import org.junit.Before;
1218
import org.junit.Test;
19+
import org.mockito.Mockito;
1320
import org.mockito.MockitoAnnotations;
1421
import org.mockito.Spy;
1522

16-
import java.lang.reflect.InvocationTargetException;
17-
import java.lang.reflect.Method;
18-
import java.util.HashMap;
19-
import java.util.Map;
20-
import java.util.Optional;
23+
import de.symeda.sormas.api.externaljournal.PatientDiaryPersonQueryResponse;
24+
import de.symeda.sormas.api.person.PersonDto;
2125

22-
import static org.junit.Assert.assertFalse;
23-
import static org.junit.Assert.assertTrue;
24-
import static org.mockito.Mockito.doReturn;
26+
import de.symeda.sormas.api.person.PersonReferenceDto;
27+
import de.symeda.sormas.api.person.Sex;
28+
import de.symeda.sormas.api.person.SymptomJournalStatus;
29+
import de.symeda.sormas.api.user.UserDto;
30+
import de.symeda.sormas.api.user.UserRole;
31+
import de.symeda.sormas.backend.AbstractBeanTest;
32+
import de.symeda.sormas.backend.MockProducer;
33+
import de.symeda.sormas.backend.TestDataCreator;
34+
import de.symeda.sormas.backend.person.Person;
35+
import de.symeda.sormas.backend.person.PersonFacadeEjb.PersonFacadeEjbLocal;
36+
import de.symeda.sormas.backend.person.PersonService;
2537

2638
public class ExternalJournalServiceTest extends AbstractBeanTest {
2739

2840
@Spy
2941
private ExternalJournalService externalJournalService;
3042

43+
private UserDto natUser;
44+
private TestDataCreator.RDCF rdcf;
45+
3146
@Before
32-
public void setUp() {
47+
public void init() {
48+
super.init();
49+
natUser = creator.createUser("", "", "", "Nat", "Usr", UserRole.NATIONAL_USER);
50+
rdcf = creator.createRDCF("Region 1", "District 1", "Community 1", "Facility 1");
51+
when(MockProducer.getPrincipal().getName()).thenReturn("NatUsr");
52+
3353
MockitoAnnotations.initMocks(this);
3454
PatientDiaryPersonQueryResponse patientDiaryPersonQueryResponse = new PatientDiaryPersonQueryResponse();
3555
patientDiaryPersonQueryResponse.setCount(0);
36-
doReturn(Optional.ofNullable(patientDiaryPersonQueryResponse)).when(externalJournalService).queryPatientDiary("Email", "[email protected]");
37-
doReturn(Optional.ofNullable(patientDiaryPersonQueryResponse)).when(externalJournalService).queryPatientDiary("Email", "test@test");
38-
doReturn(Optional.ofNullable(patientDiaryPersonQueryResponse)).when(externalJournalService).queryPatientDiary("Email", "[email protected]");
39-
doReturn(Optional.ofNullable(patientDiaryPersonQueryResponse)).when(externalJournalService)
40-
.queryPatientDiary("Mobile phone", "+49 621 1218490");
41-
doReturn(Optional.ofNullable(patientDiaryPersonQueryResponse)).when(externalJournalService)
42-
.queryPatientDiary("Mobile phone", "+49 621 1218491");
43-
doReturn(Optional.ofNullable(patientDiaryPersonQueryResponse)).when(externalJournalService).queryPatientDiary("Mobile phone", "0");;
56+
doReturn(Optional.of(patientDiaryPersonQueryResponse)).when(externalJournalService)
57+
.queryPatientDiary(Mockito.any(String.class), Mockito.any(String.class));
4458
}
4559

4660
@Test
@@ -147,32 +161,26 @@ public void givenIncompleteBirthdateIsNotExportable() {
147161
* https://gitter.im/SORMAS-Project!
148162
*/
149163
public void givenRelevantChangeShouldNotify() {
164+
EntityManager entityManager = getEntityManager();
165+
PersonFacadeEjbLocal personFacade = (PersonFacadeEjbLocal) getPersonFacade();
166+
personFacade.setExternalJournalService(externalJournalService);
167+
PersonService personService = getPersonService();
150168

151-
// Define relevant properties
152-
HashMap<String, Object> relevantProperties = new HashMap<String, Object>() {
169+
Person person = personService.createPerson();
170+
setPersonRelevantFields(person);
153171

154-
{
155-
put("FirstName", "Klaus");
156-
put("LastName", "Draufle");
157-
put("Sex", Sex.MALE);
158-
put("EmailAddress", "[email protected]");
159-
put("Phone", "+496211218490");
160-
put("BirthdateYYYY", 2000);
161-
put("BirthdateMM", 6);
162-
put("BirthdateDD", 1);
163-
put("SymptomJournalStatus", SymptomJournalStatus.REGISTERED);
164-
}
165-
};
172+
// cannot use PersonFacade save since it also calls the method being tested
173+
EntityTransaction transaction = entityManager.getTransaction();
174+
transaction.begin();
175+
entityManager.persist(person);
176+
entityManager.flush();
177+
transaction.commit();
166178

167-
// Create two person with those properties
168-
PersonDto person = new PersonDto();
169-
PersonDto updatedPerson = new PersonDto();
170-
person.setUuid(DataHelper.createUuid());
171-
for (Map.Entry<String, Object> property : relevantProperties.entrySet()) {
172-
setPersonProperty(person, property.getKey(), property.getValue());
173-
setPersonProperty(updatedPerson, property.getKey(), property.getValue());
174-
}
175-
assertFalse(getExternalJournalService().notifyExternalJournalPersonUpdate(person, updatedPerson));
179+
// need to create a case with the person to avoid pseudonymization related errors
180+
creator.createCase(natUser.toReference(), new PersonReferenceDto(person.getUuid()), rdcf);
181+
JournalPersonDto journalPerson = personFacade.getPersonForJournal(person.getUuid());
182+
183+
assertFalse(getExternalJournalService().notifyExternalJournalPersonUpdate(journalPerson));
176184

177185
// Define relevant changes
178186
HashMap<String, Object> relevantChanges = new HashMap<String, Object>() {
@@ -188,44 +196,71 @@ public void givenRelevantChangeShouldNotify() {
188196
put("BirthdateDD", 2);
189197
}
190198
};
199+
191200
// Apply each change and make sure it makes notification considered necessary
192201
for (String propertyName : relevantChanges.keySet()) {
193-
setPersonProperty(updatedPerson, propertyName, relevantChanges.get(propertyName));
194-
assertTrue(getExternalJournalService().notifyExternalJournalPersonUpdate(person, updatedPerson));
202+
journalPerson = personFacade.getPersonForJournal(person.getUuid());
203+
setPersonProperty(person, propertyName, relevantChanges.get(propertyName));
204+
person = entityManager.merge(person);
205+
assertTrue(getExternalJournalService().notifyExternalJournalPersonUpdate(journalPerson));
195206

196207
// Modify the SymptomJournalStatus of the original person
197208
person.setSymptomJournalStatus(SymptomJournalStatus.DELETED);
198-
assertFalse(getExternalJournalService().notifyExternalJournalPersonUpdate(person, updatedPerson));
209+
person = entityManager.merge(person);
210+
assertFalse(getExternalJournalService().notifyExternalJournalPersonUpdate(journalPerson));
211+
212+
journalPerson = personFacade.getPersonForJournal(person.getUuid());
199213
person.setSymptomJournalStatus(SymptomJournalStatus.REJECTED);
200-
assertFalse(getExternalJournalService().notifyExternalJournalPersonUpdate(person, updatedPerson));
214+
person = entityManager.merge(person);
215+
assertFalse(getExternalJournalService().notifyExternalJournalPersonUpdate(journalPerson));
216+
217+
journalPerson = personFacade.getPersonForJournal(person.getUuid());
201218
person.setSymptomJournalStatus(SymptomJournalStatus.UNREGISTERED);
202-
assertFalse(getExternalJournalService().notifyExternalJournalPersonUpdate(person, updatedPerson));
219+
person = entityManager.merge(person);
220+
assertFalse(getExternalJournalService().notifyExternalJournalPersonUpdate(journalPerson));
221+
222+
journalPerson = personFacade.getPersonForJournal(person.getUuid());
203223
person.setSymptomJournalStatus(SymptomJournalStatus.ACCEPTED);
204-
assertTrue(getExternalJournalService().notifyExternalJournalPersonUpdate(person, updatedPerson));
205-
person.setSymptomJournalStatus(SymptomJournalStatus.REGISTERED);
224+
person = entityManager.merge(person);
225+
assertFalse(getExternalJournalService().notifyExternalJournalPersonUpdate(journalPerson));
206226

207227
// Apply any other relevant change and make sure notification is still considered necessary
208228
for (String secondPropertyName : relevantChanges.keySet()) {
209-
setPersonProperty(updatedPerson, secondPropertyName, relevantChanges.get(secondPropertyName));
210-
assertTrue(getExternalJournalService().notifyExternalJournalPersonUpdate(person, updatedPerson));
211-
setPersonProperty(updatedPerson, secondPropertyName, relevantProperties.get(secondPropertyName));
229+
if (!secondPropertyName.equals(propertyName)) {
230+
journalPerson = personFacade.getPersonForJournal(person.getUuid());
231+
setPersonProperty(person, secondPropertyName, relevantChanges.get(secondPropertyName));
232+
person = entityManager.merge(person);
233+
assertTrue(getExternalJournalService().notifyExternalJournalPersonUpdate(journalPerson));
234+
}
212235
}
213-
// reset updatedPerson
214-
setPersonProperty(updatedPerson, propertyName, relevantProperties.get(propertyName));
236+
237+
setPersonRelevantFields(person);
238+
person = entityManager.merge(person);
215239
}
216240
}
217241

242+
protected void setPersonRelevantFields(Person person) {
243+
person.setFirstName("Klaus");
244+
person.setLastName("Draufle");
245+
person.setSex(Sex.MALE);
246+
person.setEmailAddress("[email protected]");
247+
person.setPhone("+496211218490");
248+
person.setBirthdateYYYY(2000);
249+
person.setBirthdateMM(6);
250+
person.setBirthdateDD(1);
251+
person.setSymptomJournalStatus(SymptomJournalStatus.REGISTERED);
252+
}
253+
218254
/*
219255
* If you need to change this method to make it pass, you probably changed the behaviour of the ExternalVisitsResource.
220256
* Please note that other system used alongside with SORMAS are depending on this, so that their developers must be notified of any
221257
* relevant API changes some time before they go into any test and productive system. Please inform the SORMAS core development team at
222258
* https://gitter.im/SORMAS-Project!
223259
*/
224-
private static void setPersonProperty(PersonDto person, String propertyName, Object propertyValue) {
260+
private void setPersonProperty(Person person, String propertyName, Object propertyValue) {
225261
try {
226262
Method method = person.getClass().getMethod("set" + propertyName, propertyValue.getClass());
227263
method.invoke(person, propertyValue);
228-
229264
} catch (NoSuchMethodException e) {
230265
// This probably means that the set method is gone, which may impose changes to the External Journal Interface
231266
assertTrue(false);

0 commit comments

Comments
 (0)