Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: [DHIS2-15272] Fix program expiryDays check with periodType for events (2.41) #19316

Merged
merged 5 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ public void validate(Reporter reporter, TrackerBundle bundle, Event event) {
return;
}

validateExpiryDays(reporter, bundle, event, program);
validatePeriodType(reporter, event, program);
validateCompletionExpiryDays(reporter, bundle, event, program);
validateExpiryPeriodType(reporter, event, program);
}

private void validateExpiryDays(
private void validateCompletionExpiryDays(
Reporter reporter, TrackerBundle bundle, Event event, Program program) {
User actingUser = bundle.getUser();

Expand All @@ -101,7 +101,7 @@ private void validateExpiryDays(
}
}

private void validatePeriodType(Reporter reporter, Event event, Program program) {
private void validateExpiryPeriodType(Reporter reporter, Event event, Program program) {
checkNotNull(event, TrackerImporterAssertErrors.EVENT_CANT_BE_NULL);
checkNotNull(program, TrackerImporterAssertErrors.PROGRAM_CANT_BE_NULL);

Expand All @@ -120,9 +120,16 @@ private void validatePeriodType(Reporter reporter, Event event, Program program)
return;
}

Period period = periodType.createPeriod(new Date());
Period eventPeriod = periodType.createPeriod(Date.from(referenceDate));

if (referenceDate.isBefore(period.getStartDate().toInstant())) {
if (eventPeriod
.getEndDate()
.toInstant() // This will be 00:00 time of the period end date.
.plus(
ofDays(
program.getExpiryDays()
+ 1L)) // Extra day added to account for final 24 hours of expiring day
.isBefore(Instant.now())) {
reporter.addError(event, E1047, event);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,6 @@ public void setUp() {

bundle = TrackerBundle.builder().user(user).preheat(preheat).build();

when(preheat.getProgram(MetadataIdentifier.ofUid(PROGRAM_WITH_REGISTRATION_ID)))
.thenReturn(getProgramWithRegistration());
when(preheat.getProgram(MetadataIdentifier.ofUid(PROGRAM_WITHOUT_REGISTRATION_ID)))
.thenReturn(getProgramWithoutRegistration());

Expand All @@ -102,7 +100,6 @@ public void setUp() {

@Test
void testEventIsValid() {
// given
Event event = new Event();
event.setProgram(MetadataIdentifier.ofUid(PROGRAM_WITHOUT_REGISTRATION_ID));
event.setOccurredAt(now());
Expand All @@ -111,145 +108,180 @@ void testEventIsValid() {
TrackerBundle bundle =
TrackerBundle.builder().user(getEditExpiredUser()).preheat(preheat).build();

// when
validator.validate(reporter, bundle, event);

// then
assertIsEmpty(reporter.getErrors());
}

@Test
void testEventIsNotValidWhenOccurredDateIsNotPresentAndProgramIsWithoutRegistration() {
// given
when(preheat.getProgram(MetadataIdentifier.ofUid(PROGRAM_WITH_REGISTRATION_ID)))
.thenReturn(getProgramWithRegistration(5));
Event event = new Event();
event.setEvent(CodeGenerator.generateUid());
event.setProgram(MetadataIdentifier.ofUid(PROGRAM_WITHOUT_REGISTRATION_ID));

// when
validator.validate(reporter, bundle, event);

// then
assertHasError(reporter, event, E1031);
}

@Test
void testEventIsNotValidWhenOccurredDateIsNotPresentAndEventIsActive() {
// given
when(preheat.getProgram(MetadataIdentifier.ofUid(PROGRAM_WITH_REGISTRATION_ID)))
.thenReturn(getProgramWithRegistration(5));
Event event = new Event();
event.setEvent(CodeGenerator.generateUid());
event.setProgram(MetadataIdentifier.ofUid(PROGRAM_WITH_REGISTRATION_ID));
event.setStatus(EventStatus.ACTIVE);

// when
validator.validate(reporter, bundle, event);

// then
assertHasError(reporter, event, E1031);
}

@Test
void testEventIsNotValidWhenOccurredDateIsNotPresentAndEventIsCompleted() {
// given
when(preheat.getProgram(MetadataIdentifier.ofUid(PROGRAM_WITH_REGISTRATION_ID)))
.thenReturn(getProgramWithRegistration(5));
Event event = new Event();
event.setEvent(CodeGenerator.generateUid());
event.setProgram(MetadataIdentifier.ofUid(PROGRAM_WITH_REGISTRATION_ID));
event.setStatus(EventStatus.COMPLETED);

// when
validator.validate(reporter, bundle, event);

// then
assertHasError(reporter, event, E1031);
}

@Test
void testEventIsNotValidWhenScheduledDateIsNotPresentAndEventIsSchedule() {
// given
when(preheat.getProgram(MetadataIdentifier.ofUid(PROGRAM_WITH_REGISTRATION_ID)))
.thenReturn(getProgramWithRegistration(5));
Event event = new Event();
event.setEvent(CodeGenerator.generateUid());
event.setProgram(MetadataIdentifier.ofUid(PROGRAM_WITH_REGISTRATION_ID));
event.setOccurredAt(Instant.now());
event.setStatus(EventStatus.SCHEDULE);

// when
validator.validate(reporter, bundle, event);

// then
assertHasError(reporter, event, E1050);
}

@Test
void testEventIsNotValidWhenCompletedAtIsNotPresentAndEventIsCompleted() {
// given
when(preheat.getProgram(MetadataIdentifier.ofUid(PROGRAM_WITH_REGISTRATION_ID)))
.thenReturn(getProgramWithRegistration(5));
Event event = new Event();
event.setEvent(CodeGenerator.generateUid());
event.setProgram(MetadataIdentifier.ofUid(PROGRAM_WITH_REGISTRATION_ID));
event.setOccurredAt(now());
event.setStatus(EventStatus.COMPLETED);

// when
validator.validate(reporter, bundle, event);

// then
assertHasError(reporter, event, E1042);
}

@Test
void testEventIsNotValidWhenCompletedAtIsTooSoonAndEventIsCompleted() {
// given
when(preheat.getProgram(MetadataIdentifier.ofUid(PROGRAM_WITH_REGISTRATION_ID)))
.thenReturn(getProgramWithRegistration(5));
Event event = new Event();
event.setEvent(CodeGenerator.generateUid());
event.setProgram(MetadataIdentifier.ofUid(PROGRAM_WITH_REGISTRATION_ID));
event.setOccurredAt(now());
event.setCompletedAt(sevenDaysAgo());
event.setStatus(EventStatus.COMPLETED);

// when
validator.validate(reporter, bundle, event);

// then
assertHasError(reporter, event, E1043);
}

@Test
void testEventIsNotValidWhenOccurredAtAndScheduledAtAreNotPresent() {
// given
when(preheat.getProgram(MetadataIdentifier.ofUid(PROGRAM_WITH_REGISTRATION_ID)))
.thenReturn(getProgramWithRegistration(5));
Event event = new Event();
event.setEvent(CodeGenerator.generateUid());
event.setProgram(MetadataIdentifier.ofUid(PROGRAM_WITH_REGISTRATION_ID));
event.setOccurredAt(null);
event.setScheduledAt(null);
event.setStatus(EventStatus.SKIPPED);

// when
validator.validate(reporter, bundle, event);

// then
assertHasError(reporter, event, E1046);
}

@Test
void testEventIsNotValidWhenDateBelongsToExpiredPeriod() {
// given
void shouldFailValidationForEventWhenDateBelongsToExpiredPeriod() {
when(preheat.getProgram(MetadataIdentifier.ofUid(PROGRAM_WITH_REGISTRATION_ID)))
.thenReturn(getProgramWithRegistration(6));
Event event = new Event();
event.setEvent(CodeGenerator.generateUid());
event.setProgram(MetadataIdentifier.ofUid(PROGRAM_WITH_REGISTRATION_ID));
event.setOccurredAt(sevenDaysAgo());
event.setStatus(EventStatus.ACTIVE);

// when
validator.validate(reporter, bundle, event);

// then
assertHasError(reporter, event, E1047);
}

private Program getProgramWithRegistration() {
@Test
void shouldPassValidationForEventWhenDateBelongsToPastPeriodWithZeroExpiryDays() {
when(preheat.getProgram(MetadataIdentifier.ofUid(PROGRAM_WITH_REGISTRATION_ID)))
.thenReturn(getProgramWithRegistration(0));
Event event = new Event();
event.setEvent(CodeGenerator.generateUid());
event.setProgram(MetadataIdentifier.ofUid(PROGRAM_WITH_REGISTRATION_ID));
event.setOccurredAt(sevenDaysAgo());
event.setStatus(EventStatus.ACTIVE);

validator.validate(reporter, bundle, event);

assertIsEmpty(reporter.getErrors());
}

@Test
void shouldPassValidationForEventWhenDateBelongsPastEventPeriodButWithinExpiryDays() {
when(preheat.getProgram(MetadataIdentifier.ofUid(PROGRAM_WITH_REGISTRATION_ID)))
.thenReturn(getProgramWithRegistration(7));
Event event = new Event();
event.setEvent(CodeGenerator.generateUid());
event.setProgram(MetadataIdentifier.ofUid(PROGRAM_WITH_REGISTRATION_ID));
event.setOccurredAt(sevenDaysAgo());
event.setStatus(EventStatus.ACTIVE);

validator.validate(reporter, bundle, event);

assertIsEmpty(reporter.getErrors());
}

@Test
void shouldPassValidationForEventWhenScheduledDateBelongsToFuturePeriod() {
when(preheat.getProgram(MetadataIdentifier.ofUid(PROGRAM_WITH_REGISTRATION_ID)))
.thenReturn(getProgramWithRegistration(5));
Event event = new Event();
event.setEvent(CodeGenerator.generateUid());
event.setProgram(MetadataIdentifier.ofUid(PROGRAM_WITH_REGISTRATION_ID));
event.setScheduledAt(sevenDaysLater());
event.setStatus(EventStatus.SCHEDULE);

validator.validate(reporter, bundle, event);

assertIsEmpty(reporter.getErrors());
}

private Program getProgramWithRegistration(int expiryDays) {
Program program = createProgram('A');
program.setUid(PROGRAM_WITH_REGISTRATION_ID);
program.setProgramType(ProgramType.WITH_REGISTRATION);
program.setCompleteEventsExpiryDays(5);
program.setExpiryDays(5);
program.setExpiryDays(expiryDays);
program.setExpiryPeriodType(new DailyPeriodType());
return program;
}
Expand Down Expand Up @@ -278,4 +310,8 @@ private Instant now() {
private Instant sevenDaysAgo() {
return LocalDateTime.now().minusDays(7).toInstant(ZoneOffset.UTC);
}

private Instant sevenDaysLater() {
return LocalDateTime.now().plusDays(7).toInstant(ZoneOffset.UTC);
}
}