Skip to content

Commit cded3a3

Browse files
vinay-ThoughtWorkssowmika148AlekhyaYalla
authored andcommitted
AP-46 | Appointment fixes (Bahmni#23)
* Sowmika, Vinay | MOBN-877 | Handle conflicts for services with multiple slots and with no start or end time * Sowmika, Vinay | MOBN-875 | Send NO_CONTENT response when there are no appointmnets to save * Alekhya | MOBN-877 | Handle service time in negative milliseconds * Sowmika | MOBN-875 | Retain the order of appointments using LinkedHashSet * Alekhya | MOBN-907 | Clone Appointment object in conflicts flow * Alekhya | MOBN-906 | Remove Id in cloning appointment providers * Alekhya, Siva | MOBN-904 | Remove transactional annotation for conflicts methods * Sowmika, Alekhya | MOBN-906 | Revert - 'Sowmika, Sneha, Vineela | MOBN-498 | Filter out voided appointment providers in appointments' commit * Sowmika, Alekhya | MOBN-906 | Void cancelled response providers * Alekhya | MOBN-914 | Null check when edited appointment is null * Alekhya | MOBN-914 | Refactor * Alekhya | MOBN-914 | Throw api exception when end date is before start date * Alekhya | MOBN-906 | Clone the new providers * Alekhya | MOBN-966 | Include Appointment id while cloning appointment in conflicts flow * Alekhya | MOBN-969 | Fix extension of weekly recurring appointments when only one week day is selected Co-authored-by: sowmika148 <[email protected]> Co-authored-by: Alekhya Yalla <[email protected]>
1 parent 2737277 commit cded3a3

25 files changed

+475
-154
lines changed

api/src/main/java/org/openmrs/module/appointments/conflicts/impl/AppointmentServiceUnavailabilityConflict.java

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.openmrs.module.appointments.model.Appointment;
66
import org.openmrs.module.appointments.model.AppointmentServiceDefinition;
77
import org.openmrs.module.appointments.model.ServiceWeeklyAvailability;
8+
import org.openmrs.module.appointments.util.DateUtil;
89

910
import java.sql.Time;
1011
import java.text.SimpleDateFormat;
@@ -14,6 +15,7 @@
1415
import java.util.Objects;
1516
import java.util.Optional;
1617
import java.util.Set;
18+
import java.util.stream.Collectors;
1719

1820
import static org.openmrs.module.appointments.model.AppointmentConflictType.SERVICE_UNAVAILABLE;
1921
import static org.openmrs.module.appointments.util.DateUtil.getEpochTime;
@@ -44,28 +46,29 @@ private boolean checkConflicts(Appointment appointment, AppointmentServiceDefini
4446
Set<ServiceWeeklyAvailability> weeklyAvailableDays = appointmentServiceDefinition.getWeeklyAvailability();
4547
if (isObjectPresent(weeklyAvailableDays)) {
4648
String appointmentDay = DayFormat.format(appointment.getStartDateTime());
47-
Optional<ServiceWeeklyAvailability> dayAvailability = weeklyAvailableDays.stream()
48-
.filter(day -> day.isSameDay(appointmentDay)).findFirst();
49-
if (dayAvailability.isPresent()) {
50-
ServiceWeeklyAvailability availableDay = dayAvailability.get();
51-
return checkTimeAvailability(appointment, availableDay.getStartTime(), availableDay.getEndTime());
52-
}
49+
List<ServiceWeeklyAvailability> dayAvailabilities = weeklyAvailableDays.stream()
50+
.filter(day -> day.isSameDay(appointmentDay)).collect(Collectors.toList());
51+
if (!dayAvailabilities.isEmpty())
52+
return dayAvailabilities.stream().allMatch(availableDay ->
53+
checkTimeAvailability(appointment, availableDay.getStartTime().getTime(), availableDay.getEndTime().getTime()));
5354
return true;
5455
}
55-
return checkTimeAvailability(appointment,
56-
appointmentServiceDefinition.getStartTime(), appointmentServiceDefinition.getEndTime());
57-
56+
Time serviceStartTime = appointmentServiceDefinition.getStartTime();
57+
Time serviceEndTime = appointmentServiceDefinition.getEndTime();
58+
long serviceStartMillis = serviceStartTime != null ? serviceStartTime.getTime() : DateUtil.getStartOfDay().getTime();
59+
long serviceEndMillis = serviceEndTime != null ? serviceEndTime.getTime() : DateUtil.getEndOfDay().getTime();
60+
return checkTimeAvailability(appointment, serviceStartMillis, serviceEndMillis);
5861
}
5962

6063
private boolean isObjectPresent(Collection<?> object) {
6164
return Objects.nonNull(object) && !object.isEmpty();
6265
}
6366

64-
private boolean checkTimeAvailability(Appointment appointment, Time serviceStartTime, Time serviceEndTime) {
67+
private boolean checkTimeAvailability(Appointment appointment, long serviceStartTime, long serviceEndTime) {
6568
long appointmentStartTimeMilliSeconds = getEpochTime(appointment.getStartDateTime().getTime());
6669
long appointmentEndTimeMilliSeconds = getEpochTime(appointment.getEndDateTime().getTime());
67-
long serviceStartTimeMilliSeconds = getEpochTime(serviceStartTime.getTime());
68-
long serviceEndTimeMilliSeconds = getEpochTime(serviceEndTime.getTime());
70+
long serviceStartTimeMilliSeconds = getEpochTime(serviceStartTime);
71+
long serviceEndTimeMilliSeconds = getEpochTime(serviceEndTime);
6972
boolean isConflict = (appointmentStartTimeMilliSeconds >= appointmentEndTimeMilliSeconds)
7073
|| ((appointmentStartTimeMilliSeconds < serviceStartTimeMilliSeconds)
7174
|| (appointmentEndTimeMilliSeconds > serviceEndTimeMilliSeconds));

api/src/main/java/org/openmrs/module/appointments/helper/AppointmentServiceHelper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.util.HashMap;
1717
import java.util.List;
1818
import java.util.Map;
19+
import java.util.Objects;
1920

2021
@Component
2122
public class AppointmentServiceHelper {
@@ -61,7 +62,7 @@ public String getAppointmentAsJsonString(Appointment appointment) throws IOExcep
6162

6263
private void validateAppointment(Appointment appointment, List<AppointmentValidator> appointmentValidators,
6364
List<String> errors) {
64-
if(!CollectionUtils.isEmpty(appointmentValidators)) {
65+
if(!CollectionUtils.isEmpty(appointmentValidators) && Objects.nonNull(appointment)) {
6566
for (AppointmentValidator validator : appointmentValidators) {
6667
validator.validate(appointment, errors);
6768
}

api/src/main/java/org/openmrs/module/appointments/model/AppointmentProvider.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ public class AppointmentProvider extends BaseOpenmrsData implements Serializable
1515
private Boolean voided;
1616

1717
public AppointmentProvider(AppointmentProvider appointmentProvider) {
18-
this.appointmentProviderId = appointmentProvider.getAppointmentProviderId();
1918
this.appointment = appointmentProvider.getAppointment();
2019
this.provider = appointmentProvider.getProvider();
2120
this.response = appointmentProvider.getResponse();

api/src/main/java/org/openmrs/module/appointments/model/AppointmentRecurringPattern.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import org.openmrs.module.appointments.service.impl.RecurringAppointmentType;
44

55
import java.util.Date;
6-
import java.util.HashSet;
6+
import java.util.LinkedHashSet;
77
import java.util.Set;
88
import java.util.stream.Collectors;
99

@@ -15,7 +15,7 @@ public class AppointmentRecurringPattern {
1515
private Date endDate;
1616
private RecurringAppointmentType type;
1717
private String daysOfWeek;
18-
private Set<Appointment> appointments = new HashSet<>();
18+
private Set<Appointment> appointments = new LinkedHashSet<>();
1919

2020
public Integer getId() {
2121
return id;

api/src/main/java/org/openmrs/module/appointments/service/AppointmentsService.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,9 @@ public interface AppointmentsService {
7777
@Authorized({VIEW_APPOINTMENTS, MANAGE_APPOINTMENTS})
7878
List<Appointment> search(AppointmentSearchRequest appointmentSearchRequest);
7979

80-
@Transactional
8180
@Authorized({VIEW_APPOINTMENTS, MANAGE_APPOINTMENTS})
8281
Map<Enum, List<Appointment>> getAppointmentConflicts(Appointment appointment);
8382

84-
@Transactional
8583
@Authorized({VIEW_APPOINTMENTS, MANAGE_APPOINTMENTS})
8684
Map<Enum, List<Appointment>> getAppointmentsConflicts(List<Appointment> appointments);
8785
}

api/src/main/java/org/openmrs/module/appointments/service/impl/AppointmentRecurringPatternServiceImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.Date;
2121
import java.util.HashSet;
2222
import java.util.List;
23+
import java.util.Objects;
2324
import java.util.TimeZone;
2425
import java.util.stream.Collectors;
2526

@@ -96,7 +97,7 @@ public Appointment update(AppointmentRecurringPattern appointmentRecurringPatter
9697
List<Appointment> updatedAppointments) {
9798
Appointment editedAppointment = updatedAppointments
9899
.stream()
99-
.filter(app -> app.getVoided() != true)
100+
.filter(app -> !app.getVoided())
100101
.collect(Collectors.toList()).get(0);
101102
updateAppointmentsDetails(appointmentRecurringPattern, updatedAppointments);
102103
appointmentServiceHelper.validate(editedAppointment.getRelatedAppointment(), editAppointmentValidators);

api/src/main/java/org/openmrs/module/appointments/service/impl/AppointmentsServiceImpl.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
import static org.openmrs.module.appointments.constants.PrivilegeConstants.RESET_APPOINTMENT_STATUS;
4343
import static org.openmrs.module.appointments.util.DateUtil.getStartOfDay;
4444

45-
@Transactional
45+
4646
public class AppointmentsServiceImpl implements AppointmentsService {
4747

4848
private static final String PRIVILEGES_EXCEPTION_CODE = "error.privilegesRequired";
@@ -105,6 +105,7 @@ private boolean isCurrentUserSamePersonAsOneOfTheAppointmentProviders(Set<Appoin
105105
equals(Context.getAuthenticatedUser().getPerson()));
106106
}
107107

108+
@Transactional
108109
@Override
109110
public Appointment validateAndSave(Appointment appointment) throws APIException {
110111
validate(appointment, appointmentValidators);
@@ -118,6 +119,7 @@ private void save(Appointment appointment) {
118119
appointmentDao.save(appointment);
119120
}
120121

122+
@Transactional
121123
@Override
122124
public void validate(Appointment appointment, List<AppointmentValidator> appointmentValidators) {
123125
if (!validateIfUserHasSelfOrAllAppointmentsAccess(appointment)) {
@@ -127,6 +129,7 @@ public void validate(Appointment appointment, List<AppointmentValidator> appoint
127129
appointmentServiceHelper.validate(appointment, appointmentValidators);
128130
}
129131

132+
@Transactional
130133
@Override
131134
public List<Appointment> getAllAppointments(Date forDate) {
132135
List<Appointment> appointments = appointmentDao.getAllAppointments(forDate);
@@ -144,33 +147,39 @@ private boolean isServiceOrServiceTypeVoided(Appointment appointment) {
144147
* @param appointment
145148
* @return
146149
*/
150+
@Transactional
147151
@Override
148152
public List<Appointment> search(Appointment appointment) {
149153
List<Appointment> appointments = appointmentDao.search(appointment);
150154
return appointments.stream().filter(searchedAppointment -> !isServiceOrServiceTypeVoided(searchedAppointment)).collect(Collectors.toList());
151155
}
152156

157+
@Transactional
153158
@Override
154159
public List<Appointment> getAllFutureAppointmentsForService(AppointmentServiceDefinition appointmentServiceDefinition) {
155160
return appointmentDao.getAllFutureAppointmentsForService(appointmentServiceDefinition);
156161
}
157162

163+
@Transactional
158164
@Override
159165
public List<Appointment> getAllFutureAppointmentsForServiceType(AppointmentServiceType appointmentServiceType) {
160166
return appointmentDao.getAllFutureAppointmentsForServiceType(appointmentServiceType);
161167
}
162168

169+
@Transactional
163170
@Override
164171
public List<Appointment> getAppointmentsForService(AppointmentServiceDefinition appointmentServiceDefinition, Date startDate, Date endDate, List<AppointmentStatus> appointmentStatusList) {
165172
return appointmentDao.getAppointmentsForService(appointmentServiceDefinition, startDate, endDate, appointmentStatusList);
166173
}
167174

175+
@Transactional
168176
@Override
169177
public Appointment getAppointmentByUuid(String uuid) {
170178
Appointment appointment = appointmentDao.getAppointmentByUuid(uuid);
171179
return appointment;
172180
}
173181

182+
@Transactional
174183
@Override
175184
public void changeStatus(Appointment appointment, String status, Date onDate) throws APIException {
176185
AppointmentStatus appointmentStatus = AppointmentStatus.valueOf(status);
@@ -200,12 +209,14 @@ private boolean isUserAllowedToResetStatus(AppointmentStatus toStatus, Appointme
200209
return Context.hasPrivilege(RESET_APPOINTMENT_STATUS);
201210
}
202211

212+
@Transactional
203213
@Override
204214
public List<Appointment> getAllAppointmentsInDateRange(Date startDate, Date endDate) {
205215
List<Appointment> appointments = appointmentDao.getAllAppointmentsInDateRange(startDate, endDate);
206216
return appointments.stream().filter(appointment -> !isServiceOrServiceTypeVoided(appointment)).collect(Collectors.toList());
207217
}
208218

219+
@Transactional
209220
@Override
210221
public void undoStatusChange(Appointment appointment) throws APIException {
211222
if (!validateIfUserHasSelfOrAllAppointmentsAccess(appointment)) {
@@ -221,6 +232,7 @@ public void undoStatusChange(Appointment appointment) throws APIException {
221232
throw new APIException("No status change actions to undo");
222233
}
223234

235+
@Transactional
224236
@Override
225237
public List<Appointment> search(AppointmentSearchRequest appointmentSearchRequest) {
226238
if (isNull(appointmentSearchRequest.getStartDate())) {
@@ -257,6 +269,7 @@ private List<Appointment> getNonVoidedFutureAppointments(List<Appointment> appoi
257269
}).collect(Collectors.toList());
258270
}
259271

272+
@Transactional
260273
@Override
261274
public void updateAppointmentProviderResponse(AppointmentProvider providerWithNewResponse) {
262275
Appointment appointment = providerWithNewResponse.getAppointment();
@@ -293,6 +306,7 @@ private void validateProviderResponseForSelf(AppointmentProvider appointmentProv
293306
}
294307
}
295308

309+
@Transactional
296310
@Override
297311
public Appointment reschedule(String originalAppointmentUuid, Appointment newAppointment, boolean retainAppointmentNumber) {
298312
Appointment prevAppointment = getAppointmentByUuid(originalAppointmentUuid);

api/src/main/java/org/openmrs/module/appointments/util/DateUtil.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,22 @@ public static Date getStartOfDay() {
5757
}
5858

5959
public static long getEpochTime(long date) {
60-
long milliSeconds = 0;
61-
if (date > 0) {
62-
Calendar calendar = getCalendar(new Date(date));
63-
int hours = calendar.get(Calendar.HOUR_OF_DAY);
64-
int minutes = calendar.get(Calendar.MINUTE);
65-
int seconds = calendar.get(Calendar.SECOND);
66-
milliSeconds = (hours * 3600 + minutes * 60 + seconds) * 1000;
67-
}
60+
Calendar calendar = getCalendar(new Date(date));
61+
int hours = calendar.get(Calendar.HOUR_OF_DAY);
62+
int minutes = calendar.get(Calendar.MINUTE);
63+
int seconds = calendar.get(Calendar.SECOND);
64+
long milliSeconds = ((hours * 3600 + minutes * 60 + seconds) * 1000);
6865
return milliSeconds;
6966
}
67+
68+
public static Date getEndOfDay() {
69+
Calendar calendar = Calendar.getInstance();
70+
calendar.set(Calendar.HOUR_OF_DAY, calendar.getMaximum(Calendar.HOUR_OF_DAY));
71+
calendar.set(Calendar.MINUTE, calendar.getMaximum(Calendar.MINUTE));
72+
calendar.set(Calendar.SECOND, calendar.getMaximum(Calendar.SECOND));
73+
calendar.set(Calendar.MILLISECOND, calendar.getMaximum(Calendar.MILLISECOND));
74+
return calendar.getTime();
75+
}
7076
}
7177

7278

api/src/test/java/org/openmrs/module/appointments/conflicts/impl/AppointmentServiceUnavailabilityConflictTest.java

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,77 @@ public void shouldReturnServiceUnavailableTimeSlotConflict() {
106106
conflictingAppointments.addAll(appointmentServiceUnavailabilityConflict.getConflicts(Arrays.asList(appointmentOne, appointmentTwo, appointmentThree)));
107107

108108
assertNotNull(conflictingAppointments);
109-
assertEquals(3,conflictingAppointments.size());
109+
assertEquals(3, conflictingAppointments.size());
110110
assertEquals(appointmentOne, conflictingAppointments.get(0));
111111
assertEquals(appointmentTwo, conflictingAppointments.get(1));
112112
assertEquals(appointmentThree, conflictingAppointments.get(2));
113113
}
114114

115+
@Test
116+
public void shouldNotReturnServiceUnavailableConflictsForMoreSlotsInSingleDay() {
117+
AppointmentServiceDefinition appointmentServiceDefinition = new AppointmentServiceDefinition();
118+
// All Appointments are on Monday
119+
Appointment appointmentOne = new Appointment();
120+
appointmentOne.setService(appointmentServiceDefinition);
121+
appointmentOne.setStartDateTime(getDate(2019, 8, 23, 6, 30, 0));
122+
appointmentOne.setEndDateTime(getDate(2019, 8, 23, 7, 0, 0));
123+
appointmentOne.setAppointmentId(2);
124+
Appointment appointmentTwo = new Appointment();
125+
appointmentTwo.setService(appointmentServiceDefinition);
126+
appointmentTwo.setStartDateTime(getDate(2019, 8, 23, 16, 30, 0));
127+
appointmentTwo.setEndDateTime(getDate(2019, 8, 23, 17, 30, 0));
128+
appointmentTwo.setAppointmentId(3);
129+
Appointment appointmentThree = new Appointment();
130+
appointmentThree.setService(appointmentServiceDefinition);
131+
appointmentThree.setStartDateTime(getDate(2019, 8, 23, 16, 30, 0));
132+
appointmentThree.setEndDateTime(getDate(2019, 8, 23, 17, 0, 0));
133+
appointmentThree.setAppointmentId(4);
134+
ServiceWeeklyAvailability day1 = new ServiceWeeklyAvailability();
135+
day1.setStartTime(new Time(6, 30, 0));
136+
day1.setEndTime(new Time(14, 0, 0));
137+
day1.setDayOfWeek(DayOfWeek.MONDAY);
138+
ServiceWeeklyAvailability day2 = new ServiceWeeklyAvailability();
139+
day2.setStartTime(new Time(16, 30, 0));
140+
day2.setEndTime(new Time(19, 0, 0));
141+
day2.setDayOfWeek(DayOfWeek.MONDAY);
142+
Set<ServiceWeeklyAvailability> availabilities = new HashSet<>(Arrays.asList(day1, day2));
143+
appointmentServiceDefinition.setWeeklyAvailability(availabilities);
144+
145+
List<Appointment> conflictingAppointments = new ArrayList<>();
146+
conflictingAppointments.addAll(appointmentServiceUnavailabilityConflict.getConflicts(Arrays.asList(appointmentOne, appointmentTwo, appointmentThree)));
147+
148+
assertNotNull(conflictingAppointments);
149+
assertEquals(0, conflictingAppointments.size());
150+
}
151+
152+
@Test
153+
public void shouldNotReturnServiceUnavailableConflictsForServicesWithNoAvailabilityInformation() {
154+
AppointmentServiceDefinition appointmentServiceDefinition = new AppointmentServiceDefinition();
155+
Appointment appointmentOne = new Appointment();
156+
appointmentOne.setService(appointmentServiceDefinition);
157+
appointmentOne.setStartDateTime(getDate(2019, 8, 23, 6, 30, 0));
158+
appointmentOne.setEndDateTime(getDate(2019, 8, 23, 7, 0, 0));
159+
appointmentOne.setAppointmentId(2);
160+
Appointment appointmentTwo = new Appointment();
161+
appointmentTwo.setService(appointmentServiceDefinition);
162+
appointmentTwo.setStartDateTime(getDate(2019, 8, 23, 16, 30, 0));
163+
appointmentTwo.setEndDateTime(getDate(2019, 8, 23, 17, 30, 0));
164+
appointmentTwo.setAppointmentId(3);
165+
Appointment appointmentThree = new Appointment();
166+
appointmentThree.setService(appointmentServiceDefinition);
167+
appointmentThree.setStartDateTime(getDate(2019, 8, 23, 16, 30, 0));
168+
appointmentThree.setEndDateTime(getDate(2019, 8, 23, 17, 0, 0));
169+
appointmentThree.setAppointmentId(4);
170+
Set<ServiceWeeklyAvailability> availabilities = new HashSet<>();
171+
appointmentServiceDefinition.setWeeklyAvailability(availabilities);
172+
173+
List<Appointment> conflictingAppointments = new ArrayList<>();
174+
conflictingAppointments.addAll(appointmentServiceUnavailabilityConflict.getConflicts(Arrays.asList(appointmentOne, appointmentTwo, appointmentThree)));
175+
176+
assertNotNull(conflictingAppointments);
177+
assertEquals(0, conflictingAppointments.size());
178+
}
179+
115180
@Test
116181
public void shouldReturnConflictWhenAppointmentStartTimeAfterEndTime() {
117182
AppointmentServiceDefinition appointmentServiceDefinition = new AppointmentServiceDefinition();

api/src/test/java/org/openmrs/module/appointments/helper/AppointmentServiceHelperTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,4 +171,13 @@ public void shouldThrowExceptionForInapplicableStatusChange() {
171171
any(AppointmentStatus.class),
172172
anyListOf(String.class));
173173
}
174+
175+
@Test
176+
public void shouldNotCallValidateWhenAppointmentIsNull(){
177+
List<AppointmentValidator> appointmentValidators = Collections.singletonList(appointmentValidator);
178+
appointmentServiceHelper.validate(null, appointmentValidators);
179+
180+
verify(appointmentValidator, never()).validate(any(Appointment.class),
181+
anyListOf(String.class));
182+
}
174183
}

api/src/test/java/org/openmrs/module/appointments/util/DateUtilTest.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,15 @@ public void shouldReturnStartOfDay() {
7474
assertEquals("00:00:00", time);
7575
}
7676

77+
@Test
78+
public void shouldReturnEndOfDay() {
79+
Date date = DateUtil.getEndOfDay();
80+
SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
81+
String time = dateFormat.format(date);
82+
83+
assertEquals("23:59:59", time);
84+
}
85+
7786
@Test
7887
public void shouldConvertDateToMilliSeconds() throws ParseException {
7988
String dateString = "2017-03-15T16:57:09.0Z";
@@ -85,6 +94,6 @@ public void shouldConvertDateToMilliSeconds() throws ParseException {
8594
@Test
8695
public void shouldReturnZeroWhenPassedLongIsNegative() {
8796
long milliSeconds = getEpochTime(-10000);
88-
assertEquals(0, milliSeconds);
97+
assertEquals(19790000, milliSeconds);
8998
}
9099
}

0 commit comments

Comments
 (0)