<commit_before>package org.hisp.dhis.dxf2.events.importer.update.validation;

import static org.hisp.dhis.DhisConvenienceTest.createProgram;
import static org.mockito.Mockito.when;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.hisp.dhis.dxf2.common.ImportOptions;
import org.hisp.dhis.dxf2.events.importer.shared.ImmutableEvent;
import org.hisp.dhis.dxf2.events.importer.validation.BaseValidationTest;
import org.hisp.dhis.dxf2.importsummary.ImportSummary;
import org.hisp.dhis.event.EventStatus;
import org.hisp.dhis.period.PeriodType;
import org.hisp.dhis.program.Program;
import org.hisp.dhis.program.ProgramStageInstance;
import org.hisp.dhis.user.User;
import org.junit.Before;
import org.junit.Test;

/**
 * @author <NAME>
 */
public class ExpirationDaysCheckTest extends BaseValidationTest
{
    private ExpirationDaysCheck rule;

    @Before
    public void setUp()
    {
        rule = new ExpirationDaysCheck();

        // Prepare import options
        ImportOptions importOptions = ImportOptions.getDefaultImportOptions();
        importOptions.setUser( new User() );
        when( workContext.getImportOptions() ).thenReturn( importOptions );

    }

    @Test
    public void failWhenProgramStageInstanceHasNoCompletedDateAndProgramHasExpiryDays()
    {
        // Given

        // Prepare program
        Program program = createProgram( 'P' );
        program.setCompleteEventsExpiryDays( 3 );
        Map<String, Program> programMap = new HashMap<>();
        programMap.put( program.getUid(), program );
        when( workContext.getProgramsMap() ).thenReturn( programMap );

        // Prepare program stage instance
        Map<String, ProgramStageInstance> psiMap = new HashMap<>();
        ProgramStageInstance psi = new ProgramStageInstance();
        psi.setStatus( EventStatus.COMPLETED );
        psi.setUid( event.getUid() );
        psiMap.put( event.getUid(), psi );
        when( workContext.getProgramStageInstanceMap() ).thenReturn( psiMap );

        // Prepare event
        event.setProgram( program.getUid() );
        event.setStatus( EventStatus.COMPLETED );

        // When
        ImportSummary importSummary = rule.check( new ImmutableEvent( event ), workContext );

        // Then
        assertHasError( importSummary, event, "Event needs to have completed date" );
    }

    @Test
    public void failWhenEventHasNoCompletedDateAndProgramHasExpiryDays()
    {
        // Given

        // Prepare program
        Program program = createProgram( 'P' );
        program.setCompleteEventsExpiryDays( 3 );
        Map<String, Program> programMap = new HashMap<>();
        programMap.put( program.getUid(), program );
        when( workContext.getProgramsMap() ).thenReturn( programMap );

        // Prepare event
        event.setProgram( program.getUid() );
        event.setStatus( EventStatus.COMPLETED );

        // When
        ImportSummary importSummary = rule.check( new ImmutableEvent( event ), workContext );

        // Then
        assertHasError( importSummary, event, "Event needs to have completed date" );
    }

    @Test
    public void failWhenProgramStageInstanceCompletedDateFallsAfterCurrentDay()
    {
        // Given

        // Prepare program
        Program program = createProgram( 'P' );
        program.setCompleteEventsExpiryDays( 3 );
        Map<String, Program> programMap = new HashMap<>();
        programMap.put( program.getUid(), program );
        when( workContext.getProgramsMap() ).thenReturn( programMap );

        // Prepare program stage instance
        Map<String, ProgramStageInstance> psiMap = new HashMap<>();
        ProgramStageInstance psi = new ProgramStageInstance();
        psi.setStatus( EventStatus.COMPLETED );
        psi.setCompletedDate( getTodayMinusDays( 5 ) );
        psi.setUid( event.getUid() );
        psiMap.put( event.getUid(), psi );
        when( workContext.getProgramStageInstanceMap() ).thenReturn( psiMap );

        // Prepare event
        event.setProgram( program.getUid() );
        event.setStatus( EventStatus.COMPLETED );

        // When
        ImportSummary importSummary = rule.check( new ImmutableEvent( event ), workContext );

        // Then
        assertHasError( importSummary, event,
            "The event's completeness date has expired. Not possible to make changes to this event" );
    }

    @Test
    public void failWhenProgramStageInstanceHasNoExecDateAndProgramHasPeriodType()
    {
        // Given

        // Prepare program
        Program program = createProgram( 'P' );
        program.setCompleteEventsExpiryDays( 3 );
        program.setExpiryPeriodType( PeriodType.getPeriodTypeFromIsoString( "202001" ) );
        program.setExpiryDays( 3 );
        Map<String, Program> programMap = new HashMap<>();
        programMap.put( program.getUid(), program );
        when( workContext.getProgramsMap() ).thenReturn( programMap );

        // Prepare program stage instance
        Map<String, ProgramStageInstance> psiMap = new HashMap<>();
        ProgramStageInstance psi = new ProgramStageInstance();
        psi.setCompletedDate( getTodayPlusDays( 5 ) );
        psi.setUid( event.getUid() );
        psiMap.put( event.getUid(), psi );
        when( workContext.getProgramStageInstanceMap() ).thenReturn( psiMap );

        // Prepare event
        event.setProgram( program.getUid() );

        // When
        ImportSummary importSummary = rule.check( new ImmutableEvent( event ), workContext );

        // Then
        assertHasError( importSummary, event, "Event needs to have event date" );
    }

    @Test
    public void failWhenProgramStageInstanceHasExecutionDateBeforeAllowedProgramExpiryDaysBasedOnPeriod()
    {
        // Given
        final String monthlyPeriodType = new SimpleDateFormat( "yyyyMM" ).format( new Date() );
        // Prepare program
        Program program = createProgram( 'P' );
        program.setExpiryPeriodType( PeriodType.getPeriodTypeFromIsoString( monthlyPeriodType ) );
        program.setExpiryDays( 3 );
        Map<String, Program> programMap = new HashMap<>();
        programMap.put( program.getUid(), program );
        when( workContext.getProgramsMap() ).thenReturn( programMap );

        // Prepare program stage instance
        Map<String, ProgramStageInstance> psiMap = new HashMap<>();
        ProgramStageInstance psi = new ProgramStageInstance();
        psi.setExecutionDate( getTodayMinusDays( 32 ) ); // month length + two days
        psi.setUid( event.getUid() );
        psiMap.put( event.getUid(), psi );
        when( workContext.getProgramStageInstanceMap() ).thenReturn( psiMap );
<commit_msg>fix: failing unit test due to invalid period length (#6059)<commit_after>package org.hisp.dhis.dxf2.events.importer.update.validation;

import static org.hisp.dhis.DhisConvenienceTest.createProgram;
import static org.mockito.Mockito.when;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.hisp.dhis.dxf2.common.ImportOptions;
import org.hisp.dhis.dxf2.events.importer.shared.ImmutableEvent;
import org.hisp.dhis.dxf2.events.importer.validation.BaseValidationTest;
import org.hisp.dhis.dxf2.importsummary.ImportSummary;
import org.hisp.dhis.event.EventStatus;
import org.hisp.dhis.period.PeriodType;
import org.hisp.dhis.program.Program;
import org.hisp.dhis.program.ProgramStageInstance;
import org.hisp.dhis.user.User;
import org.junit.Before;
import org.junit.Test;

/**
 * @author <NAME>
 */
public class ExpirationDaysCheckTest extends BaseValidationTest
{
    private ExpirationDaysCheck rule;

    @Before
    public void setUp()
    {
        rule = new ExpirationDaysCheck();

        // Prepare import options
        ImportOptions importOptions = ImportOptions.getDefaultImportOptions();
        importOptions.setUser( new User() );
        when( workContext.getImportOptions() ).thenReturn( importOptions );

    }

    @Test
    public void failWhenProgramStageInstanceHasNoCompletedDateAndProgramHasExpiryDays()
    {
        // Given

        // Prepare program
        Program program = createProgram( 'P' );
        program.setCompleteEventsExpiryDays( 3 );
        Map<String, Program> programMap = new HashMap<>();
        programMap.put( program.getUid(), program );
        when( workContext.getProgramsMap() ).thenReturn( programMap );

        // Prepare program stage instance
        Map<String, ProgramStageInstance> psiMap = new HashMap<>();
        ProgramStageInstance psi = new ProgramStageInstance();
        psi.setStatus( EventStatus.COMPLETED );
        psi.setUid( event.getUid() );
        psiMap.put( event.getUid(), psi );
        when( workContext.getProgramStageInstanceMap() ).thenReturn( psiMap );

        // Prepare event
        event.setProgram( program.getUid() );
        event.setStatus( EventStatus.COMPLETED );

        // When
        ImportSummary importSummary = rule.check( new ImmutableEvent( event ), workContext );

        // Then
        assertHasError( importSummary, event, "Event needs to have completed date" );
    }

    @Test
    public void failWhenEventHasNoCompletedDateAndProgramHasExpiryDays()
    {
        // Given

        // Prepare program
        Program program = createProgram( 'P' );
        program.setCompleteEventsExpiryDays( 3 );
        Map<String, Program> programMap = new HashMap<>();
        programMap.put( program.getUid(), program );
        when( workContext.getProgramsMap() ).thenReturn( programMap );

        // Prepare event
        event.setProgram( program.getUid() );
        event.setStatus( EventStatus.COMPLETED );

        // When
        ImportSummary importSummary = rule.check( new ImmutableEvent( event ), workContext );

        // Then
        assertHasError( importSummary, event, "Event needs to have completed date" );
    }

    @Test
    public void failWhenProgramStageInstanceCompletedDateFallsAfterCurrentDay()
    {
        // Given

        // Prepare program
        Program program = createProgram( 'P' );
        program.setCompleteEventsExpiryDays( 3 );
        Map<String, Program> programMap = new HashMap<>();
        programMap.put( program.getUid(), program );
        when( workContext.getProgramsMap() ).thenReturn( programMap );

        // Prepare program stage instance
        Map<String, ProgramStageInstance> psiMap = new HashMap<>();
        ProgramStageInstance psi = new ProgramStageInstance();
        psi.setStatus( EventStatus.COMPLETED );
        psi.setCompletedDate( getTodayMinusDays( 5 ) );
        psi.setUid( event.getUid() );
        psiMap.put( event.getUid(), psi );
        when( workContext.getProgramStageInstanceMap() ).thenReturn( psiMap );

        // Prepare event
        event.setProgram( program.getUid() );
        event.setStatus( EventStatus.COMPLETED );

        // When
        ImportSummary importSummary = rule.check( new ImmutableEvent( event ), workContext );

        // Then
        assertHasError( importSummary, event,
            "The event's completeness date has expired. Not possible to make changes to this event" );
    }

    @Test
    public void failWhenProgramStageInstanceHasNoExecDateAndProgramHasPeriodType()
    {
        // Given

        // Prepare program
        Program program = createProgram( 'P' );
        program.setCompleteEventsExpiryDays( 3 );
        program.setExpiryPeriodType( PeriodType.getPeriodTypeFromIsoString( "202001" ) );
        program.setExpiryDays( 3 );
        Map<String, Program> programMap = new HashMap<>();
        programMap.put( program.getUid(), program );
        when( workContext.getProgramsMap() ).thenReturn( programMap );

        // Prepare program stage instance
        Map<String, ProgramStageInstance> psiMap = new HashMap<>();
        ProgramStageInstance psi = new ProgramStageInstance();
        psi.setCompletedDate( getTodayPlusDays( 5 ) );
        psi.setUid( event.getUid() );
        psiMap.put( event.getUid(), psi );
        when( workContext.getProgramStageInstanceMap() ).thenReturn( psiMap );

        // Prepare event
        event.setProgram( program.getUid() );

        // When
        ImportSummary importSummary = rule.check( new ImmutableEvent( event ), workContext );

        // Then
        assertHasError( importSummary, event, "Event needs to have event date" );
    }

    @Test
    public void failWhenProgramStageInstanceHasExecutionDateBeforeAllowedProgramExpiryDaysBasedOnPeriod()
    {
        // Given
        final String monthlyPeriodType = new SimpleDateFormat( "yyyyMM" ).format( new Date() );
        // Prepare program
        Program program = createProgram( 'P' );
        program.setExpiryPeriodType( PeriodType.getPeriodTypeFromIsoString( monthlyPeriodType ) );
        program.setExpiryDays( 3 );
        Map<String, Program> programMap = new HashMap<>();
        programMap.put( program.getUid(), program );
        when( workContext.getProgramsMap() ).thenReturn( programMap );

        // Prepare program stage instance
        Map<String, ProgramStageInstance> psiMap = new HashMap<>();
        ProgramStageInstance psi = new ProgramStageInstance();
        psi.setExecutionDate( getTodayMinusDays( 35 ) ); // month length + 5 days
        psi.setUid( event.getUid() );
        psiMap.put( event.getUid(), psi );
        when( workContext.getProgramStageInstanceMap() ).thenReturn( psiMap );

{'fraction_non_alphanumeric': 0.10496830311071798, 'fraction_numerical': 0.003464543712221731, 'mean_word_length': 2.941603718768158, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6547457', 'n_tokens_mistral': 3854, 'n_tokens_neox': 3710, 'n_words': 851}