@Test
  public void shouldUpdateCurrentPriceOfProgramProduct() throws Exception {
    ProgramProduct programProduct = make(a(ProgramProductBuilder.defaultProgramProduct));
    programProductRepository.updateCurrentPrice(programProduct);

    verify(programProductMapper).updateCurrentPrice(programProduct);
  }
 @Test
 public void shouldThrowExceptionIfNoProgramProductExistForGivenProgramIdAndProductId() {
   when(programProductMapper.getIdByProgramAndProductId(1L, 2L)).thenReturn(null);
   expectedEx.expect(DataException.class);
   expectedEx.expectMessage("programProduct.product.program.invalid");
   programProductRepository.getIdByProgramIdAndProductId(1L, 2L);
 }
  @Test
  public void shouldGetProgramProductIdByProgramAndProductId() {
    when(programProductMapper.getIdByProgramAndProductId(1L, 2L)).thenReturn(3L);

    assertThat(programProductRepository.getIdByProgramIdAndProductId(1L, 2L), is(3L));
    verify(programProductMapper).getIdByProgramAndProductId(1L, 2L);
  }
  @Test
  public void shouldInsertNewCostWithStartDateAsCurrentAndCloseLastPeriodsCostWithEndDateAsCurrent()
      throws Exception {
    ProgramProductPrice programProductPrice = new ProgramProductPrice();
    programProductRepository.updatePriceHistory(programProductPrice);

    verify(programProductPriceMapper).closeLastActivePrice(programProductPrice);
    verify(programProductPriceMapper).insertNewCurrentPrice(programProductPrice);
  }
  @Test
  public void shouldThrowErrorWhenInsertingInvalidProductForAProgram() {
    Program program = make(a(defaultProgram));
    when(programRepository.getIdByCode(program.getCode())).thenReturn(1L);
    ProgramProduct programProduct = new ProgramProduct(program, new Product(), 10, true);

    expectedEx.expect(Matchers.dataExceptionMatcher("product.code.invalid"));

    programProductRepository.save(programProduct);
  }
  @Test
  public void shouldGetProgramProductsByProgram() {
    Program program = new Program();
    List<ProgramProduct> expectedProgramProducts = new ArrayList<>();
    when(programProductMapper.getByProgram(program)).thenReturn(expectedProgramProducts);

    List<ProgramProduct> programProducts = programProductRepository.getByProgram(program);

    verify(programProductMapper).getByProgram(program);
    assertThat(programProducts, is(expectedProgramProducts));
  }
  @Test
  public void shouldThrowErrorWhenInsertingProductForInvalidProgram() {
    Product product = make(a(defaultProduct));
    Program program = make(a(defaultProgram));
    ProgramProduct programProduct = new ProgramProduct(program, product, 10, true);
    when(programRepository.getIdByCode(programProduct.getProgram().getCode()))
        .thenThrow(new DataException("exception"));

    expectedEx.expect(DataException.class);
    expectedEx.expectMessage("exception");
    programProductRepository.save(programProduct);
  }
  @Test
  public void shouldInsertProgramForAProduct() {
    Program program = new Program();
    program.setCode("P1");
    Product product = new Product();
    product.setCode("P2");
    ProgramProduct programProduct = new ProgramProduct(program, product, 10, true);
    programProduct.setModifiedDate(new Date());

    when(programProductMapper.getByProgramAndProductId(anyLong(), anyLong())).thenReturn(null);

    programProductRepository.save(programProduct);
    verify(programProductMapper).insert(programProduct);
  }
  @Test
  public void shouldUpdateProgramProductIfExist() throws Exception {
    Long programId = 88L;
    Long productId = 99L;

    programProduct.setId(1L);
    when(programRepository.getIdByCode(anyString())).thenReturn(programId);
    when(productRepository.getIdByCode(anyString())).thenReturn(productId);

    programProductRepository.save(programProduct);

    assertThat(programProduct.getProgram().getId(), is(88L));
    assertThat(programProduct.getProduct().getId(), is(99L));
    verify(programProductMapper).update(programProduct);
  }
  @Test
  public void shouldGetProgramProductByProgramAndProductCodes() throws Exception {
    ProgramProduct programProduct = make(a(ProgramProductBuilder.defaultProgramProduct));

    final Long programId = 123L;
    when(programRepository.getIdByCode(PROGRAM_CODE)).thenReturn(programId);
    final Long productId = 12L;
    when(productRepository.getIdByCode(PRODUCT_CODE)).thenReturn(productId);
    ProgramProduct expectedProgramProduct = new ProgramProduct();
    when(programProductMapper.getByProgramAndProductId(programId, productId))
        .thenReturn(expectedProgramProduct);

    ProgramProduct result = programProductRepository.getByProgramAndProductCode(programProduct);
    verify(programRepository).getIdByCode(PROGRAM_CODE);
    verify(productRepository).getIdByCode(PRODUCT_CODE);
    verify(programProductMapper).getByProgramAndProductId(programId, productId);

    assertThat(result, is(expectedProgramProduct));
  }
  @Test
  public void shouldUpdateProgramProduct() throws Exception {
    programProductRepository.updateProgramProduct(programProduct);

    verify(programProductMapper).update(programProduct);
  }