ProgramObjectBundleHook extends
    AbstractObjectBundleHook { @Override public <T extends IdentifiableObject> List<ErrorReport> validate( T object, ObjectBundle bundle ) { List<ErrorReport> errors = new ArrayList<>(); if ( !isProgram( object ) ) { return errors; } Program program = (Program) object; if ( program.getId() != 0 && getProgramInstancesCount( program ) > 1 ) { errors.add( new ErrorReport( Program.class, ErrorCode.E6000, program.getName() ) ); } errors.addAll( validateAttributeSecurity( program, bundle ) ); return errors; } ProgramObjectBundleHook( ProgramInstanceService programInstanceService, ProgramService programService,
        ProgramStageService programStageService, AclService aclService ); @Override void postCreate( IdentifiableObject object, ObjectBundle bundle ); @Override void postUpdate( IdentifiableObject object, ObjectBundle bundle ); @Override List<ErrorReport> validate( T object, ObjectBundle bundle );  }
@Test public void verifyProgramValidates() { assertEquals( 0, subject.validate( programA, null ).size() ); }
@Test public void verifyProgramFailsValidation() { ProgramInstanceQueryParams programInstanceQueryParams = new ProgramInstanceQueryParams(); programInstanceQueryParams.setProgram( programA ); programInstanceQueryParams.setProgramStatus( ProgramStatus.ACTIVE ); when( programInstanceService.getProgramInstances( programA, ProgramStatus.ACTIVE ) ) .thenReturn( Lists.newArrayList( new ProgramInstance(), new ProgramInstance() ) ); List<ErrorReport> errors = subject.validate( programA, null ); assertEquals( 1, errors.size() ); assertEquals( errors.get( 0 ).getErrorCode(), ErrorCode.E6000 ); assertEquals( errors.get( 0 ).getMessage(), "Program `ProgramA` has more than one Program Instances" ); }
@Test public void verifyValidationIsSkippedWhenObjectIsTransient() { Program transientObj = createProgram( 'A' ); subject.validate( transientObj, null ); verifyNoInteractions( programInstanceService ); }