Summary Table

Categories Total Count
PII 0
URL 0
DNS 0
EKL 0
IP 0
PORT 0
VsID 0
CF 0
AI 0
VPD 0
PL 0
Other 0

File Content

/*
* SeocServiceTest.java
* Copyright (c) 2017 Veterans Affairs.
*/
package gov.va.oneconsult.seoc.api.service;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.http.HttpStatus;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import gov.va.oneconsult.seoc.api.controller.SeocObjectGenerator;
import gov.va.oneconsult.seoc.api.exceptions.CodeRequiredNotValidException;
import gov.va.oneconsult.seoc.api.exceptions.SeocConstraintViolationException;
import gov.va.oneconsult.seoc.api.exceptions.SeocEffectiveDateNotValidException;
import gov.va.oneconsult.seoc.api.json.CreateBillingCodeRequest;
import gov.va.oneconsult.seoc.api.json.CreateServiceRequest;
import gov.va.oneconsult.seoc.api.json.SeocActivateRequest;
import gov.va.oneconsult.seoc.api.json.SeocCreateRequest;
import gov.va.oneconsult.seoc.api.json.SeocCreateResponse;
import gov.va.oneconsult.seoc.api.json.SeocGenericResponse;
import gov.va.oneconsult.seoc.api.model.BillingCode;
import gov.va.oneconsult.seoc.api.model.ClinicalService;
import gov.va.oneconsult.seoc.api.model.CodeRequired;
import gov.va.oneconsult.seoc.api.model.Hptc;
import gov.va.oneconsult.seoc.api.model.PayableService;
import gov.va.oneconsult.seoc.api.model.Seoc;
import gov.va.oneconsult.seoc.api.model.ServiceHptc;
import gov.va.oneconsult.seoc.api.model.ServiceHptcId;
import gov.va.oneconsult.seoc.api.model.ServiceLine;
import gov.va.oneconsult.seoc.api.model.Status;
import gov.va.oneconsult.seoc.api.repository.BillingCodeRepository;
import gov.va.oneconsult.seoc.api.repository.PayableServiceRepository;
import gov.va.oneconsult.seoc.api.repository.SeocRepository;
import gov.va.oneconsult.seoc.api.repository.ServiceHptcRepository;
import gov.va.oneconsult.seoc.api.service.impl.SeocServiceHelper;
import gov.va.oneconsult.seoc.api.service.impl.SeocServiceImpl;
import gov.va.oneconsult.seoc.api.threadlocal.Context;
import gov.va.oneconsult.seoc.api.threadlocal.SeocThreadLocal;
import gov.va.oneconsult.seoc.api.util.ApiUtil;
import gov.va.oneconsult.seoc.api.util.Constants;
import gov.va.oneconsult.seoc.api.util.TestUtil;

/**
* Description: SeocService Level Test Cases
*
* @author AbleVets
*/
@RunWith(SpringJUnit4ClassRunner.class)

public class SeocServiceTest {
@Mock
private SeocRepository seocRepository;

@Mock
private PayableServiceRepository serviceRepository;

@Mock
private BillingCodeRepository billingCodeRepository;

@Mock
private GenericService genericService;

@Mock
private ServiceHptcRepository serviceHptcRepository;

@InjectMocks
private SeocService seocService = new SeocServiceImpl();

private Status inprogress;

private Status dateHold;

@Before
public void setUp() {
inprogress = SeocObjectGenerator.getStatus(1, Constants.STATUS_INPROGRESS);
dateHold = SeocObjectGenerator.getStatus(1, Constants.STATUS_DATEHOLD);
MockitoAnnotations.initMocks(this);
}

/**
* Description: Find seoc by Id
*/
@Test
public void testGetSeocById() {

int id = 1;

Seoc seocExpected = SeocObjectGenerator.getSeoc(id, "Seoc Test 1.0.1", 0, null, null, null, "disclaimer", 6,
"description", true, "proceduralOverview", 10, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, inprogress, null, null);

Mockito.when(seocRepository.findById(id)).thenReturn(seocExpected);

Seoc seocFound = seocRepository.findById(id);
assertEquals(seocFound, seocExpected);

ArgumentCaptor<Integer> argCaptor = ArgumentCaptor.forClass(Integer.class);
Mockito.verify(seocRepository, Mockito.times(1)).findById(argCaptor.capture());
Mockito.verifyNoMoreInteractions(seocRepository);
}

/**
* Description: Find Seoc by name
*/
@Test
public void testGetSeocByName() {

String name = "Seoc Test 1.0.1";

Seoc seocExpected = SeocObjectGenerator.getSeoc(name, 0, null, null, null, "disclaimer", 6, "description", true,
"proceduralOverview", 10, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, null, null);
Set<Seoc> seocsWithSameName = new HashSet<Seoc>();
seocsWithSameName.add(seocExpected);
Mockito.when(seocRepository.findByName(name)).thenReturn(seocsWithSameName);

Set<Seoc> seocsFound = seocRepository.findByName(name);
assertEquals(seocsFound, seocsWithSameName);

ArgumentCaptor<String> argCaptor = ArgumentCaptor.forClass(String.class);
Mockito.verify(seocRepository, Mockito.times(1)).findByName(argCaptor.capture());
Mockito.verifyNoMoreInteractions(seocRepository);
}

/**
* Description: Find Seoc by name match
*/
@Test
public void testGetSeocByNameMatch() {

String name1 = "Seoc Test 1.0.1";
String name2 = "Seoc Test 1.0.2";
String searchString = "test";

Seoc seocTest1Expected = SeocObjectGenerator.getSeoc(name1, 0, null, null, null, "disclaimer", 6, "description",
true, "proceduralOverview", 10, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, inprogress, null, null);
Seoc seocTest2Expected = SeocObjectGenerator.getSeoc(name2, 0, null, null, null, "disclaimer", 6, "description",
true, "proceduralOverview", 10, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, inprogress, null, null);

Set<Seoc> expectedSet = new HashSet<Seoc>();
expectedSet.add(seocTest1Expected);
expectedSet.add(seocTest2Expected);

Mockito.when(seocRepository.findSeocByNameMatch(searchString)).thenReturn(expectedSet);

Set<Seoc> seocSetFound = seocRepository.findSeocByNameMatch(searchString);

assertThat(seocSetFound).hasSize(expectedSet.size()).contains(seocTest1Expected, seocTest2Expected);

ArgumentCaptor<String> argCaptor = ArgumentCaptor.forClass(String.class);
Mockito.verify(seocRepository, Mockito.times(1)).findSeocByNameMatch(argCaptor.capture());
Mockito.verifyNoMoreInteractions(seocRepository);
}

/**
* Description: Find Seocs by seocKey
*/
@Test
public void testGetSeocBySeocKey() {

String name1 = "Seoc Test 1.0.1";
String name2 = "Seoc Test 1.0.2";
Integer seocKey = 1;

Seoc seocTest1Expected = SeocObjectGenerator.getSeoc(name1, 1, null, null, null, "disclaimer", 6, "description",
true, "proceduralOverview", 10, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, inprogress, null, null);
Seoc seocTest2Expected = SeocObjectGenerator.getSeoc(name2, 1, null, null, null, "disclaimer", 6, "description",
true, "proceduralOverview", 10, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, inprogress, null, null);

Set<Seoc> expectedSet = new HashSet<Seoc>();
expectedSet.add(seocTest1Expected);
expectedSet.add(seocTest2Expected);

Mockito.when(seocRepository.findBySeocKey(seocKey)).thenReturn(expectedSet);

Set<Seoc> seocSetFound = seocRepository.findBySeocKey(seocKey);

assertThat(seocSetFound).hasSize(expectedSet.size()).contains(seocTest1Expected, seocTest2Expected);

ArgumentCaptor<Integer> argCaptor = ArgumentCaptor.forClass(Integer.class);
Mockito.verify(seocRepository, Mockito.times(1)).findBySeocKey(argCaptor.capture());
Mockito.verifyNoMoreInteractions(seocRepository);
}

/**
* Description:Checking for Seoc with name and no key - Seoc with name is found
* in the database - FAILURE
*/
@Test
public void isSeocAvailableSeocNameNotAvailableForCreation() {
String name = "Seoc Test";
int seocKey = 0;

Seoc seocExpected = SeocObjectGenerator.getSeoc(name, 0, null, null, null, "disclaimer", 6, "description", true,
"proceduralOverview", 10, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, null, null);
Set<Seoc> seocsWithSameName = new HashSet<Seoc>();
seocsWithSameName.add(seocExpected);

Mockito.when(seocRepository.findDuplicateSeocNames(name)).thenReturn(seocsWithSameName);

boolean seocAvailable = seocService.isSeocAvailable(seocKey, name);
assertThat(seocAvailable).isFalse();

Mockito.verify(seocRepository, Mockito.times(1)).findDuplicateSeocNames(Mockito.anyString());

Mockito.verifyNoMoreInteractions(seocRepository);
}

/**
* Description:Checking for Seoc with name and no key - Seoc with name is not
* found in the database - SUCCESS
*/
@Test
public void isSeocAvailableSeocNameAvailableForCreation() {
String name = "Seoc Test";
int seocKey = 0;
Set<Seoc> seocsWithSameName = new HashSet<Seoc>();

Mockito.when(seocRepository.findDuplicateSeocNames(name)).thenReturn(seocsWithSameName);

boolean seocAvilable = seocService.isSeocAvailable(seocKey, name);

assertThat(seocAvilable).isTrue();

Mockito.verify(seocRepository, Mockito.times(1)).findDuplicateSeocNames(Mockito.anyString());
Mockito.verifyNoMoreInteractions(seocRepository);
}


@Test
public void isSeocAvailableSeocNameWithSpacesAvail() {
String name = "Seoc Test";
int seocKey = 0;
Set<Seoc> seocsWithSameName = new HashSet<Seoc>();

Mockito.when(seocRepository.findDuplicateSeocNames(name)).thenReturn(seocsWithSameName);

boolean seocAvilable = seocService.isSeocAvailable(seocKey, name);

assertThat(seocAvilable).isTrue();

Mockito.verify(seocRepository, Mockito.times(1)).findDuplicateSeocNames(Mockito.anyString());
Mockito.verifyNoMoreInteractions(seocRepository);
}




/**
* Description:Editing seoc name with key 1 to a value where only seocs with
* same name and key combination exists - SUCCESS
*/
@Test
public void isSeocAvailableIgnoreCase() {
String name = "Seoc Test";
int seocKey = 1;

Seoc seocExpectedSameName1 = SeocObjectGenerator.getSeoc(1, name, seocKey, null, null, null, "disclaimer", 6,
"description", true, "proceduralOverview", 10, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, inprogress, null, null);
Seoc seocExpectedSameName2 = SeocObjectGenerator.getSeoc(2, name, seocKey, null, null, null, "disclaimer", 6,
"description", true, "proceduralOverview", 10, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, inprogress, null, null);
Seoc seocNameWithUpercase = SeocObjectGenerator.getSeoc(3, "SEOC TEST", 2, null, null, null,
"disclaimer", 6, "description", true, "proceduralOverview", 10, null, null, null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, inprogress, null, null);
Set<Seoc> seocsWithSameName = new HashSet<Seoc>();
seocsWithSameName.add(seocExpectedSameName1);
seocsWithSameName.add(seocExpectedSameName2);
seocsWithSameName.add(seocNameWithUpercase);

Mockito.when(seocRepository.findDuplicateSeocNames(name)).thenReturn(seocsWithSameName);

boolean seocAvilable = seocService.isSeocAvailable(seocKey, name);
assertThat(seocAvilable).isFalse();

Mockito.verify(seocRepository, Mockito.times(1)).findDuplicateSeocNames(Mockito.anyString());

Mockito.verifyNoMoreInteractions(seocRepository);
}










@Test
public void isSeocAvailableCallForEditSeocFound() {
String name = "Seoc Test";
int seocKey = 1;

Seoc seocExpectedSameName1 = SeocObjectGenerator.getSeoc(1, name, seocKey, null, null, null, "disclaimer", 6,
"description", true, "proceduralOverview", 10, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, inprogress, null, null);
Seoc seocExpectedSameName2 = SeocObjectGenerator.getSeoc(2, name, seocKey, null, null, null, "disclaimer", 6,
"description", true, "proceduralOverview", 10, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, inprogress, null, null);
Seoc seocExpectedDifferentName = SeocObjectGenerator.getSeoc(3, "Seoc Another Test", 2, null, null, null,
"disclaimer", 6, "description", true, "proceduralOverview", 10, null, null, null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, inprogress, null, null);
Set<Seoc> seocsWithSameName = new HashSet<Seoc>();
seocsWithSameName.add(seocExpectedSameName1);
seocsWithSameName.add(seocExpectedSameName2);
seocsWithSameName.add(seocExpectedDifferentName);

Mockito.when(seocRepository.findDuplicateSeocNames(name)).thenReturn(seocsWithSameName);

boolean seocAvilable = seocService.isSeocAvailable(seocKey, name);
assertThat(seocAvilable).isTrue();

Mockito.verify(seocRepository, Mockito.times(1)).findDuplicateSeocNames(Mockito.anyString());

Mockito.verifyNoMoreInteractions(seocRepository);
}








/**
* Description:Editing seoc name with key 1 to a value where alraedy a seoc
* exists with that name and seoc key 2 - FAILURE
*/
@Test
public void isSeocAvailableCallForEditSeocNotFound() {
String name = "Seoc Test";
String editedName = "Seoc Edited Name";
int availableWithSeocKey = 2;
int seocKey = 1;

Seoc seocExpectedSameName1 = SeocObjectGenerator.getSeoc(1, name, seocKey, null, null, null, "disclaimer", 6,
"description", true, "proceduralOverview", 10, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, inprogress, null, null);
Seoc seocExpectedSameName2 = SeocObjectGenerator.getSeoc(2, name, seocKey, null, null, null, "disclaimer", 6,
"description", true, "proceduralOverview", 10, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, inprogress, null, null);
Seoc seocExpectedWithEditedName = SeocObjectGenerator.getSeoc(3, editedName, availableWithSeocKey, null, null,
null, "disclaimer", 6, "description", true, "proceduralOverview", 10, null, null, null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, inprogress, null, null);
Set<Seoc> seocsWithSameName = new HashSet<Seoc>();
seocsWithSameName.add(seocExpectedSameName1);
seocsWithSameName.add(seocExpectedSameName2);
seocsWithSameName.add(seocExpectedWithEditedName);
// Modified
Mockito.when(seocRepository.findDuplicateSeocNames(editedName)).thenReturn(seocsWithSameName);

boolean seocAvilable = seocService.isSeocAvailable(seocKey, editedName);
assertThat(seocAvilable).isFalse();


Mockito.verify(seocRepository, Mockito.times(1)).findDuplicateSeocNames(editedName);

Mockito.verifyNoMoreInteractions(seocRepository);
}

/**
* Description: Throw CodeRequiredNotValidException exception when Code Required
* is NO and billing codes are available in the request
*/
@Test(expected = CodeRequiredNotValidException.class)
public void readServicesCustomExceptionWithBillingCodes() {
Set<String> billingCodes = new HashSet<String>();
billingCodes.add("testBC1");
billingCodes.add("testBC2");
CreateServiceRequest serviceRequest = CreateServiceRequest.Builder.create().withDescription("service1")
.withCodeRequired("NO").withBillingCodes(billingCodes).build();

List<CreateServiceRequest> requestList = new ArrayList<CreateServiceRequest>();
requestList.add(serviceRequest);

Seoc parentSeoc = new Seoc();

List<PayableService> services = ((SeocServiceImpl) seocService).readServices(parentSeoc, requestList);

assertThat(services).isEmpty();
}

/**
* Description: Throw CodeRequiredNotValidException exception when Code Required
* is YES and billing codes are not available in the request
*/
@Test(expected = CodeRequiredNotValidException.class)
public void readServicesCustomExceptionNoBillingCodes() {
Set<String> billingCodes = new HashSet<String>();

CreateServiceRequest serviceRequest = CreateServiceRequest.Builder.create().withDescription("service1")
.withCodeRequired("YES").withBillingCodes(billingCodes).build();

List<CreateServiceRequest> requestList = new ArrayList<CreateServiceRequest>();
requestList.add(serviceRequest);

Seoc parentSeoc = new Seoc();

List<PayableService> services = ((SeocServiceImpl) seocService).readServices(parentSeoc, requestList);

assertThat(services).isEmpty();
}

/**
* Description: Successful creation of a new SEOC
*
* NOTE: For some reason, converting the name of this test to camelcase causes a
* NullPointer exception
*/
@Test
public void saveSeoc_createdSuccessfully() {

SeocCreateResponse seocResponse = new SeocCreateResponse();
seocResponse.setAction("Save");
seocResponse.setStatus("Created");
seocResponse.setName("Test");
seocResponse.setSeocKey(1);
seocResponse.setUniqueId(1);

SeocCreateRequest seocRequest = SeocCreateRequest.Builder.create("Test", "sl").withMaxVisits(0).withDuration(0)
.withDisclaimer("disclaimer").withDescription("description").build();

Seoc seoc = SeocObjectGenerator.getSeoc(0, "Test", 1, null, null, null, "disclaimer", 0, "description", null,
null, 0, null, null, null, null, null, SeocObjectGenerator.sl1, inprogress, null, null);
seoc.setServices(new ArrayList<PayableService>());

Integer seocKeyReturned = new Integer(0);

Seoc seocReturned = SeocObjectGenerator.getSeoc(1, "Test", 1, null, null, null, "disclaimer", 6, "description",
true, "proceduralOverview", 10, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, inprogress, null, null);

ServiceLine sl = SeocObjectGenerator.sl1;

Mockito.when(genericService.getServiceLineByFullDescription("sl")).thenReturn(sl);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

Mockito.when(seocRepository.findMaxSeocKey()).thenReturn(Optional.of(seocKeyReturned));

Mockito.when(seocRepository.save(seoc)).thenReturn(seocReturned);

// SaveSeoc
SeocCreateResponse seocResponseFound = seocService.saveSeoc(seocRequest);

// Assert that response object is coming as expected
assertThat(seocResponseFound.getAction()).isEqualTo(seocResponse.getAction());
assertThat(seocResponseFound.getName()).isEqualTo(seocResponse.getName());
assertThat(seocResponseFound.getSeocKey()).isEqualTo(seocResponse.getSeocKey());
assertThat(seocResponseFound.getUniqueId()).isEqualTo(seocResponse.getUniqueId());
assertThat(seocResponseFound.getStatus()).isEqualTo(seocResponse.getStatus());

ArgumentCaptor<String> argStrCaptor = ArgumentCaptor.forClass(String.class);
Mockito.verify(genericService, Mockito.times(1)).getServiceLineByFullDescription(argStrCaptor.capture());

Mockito.verify(genericService, Mockito.times(1)).getStatusByDescription(argStrCaptor.capture());

ArgumentCaptor<Seoc> argSeocCaptor = ArgumentCaptor.forClass(Seoc.class);
Mockito.verify(seocRepository, Mockito.times(1)).save(argSeocCaptor.capture());

Mockito.verify(seocRepository, Mockito.times(1)).findMaxSeocKey();

Mockito.verifyNoMoreInteractions(genericService);
Mockito.verifyNoMoreInteractions(seocRepository);

}

/**
* Description: Successful creation of a new SEOC
*/
@Test
public void saveSeocServiceLineDiscontinued() {

SeocCreateResponse seocResponse = new SeocCreateResponse();
seocResponse.setStatus("Failure");
seocResponse.setComments("The Service Line value " + SeocObjectGenerator.sl3.getDescription()
+ " has been discontinued. A valid Service Line must be selected.");

SeocCreateRequest seocRequest = SeocCreateRequest.Builder.create("Test", "sl").withMaxVisits(0).withDuration(0)
.withDisclaimer("disclaimer").withDescription("description").build();

Seoc seoc = SeocObjectGenerator.getSeoc(0, "Test", 1, null, null, null, "disclaimer", 0, "description", null,
null, 0, null, null, null, null, null, SeocObjectGenerator.sl3, inprogress, null, null);
seoc.setServices(new ArrayList<PayableService>());

ServiceLine sl = SeocObjectGenerator.sl3;

Mockito.when(genericService.getServiceLineByFullDescription("sl")).thenReturn(sl);

// SaveSeoc
SeocCreateResponse seocResponseFound = seocService.saveSeoc(seocRequest);

// Assert that response object is coming as expected
assertThat(seocResponseFound.getComments()).isEqualTo(seocResponse.getComments());
assertThat(seocResponseFound.getStatus()).isEqualTo(seocResponse.getStatus());

ArgumentCaptor<String> argStrCaptor = ArgumentCaptor.forClass(String.class);
Mockito.verify(genericService, Mockito.times(1)).getServiceLineByFullDescription(argStrCaptor.capture());
Mockito.verify(genericService, Mockito.times(0)).getStatusByDescription(argStrCaptor.capture());

ArgumentCaptor<Seoc> argSeocCaptor = ArgumentCaptor.forClass(Seoc.class);
Mockito.verify(seocRepository, Mockito.times(0)).save(argSeocCaptor.capture());

Mockito.verify(seocRepository, Mockito.times(0)).findMaxSeocKey();

Mockito.verifyNoMoreInteractions(genericService);
Mockito.verifyNoMoreInteractions(seocRepository);

}

/**
* Description: getSeocPendingRevision default
*/
@Test
public void getSeocPendingRevisionDefault() {
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 10, "1.0.1", effectiveDate, null, "disclaimer", 0,
"description", null, null, 0, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
dateHold, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "YES", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(2, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
service1.setBillingCodes(SeocObjectGenerator.bc2345Set);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Seoc seocCloned = SeocObjectGenerator.getSeoc(0, "Test", 10, "1.0.1", effectiveDate, null, "disclaimer", 0,
"description", null, null, 0, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
dateHold, SeocObjectGenerator.qasp1, null);
seocCloned.setServices(new ArrayList<PayableService>());

PayableService service1Cloned = SeocObjectGenerator.getPayableService(0, "Test Service1", 5, "weeks", 5, "YES",
null, null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2Cloned = SeocObjectGenerator.getPayableService(0, "Test Service2", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);
service1Cloned.setBillingCodes(SeocObjectGenerator.bc2345Set);
service2Cloned.setBillingCodes(new HashSet<BillingCode>());

seocCloned.getServices().add(service1Cloned);
seocCloned.getServices().add(service2Cloned);

seocCloned.setVersionNumber(Constants.VERSION_PENDING_REVISION);
seocCloned.setStatus(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS));
seocCloned.setActivatedBy(null);
seocCloned.setActivatedTimestamp(null);
seocCloned.setDiscontinuedBy(null);
seocCloned.setDiscontinuedTimestamp(null);
seocCloned.setEffectiveDate(null);
seocCloned.setEndDate(null);

Seoc pendingRevision = seocService.getSeocPendingRevision(seoc1);

assertThat(pendingRevision.toString()).isEqualTo(seocCloned.toString());
}

/**
* Description: getSeocPendingRevision null SEOC
*/
@Test
public void getSeocPendingRevisionNullSeoc() {
Seoc pendingRevision = seocService.getSeocPendingRevision(null);

assertThat(pendingRevision).isNull();
}

/**
* Description: getSeocPendingRevision noDeactivatedBillingCodes is false
*/
@Test
public void getSeocPendingRevisionNoDeactivatedBillingCodesFalse() {
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 10, "1.0.1", effectiveDate, null, "disclaimer", 0,
"description", null, null, 0, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
dateHold, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "YES", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(2, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
service1.setBillingCodes(SeocObjectGenerator.bc2345Set);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Seoc seocCloned = SeocObjectGenerator.getSeoc(0, "Test", 10, "1.0.1", effectiveDate, null, "disclaimer", 0,
"description", null, null, 0, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
dateHold, SeocObjectGenerator.qasp1, null);
seocCloned.setServices(new ArrayList<PayableService>());

PayableService service1Cloned = SeocObjectGenerator.getPayableService(0, "Test Service1", 5, "weeks", 5, "YES",
null, null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2Cloned = SeocObjectGenerator.getPayableService(0, "Test Service2", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);
service1Cloned.setBillingCodes(SeocObjectGenerator.bc2345Set);
service2Cloned.setBillingCodes(new HashSet<BillingCode>());

seocCloned.getServices().add(service1Cloned);
seocCloned.getServices().add(service2Cloned);

seocCloned.setVersionNumber(Constants.VERSION_PENDING_REVISION);
seocCloned.setStatus(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS));
seocCloned.setActivatedBy(null);
seocCloned.setActivatedTimestamp(null);
seocCloned.setDiscontinuedBy(null);
seocCloned.setDiscontinuedTimestamp(null);
seocCloned.setEffectiveDate(null);
seocCloned.setEndDate(null);

Seoc pendingRevision = seocService.getSeocPendingRevision(seoc1, false);

assertThat(pendingRevision.toString()).isEqualTo(seocCloned.toString());
}

/**
* Description: getSeocPendingRevision noDeactivatedBillingCodes is null
*/
@Test
public void getSeocPendingRevisionNoDeactivatedBillingCodesNull() {
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 10, "1.0.1", effectiveDate, null, "disclaimer", 0,
"description", null, null, 0, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
dateHold, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "YES", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(2, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
service1.setBillingCodes(SeocObjectGenerator.bc2345Set);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Seoc seocCloned = SeocObjectGenerator.getSeoc(0, "Test", 10, "1.0.1", effectiveDate, null, "disclaimer", 0,
"description", null, null, 0, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
dateHold, SeocObjectGenerator.qasp1, null);
seocCloned.setServices(new ArrayList<PayableService>());

PayableService service1Cloned = SeocObjectGenerator.getPayableService(0, "Test Service1", 5, "weeks", 5, "YES",
null, null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2Cloned = SeocObjectGenerator.getPayableService(0, "Test Service2", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);
service1Cloned.setBillingCodes(SeocObjectGenerator.bc2345Set);
service2Cloned.setBillingCodes(new HashSet<BillingCode>());

seocCloned.getServices().add(service1Cloned);
seocCloned.getServices().add(service2Cloned);

seocCloned.setVersionNumber(Constants.VERSION_PENDING_REVISION);
seocCloned.setStatus(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS));
seocCloned.setActivatedBy(null);
seocCloned.setActivatedTimestamp(null);
seocCloned.setDiscontinuedBy(null);
seocCloned.setDiscontinuedTimestamp(null);
seocCloned.setEffectiveDate(null);
seocCloned.setEndDate(null);

Seoc pendingRevision = seocService.getSeocPendingRevision(seoc1, null);

assertThat(pendingRevision.toString()).isEqualTo(seocCloned.toString());
}

/**
* Description: getSeocPendingRevision noDeactivatedBillingCodes is true
*/
@Test
public void getSeocPendingRevisionNoDeactivatedBillingCodesTrue() {
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 10, "1.0.1", effectiveDate, null, "disclaimer", 0,
"description", null, null, 0, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
dateHold, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "YES", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(2, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
service1.setBillingCodes(SeocObjectGenerator.bc2345Set);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Seoc seocCloned = SeocObjectGenerator.getSeoc(0, "Test", 10, "1.0.1", effectiveDate, null, "disclaimer", 0,
"description", null, null, 0, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
dateHold, SeocObjectGenerator.qasp1, null);
seocCloned.setServices(new ArrayList<PayableService>());

PayableService service1Cloned = SeocObjectGenerator.getPayableService(0, "Test Service1", 5, "weeks", 5, "YES",
null, null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2Cloned = SeocObjectGenerator.getPayableService(0, "Test Service2", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);
service1Cloned.setBillingCodes(SeocObjectGenerator.bc234Set);
service2Cloned.setBillingCodes(new HashSet<BillingCode>());

seocCloned.getServices().add(service1Cloned);
seocCloned.getServices().add(service2Cloned);

seocCloned.setVersionNumber(Constants.VERSION_PENDING_REVISION);
seocCloned.setStatus(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS));
seocCloned.setActivatedBy(null);
seocCloned.setActivatedTimestamp(null);
seocCloned.setDiscontinuedBy(null);
seocCloned.setDiscontinuedTimestamp(null);
seocCloned.setEffectiveDate(null);
seocCloned.setEndDate(null);

Seoc pendingRevision = seocService.getSeocPendingRevision(seoc1, true);

assertThat(pendingRevision.toString()).isEqualTo(seocCloned.toString());
}

/**
* Description: Create pending revision success
*/
@Test
public void createPendingRevisionSuccess() {
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 10, "1.0.1", effectiveDate, null, "disclaimer", 0,
"description", null, null, 0, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
dateHold, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

Seoc seocCloned = SeocObjectGenerator.getSeoc(0, "Test", 10, "1.0.1", effectiveDate, null, "disclaimer", 0,
"description", null, null, 0, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
dateHold, SeocObjectGenerator.qasp1, null);
seocCloned.setServices(new ArrayList<PayableService>());

seocCloned.setVersionNumber(Constants.VERSION_PENDING_REVISION);
seocCloned.setStatus(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS));
seocCloned.setActivatedBy(null);
seocCloned.setActivatedTimestamp(null);
seocCloned.setDiscontinuedBy(null);
seocCloned.setDiscontinuedTimestamp(null);
seocCloned.setEffectiveDate(null);
seocCloned.setEndDate(null);

Seoc seoc11 = SeocObjectGenerator.getSeoc(2, "Test", 10, Constants.VERSION_PENDING_REVISION, null, null,
"disclaimer", 0, "description", null, null, 0, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, inprogress, SeocObjectGenerator.qasp1, null);
seoc11.setServices(new ArrayList<PayableService>());

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

Set<Seoc> seocWithSameKey = new HashSet<Seoc>();
seocWithSameKey.add(seoc1);
Mockito.when(seocRepository.findBySeocKey(1)).thenReturn(seocWithSameKey);

Mockito.when(seocRepository.save(seocCloned)).thenReturn(seoc11);

SeocCreateResponse seocResponse = seocService.createPendingRevision(1);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.CREATED);

Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());
Mockito.verify(seocRepository, Mockito.times(1)).findBySeocKey(Mockito.anyInt());

ArgumentCaptor<Seoc> argSeocCaptor = ArgumentCaptor.forClass(Seoc.class);
Mockito.verify(seocRepository, Mockito.times(1)).save(argSeocCaptor.capture());
}

/**
* Description: Seoc requested for Creating Pending Revision has a status other
* than active
*/
@Test
public void createPendingRevisionSeocNotAvailable() {
int id = 1;
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 10, null, null, null, "disclaimer", 0, "description", null,
null, 0, null, null, null, null, null, SeocObjectGenerator.sl1, inprogress, null, null);
seoc1.setServices(new ArrayList<PayableService>());

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

SeocCreateResponse seocResponse = seocService.createPendingRevision(id);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);

Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());
}

/**
* Description: Seoc requested for Creating Pending Revision has an In-Progress
* status
*/
@Test
public void createPendingRevisionSeocInProgress() {
int id = 1;
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 10, null, null, null, "disclaimer", 0, "description", null,
null, 0, null, null, null, null, null, SeocObjectGenerator.sl1, inprogress, null, null);
seoc1.setServices(new ArrayList<PayableService>());

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

SeocCreateResponse seocResponse = seocService.createPendingRevision(id);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);
assertThat(seocResponse.getMessage()).isEqualTo(
"Seoc is not eligible for Pending revision. Current status of SEOC is " + Constants.STATUS_INPROGRESS);

Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());
}

/**
* Description: Seoc requested for Creating Pending Revision has a Date Hold
* status
*/
@Test
public void createPendingRevisionSeocDateHold() {
int id = 1;
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 10, "1.0.1", TestUtil.getEffectiveDateFuture(), null,
"disclaimer", 0, "description", null, null, 0, null, null, null, null, null, SeocObjectGenerator.sl1,
dateHold, null, null);
seoc1.setServices(new ArrayList<PayableService>());

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

SeocCreateResponse seocResponse = seocService.createPendingRevision(id);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);
assertThat(seocResponse.getMessage()).isEqualTo(
"Seoc is not eligible for Pending revision. Current status of SEOC is " + Constants.STATUS_DATEHOLD);

Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());
}

/**
* Description: Seoc requested for Creating Pending Revision has a Discontinued
* status
*/
@Test
public void createPendingRevisionSeocDiscontinued() {
int id = 1;
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 10, "1.0.1", TestUtil.getEffectiveDatePast(),
TestUtil.getEffectiveDatePast(), "disclaimer", 0, "description", null, null, 0, null, null, null, null,
null, SeocObjectGenerator.sl1, dateHold, null, null);
seoc1.setServices(new ArrayList<PayableService>());

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

SeocCreateResponse seocResponse = seocService.createPendingRevision(id);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);
assertThat(seocResponse.getMessage())
.isEqualTo("Seoc is not eligible for Pending revision. Current status of SEOC is "
+ Constants.STATUS_DISCONTINUED);

Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());
}

/**
* Description: Create pending revision failure
*/
@Test
public void createPendingRevisionFailurePendingRevisionAvailable() {
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 10, "1.0.1", effectiveDate, null, "disclaimer", 0,
"description", null, null, 0, null, null, null, null, null, SeocObjectGenerator.sl1, dateHold, null,
null);
seoc1.setServices(new ArrayList<PayableService>());

Seoc seoc11 = SeocObjectGenerator.getSeoc(2, "Test", 10, Constants.VERSION_PENDING_REVISION, null, null,
"disclaimer", 0, "description", null, null, 0, null, null, null, null, null, SeocObjectGenerator.sl1,
inprogress, null, null);
seoc11.setServices(new ArrayList<PayableService>());

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

Set<Seoc> seocWithSameKey = new HashSet<Seoc>();
seocWithSameKey.add(seoc11);
Mockito.when(seocRepository.findBySeocKey(10)).thenReturn(seocWithSameKey);

SeocCreateResponse seocResponse = seocService.createPendingRevision(1);

assertThat(seocResponse.getMessage())
.isEqualTo("Pending Revision Draft exists for another Seoc with same seoc key " + 10);
assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);

Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());
Mockito.verify(seocRepository, Mockito.times(1)).findBySeocKey(Mockito.anyInt());

}

/**
* Description: Valid pending revision success
*/
@Test
public void validPendingRevisionRevisionInMakingReturnsFalse() {
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 10, "1.0.1", effectiveDate, null, "disclaimer", 0,
"description", null, null, 0, null, null, null, null, null, SeocObjectGenerator.sl1, dateHold, null,
null);
seoc1.setServices(new ArrayList<PayableService>());

Seoc seoc11 = SeocObjectGenerator.getSeoc(2, "Test", 10, null, null, null, "disclaimer", 0, "description", null,
null, 0, null, null, null, null, null, SeocObjectGenerator.sl1, inprogress, null, null);
seoc11.setServices(new ArrayList<PayableService>());

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

Set<Seoc> seocWithSameKey = new HashSet<Seoc>();
seocWithSameKey.add(seoc1);
seocWithSameKey.add(seoc11);
Mockito.when(seocRepository.findBySeocKey(10)).thenReturn(seocWithSameKey);

SeocGenericResponse seocResponse = seocService.validPendingRevision(1);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
Mockito.verify(seocRepository, Mockito.times(1)).findBySeocKey(Mockito.anyInt());
}

/**
* Description: Valid pending revision failure
*/
@Test
public void validPendingRevisionRevisionInMakingReturnsTrue() {
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 10, "1.0.1", effectiveDate, null, "disclaimer", 0,
"description", null, null, 0, null, null, null, null, null, SeocObjectGenerator.sl1, dateHold, null,
null);
seoc1.setServices(new ArrayList<PayableService>());

Seoc seoc11 = SeocObjectGenerator.getSeoc(2, "Test", 10, Constants.VERSION_PENDING_REVISION, null, null,
"disclaimer", 0, "description", null, null, 0, null, null, null, null, null, SeocObjectGenerator.sl1,
inprogress, null, null);
seoc11.setServices(new ArrayList<PayableService>());

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

Set<Seoc> seocWithSameKey = new HashSet<Seoc>();
seocWithSameKey.add(seoc1);
seocWithSameKey.add(seoc11);
Mockito.when(seocRepository.findBySeocKey(10)).thenReturn(seocWithSameKey);

SeocGenericResponse seocResponse = seocService.validPendingRevision(1);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);
assertThat(seocResponse.getMessage())
.isEqualTo("Pending Revision Draft exists for another Seoc with same seoc key " + 10);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
Mockito.verify(seocRepository, Mockito.times(1)).findBySeocKey(Mockito.anyInt());
}

/**
* Description: Valid pending revision success
*/
@Test
public void validPendingRevisionRevisionInMakingReturnsNull() {
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 10, "1.0.1", effectiveDate, null, "disclaimer", 0,
"description", null, null, 0, null, null, null, null, null, SeocObjectGenerator.sl1, dateHold, null,
null);
seoc1.setServices(new ArrayList<PayableService>());

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

Set<Seoc> seocWithSameKey = null;
Mockito.when(seocRepository.findBySeocKey(10)).thenReturn(seocWithSameKey);

SeocGenericResponse seocResponse = seocService.validPendingRevision(1);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);
assertThat(seocResponse.getMessage()).isEqualTo("Pending revision can be created.");

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
Mockito.verify(seocRepository, Mockito.times(1)).findBySeocKey(Mockito.anyInt());
}

/**
* Description: Valid pending revision fails due to date hold status of pending
* revision
*/
@Test
public void validPendingRevisionRevisionInMakingIsDateHold() {
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 10, "1.0.1", effectiveDate, null, "disclaimer", 0,
"description", null, null, 0, null, null, null, null, null, SeocObjectGenerator.sl1, dateHold, null,
null);
seoc1.setServices(new ArrayList<PayableService>());

Seoc seoc11 = SeocObjectGenerator.getSeoc(2, "Test", 10, "1.0.2", TestUtil.getEffectiveDate(), null,
"disclaimer", 0, "description", null, null, 0, null, null, null, null, null, SeocObjectGenerator.sl1,
dateHold, null, null);
seoc11.setServices(new ArrayList<PayableService>());

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

Set<Seoc> seocWithSameKey = new HashSet<Seoc>();
seocWithSameKey.add(seoc1);
seocWithSameKey.add(seoc11);
Mockito.when(seocRepository.findBySeocKey(10)).thenReturn(seocWithSameKey);

SeocGenericResponse seocResponse = seocService.validPendingRevision(1);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);
assertThat(seocResponse.getMessage())
.isEqualTo("Pending Revision Draft exists for another Seoc with same seoc key " + 10);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
Mockito.verify(seocRepository, Mockito.times(1)).findBySeocKey(Mockito.anyInt());
}

/**
* Description: Valid pending revision fails due to status of In-Progress
*/
@Test
public void validPendingRevisionInProgress() {
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 10, null, null, null, "disclaimer", 0, "description", null,
null, 0, null, null, null, null, null, SeocObjectGenerator.sl1, inprogress, null, null);
seoc1.setServices(new ArrayList<PayableService>());

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

SeocGenericResponse seocResponse = seocService.validPendingRevision(1);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);
assertThat(seocResponse.getMessage()).isEqualTo(
"Seoc is not eligible for Pending revision. Current status of SEOC is " + Constants.STATUS_INPROGRESS);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
}

/**
* Description: Valid pending revision fails due to status of Date Hold
*/
@Test
public void validPendingRevisionDateHold() {
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 10, "1.0.1", TestUtil.getEffectiveDateFuture(), null,
"disclaimer", 0, "description", null, null, 0, null, null, null, null, null, SeocObjectGenerator.sl1,
dateHold, null, null);
seoc1.setServices(new ArrayList<PayableService>());

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

SeocGenericResponse seocResponse = seocService.validPendingRevision(1);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);
assertThat(seocResponse.getMessage()).isEqualTo(
"Seoc is not eligible for Pending revision. Current status of SEOC is " + Constants.STATUS_DATEHOLD);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
}

/**
* Description: Valid pending revision fails due to status of Discontinued
*/
@Test
public void validPendingRevisionDiscontinued() {
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 10, "1.0.1", TestUtil.getEffectiveDatePast(),
TestUtil.getEffectiveDatePast(), "disclaimer", 0, "description", null, null, 0, null, null, null, null,
null, SeocObjectGenerator.sl1, dateHold, null, null);
seoc1.setServices(new ArrayList<PayableService>());

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

SeocGenericResponse seocResponse = seocService.validPendingRevision(1);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);
assertThat(seocResponse.getMessage())
.isEqualTo("Seoc is not eligible for Pending revision. Current status of SEOC is "
+ Constants.STATUS_DISCONTINUED);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
}

/**
* Description: validActivate all required fields are available
*/
@Test
public void validActivateSeocSuccess() {
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 1, null, null, null, "disclaimer", 5, "Description", false,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

Set<BillingCode> billingCodes1 = new HashSet<BillingCode>();
Set<BillingCode> billingCodes2 = new HashSet<BillingCode>();

billingCodes1.add(SeocObjectGenerator.getBillingCode(1, "01234", "CPT", "Test BillingCode1", false));
billingCodes2.add(SeocObjectGenerator.getBillingCode(2, "12345", "CPT", "Test BillingCode3", false));

PayableService service1 = SeocObjectGenerator.getPayableService("Test Service1", 5, "weeks", 5, "YES", null,
null, SeocObjectGenerator.cs1Set, seoc1, billingCodes1);
PayableService service2 = SeocObjectGenerator.getPayableService("Test Service2", 5, "weeks", 5, "YES", null,
null, SeocObjectGenerator.cs1Set, seoc1, billingCodes2);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc1.setHptcs(hptcs);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);
Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

SeocGenericResponse seocResponse = seocService.validSeocActivate(1);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(2)).getStatusByDescription(Mockito.anyString());
}

/**
* Description: validActivate REV flag is false when PRCT is true
*/
@Test
public void validActivateSeocSuccessREVFalsePRCTTrue() {
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 1, null, null, null, "disclaimer", 5, "Description", false,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

Set<BillingCode> billingCodes1 = new HashSet<BillingCode>();
Set<BillingCode> billingCodes2 = new HashSet<BillingCode>();

billingCodes1.add(SeocObjectGenerator.getBillingCode(1, "01234", "CPT", "Test BillingCode1", false));
billingCodes2.add(SeocObjectGenerator.getBillingCode(2, "12345", "CPT", "Test BillingCode3", true));

PayableService service1 = SeocObjectGenerator.getPayableService("Test Service1", 5, "weeks", 5, "YES", null,
null, SeocObjectGenerator.cs1Set, seoc1, billingCodes1);
PayableService service2 = SeocObjectGenerator.getPayableService("Test Service2", 5, "weeks", 5, "YES", null,
null, SeocObjectGenerator.cs1Set, seoc1, billingCodes2);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc1.setHptcs(hptcs);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);
Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

SeocGenericResponse seocResponse = seocService.validSeocActivate(1);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(2)).getStatusByDescription(Mockito.anyString());

}

/**
* Description: validActivate REV flag is true when PRCT is true
*/
@Test
public void validActivateSeocSuccessREVTruePRCTTrue() {
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 1, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

Set<BillingCode> billingCodes1 = new HashSet<BillingCode>();
Set<BillingCode> billingCodes2 = new HashSet<BillingCode>();

billingCodes1.add(SeocObjectGenerator.getBillingCode(1, "01234", "CPT", "Test BillingCode1", false));
billingCodes2.add(SeocObjectGenerator.getBillingCode(2, "12345", "CPT", "Test BillingCode3", true));

PayableService service1 = SeocObjectGenerator.getPayableService("Test Service1", 5, "weeks", 5, "YES", null,
null, SeocObjectGenerator.cs1Set, seoc1, billingCodes1);
PayableService service2 = SeocObjectGenerator.getPayableService("Test Service2", 5, "weeks", 5, "YES", null,
null, SeocObjectGenerator.cs1Set, seoc1, billingCodes2);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc1.setHptcs(hptcs);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);
Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

SeocGenericResponse seocResponse = seocService.validSeocActivate(1);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(2)).getStatusByDescription(Mockito.anyString());

}

/**
* Description: validActivate REV flag is true when PRCT is true, Any Code
* Accepted
*/
@Test
public void validActivateSeocSuccessREVTruePRCTTrueAnyCodeAccepted() {
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 1, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

Set<BillingCode> billingCodes1 = new HashSet<BillingCode>();
billingCodes1.add(SeocObjectGenerator.getBillingCode(1, "01234", "CPT", "Test BillingCode1", false));

PayableService service1 = SeocObjectGenerator.getPayableService("Test Service1", 5, "weeks", 5, "YES", null,
null, SeocObjectGenerator.cs1Set, seoc1, billingCodes1);
PayableService service2 = SeocObjectGenerator.getPayableService(2, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc1.setHptcs(hptcs);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);
Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

SeocGenericResponse seocResponse = seocService.validSeocActivate(1);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(2)).getStatusByDescription(Mockito.anyString());

}

/**
* Description: validActivate REV flag is true when PRCT is true, No Code
* Required
*/
@Test
public void validActivateSeocSuccessREVTruePRCTTrueNoCodeRequired() {
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 1, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

Set<BillingCode> billingCodes1 = new HashSet<BillingCode>();
billingCodes1.add(SeocObjectGenerator.getBillingCode(1, "01234", "CPT", "Test BillingCode1", false));

PayableService service1 = SeocObjectGenerator.getPayableService("Test Service1", 5, "weeks", 5, "YES", null,
null, SeocObjectGenerator.cs1Set, seoc1, billingCodes1);
PayableService service2 = SeocObjectGenerator.getPayableService(2, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc1.setHptcs(hptcs);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);
Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

SeocGenericResponse seocResponse = seocService.validSeocActivate(1);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(2)).getStatusByDescription(Mockito.anyString());

}

/**
* Description: Active seoc found for the requested id
*/
@Test
public void validActivateSeocSeocActive() {
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 1, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
dateHold, SeocObjectGenerator.qasp1, null);

seoc1.setServices(new ArrayList<PayableService>());

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

SeocGenericResponse seocResponse = seocService.validSeocActivate(1);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);
assertThat(seocResponse.getMessage()).isNotEmpty();

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());

}

/**
* Description: No seoc for the requested id found
*/
@Test
public void validActivateSeocSeocNotFound() {
Seoc seoc1 = null;

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

SeocGenericResponse seocResponse = seocService.validSeocActivate(1);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());

}

/**
* Description: Constraint validation errors
*/
@Test(expected = SeocConstraintViolationException.class)
public void validActivateSeocFailure() {
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 1, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, null, null);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);
Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);
Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

SeocGenericResponse seocResponse = seocService.validSeocActivate(1);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(2)).getStatusByDescription(Mockito.anyString());

}

/**
* Description: Constraint validation errors
*/
@Test(expected = SeocConstraintViolationException.class)
public void validActivateSeocClinicalServicesMissingFailure() {
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 1, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, SeocObjectGenerator.qasp1, null);

Date today = ApiUtil.today_UTC();
seoc1.setServices(new ArrayList<PayableService>());
Set<ClinicalService> clinicalServices = new HashSet<ClinicalService>();

PayableService service1 = SeocObjectGenerator.getPayableService(1, "TestSeoc Service", 4, "Weeks", 5,
CodeRequired.ANY.getValue(), "System", today, clinicalServices, seoc1);
seoc1.getServices().add(service1);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);
seoc1.setHptcs(hptcs);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);
Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);
Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

SeocGenericResponse seocResponse = seocService.validSeocActivate(1);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(2)).getStatusByDescription(Mockito.anyString());

}

/**
* Description: Constraint validation errors - Service Line Discontinued
*/
@Test()
public void validActivateSeocServiceLineDiscontinuedFailure() {
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 1, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc3, SeocObjectGenerator.sl3,
inprogress, SeocObjectGenerator.qasp1, null);

Date today = ApiUtil.today_UTC();
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "TestSeoc Service", 4, "Weeks", 5,
CodeRequired.ANY.getValue(), "System", today, SeocObjectGenerator.cs1Set, seoc1);
seoc1.getServices().add(service1);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);
seoc1.setHptcs(hptcs);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);
Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);
Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

try {
seocService.validSeocActivate(1);
fail();
} catch (SeocConstraintViolationException e) {
assertThat(e.getConstraintViolations().toString())
.contains("The Service Line value " + SeocObjectGenerator.sl3.getDescription()
+ " has been discontinued. A valid Service Line must be selected.");

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(2)).getStatusByDescription(Mockito.anyString());
}
}

/**
* Description: Constraint validation errors - Category of Care Discontinued
*/
@Test()
public void validActivateSeocCategoryOfCareDiscontinuedFailure() {
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 1, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc4, SeocObjectGenerator.sl4,
inprogress, SeocObjectGenerator.qasp1, null);

Date today = ApiUtil.today_UTC();
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "TestSeoc Service", 4, "Weeks", 5,
CodeRequired.ANY.getValue(), "System", today, SeocObjectGenerator.cs1Set, seoc1);
seoc1.getServices().add(service1);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);
seoc1.setHptcs(hptcs);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);
Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);
Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

try {
seocService.validSeocActivate(1);
fail();
} catch (SeocConstraintViolationException e) {
assertThat(e.getConstraintViolations().toString())
.contains("The Category of Care value " + SeocObjectGenerator.cc4.getDescription()
+ " has been discontinued. A valid Category of Care must be selected.");

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(2)).getStatusByDescription(Mockito.anyString());
}
}

/**
* Description: Constraint validation errors - Qasp Discontinued
*/
@Test()
public void validActivateSeocQaspDiscontinuedFailure() {
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 1, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, SeocObjectGenerator.qasp3, null);

Date today = ApiUtil.today_UTC();
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "TestSeoc Service", 4, "Weeks", 5,
CodeRequired.ANY.getValue(), "System", today, SeocObjectGenerator.cs1Set, seoc1);
seoc1.getServices().add(service1);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);
seoc1.setHptcs(hptcs);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);
Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);
Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

try {
seocService.validSeocActivate(1);
fail();
} catch (SeocConstraintViolationException e) {
assertThat(e.getConstraintViolations().toString())
.contains("The QASP value " + SeocObjectGenerator.qasp3.getDescription()
+ " has been discontinued. A valid QASP must be selected.");

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(2)).getStatusByDescription(Mockito.anyString());
}
}

/**
* Description: Constraint validation errors - Clinical Service Discontinued
*/
@Test()
public void validActivateSeocClinicalServiceDiscontinuedFailure() {
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 1, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, SeocObjectGenerator.qasp1, null);

Date today = ApiUtil.today_UTC();
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "TestSeoc Service", 4, "Weeks", 5,
CodeRequired.ANY.getValue(), "System", today, SeocObjectGenerator.cs4Set, seoc1);
seoc1.getServices().add(service1);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);
seoc1.setHptcs(hptcs);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);
Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);
Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

try {
seocService.validSeocActivate(1);
fail();
} catch (SeocConstraintViolationException e) {
assertThat(e.getConstraintViolations().toString())
.contains("The Clinical Service value " + SeocObjectGenerator.cs4.getDescription()
+ " has been discontinued. A valid Clinical Service must be selected.");

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(2)).getStatusByDescription(Mockito.anyString());
}
}

/**
* Description: Constraint validation errors - REV flag set to true and no
* services require pre-certification
*/
@Test()
public void validActivateSeocREVTrueWithoutPRCT() {
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 1, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

Set<BillingCode> billingCodes1 = new HashSet<BillingCode>();
Set<BillingCode> billingCodes2 = new HashSet<BillingCode>();

billingCodes1.add(SeocObjectGenerator.getBillingCode(1, "01234", "CPT", "Test BillingCode1", false));
billingCodes2.add(SeocObjectGenerator.getBillingCode(2, "12345", "CPT", "Test BillingCode2", false));

PayableService service1 = SeocObjectGenerator.getPayableService("Test Service1", 5, "weeks", 5, "YES", null,
null, SeocObjectGenerator.cs1Set, seoc1, billingCodes1);
PayableService service2 = SeocObjectGenerator.getPayableService("Test Service2", 5, "weeks", 5, "YES", null,
null, SeocObjectGenerator.cs1Set, seoc1, billingCodes2);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);
seoc1.setHptcs(hptcs);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);
Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);
Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

try {
seocService.validSeocActivate(1);
fail();
} catch (SeocConstraintViolationException e) {
assertThat(e.getConstraintViolations().toString()).contains(
"The REV flag cannot be set unless at least one payable service requires pre-certification");

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(2)).getStatusByDescription(Mockito.anyString());
}
}

/**
* Description: Seoc requested for activation, with effective date and status
* DateHold(active SEOC)
*/
@Test
public void activateSeocFailureActivatedBefore() throws Exception {
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
int id = 1;
SeocActivateRequest seocActivateRequest = SeocActivateRequest.Builder
.create(id, TestUtil.getEffectiveDateString()).build();
Seoc seoc1 = SeocObjectGenerator.getSeoc(id, "Test", 1, null, effectiveDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, null, null);
seoc1.setServices(new ArrayList<PayableService>());
PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

// Update etag in the context
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
SeocThreadLocal.setContext(context);

// Call Activate
SeocGenericResponse seocResponse = seocService.activateSeoc(seocActivateRequest);

// Assert the result as expected
assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);
assertThat(seocResponse.getMessage()).isEqualTo("Seoc status not valid for activation.");

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
}

/**
* Description: Seoc requested for activation, with effective date and status
* draft
*/
@Test
public void activateSeocFailureNotValidCondition1() throws Exception {
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
int id = 1;
SeocActivateRequest seocActivateRequest = SeocActivateRequest.Builder
.create(id, TestUtil.getEffectiveDateString()).build();
Seoc seoc1 = SeocObjectGenerator.getSeoc(id, "Test", 1, null, effectiveDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, inprogress, null, null);
seoc1.setServices(new ArrayList<PayableService>());
PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

// Update etag in the context
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
SeocThreadLocal.setContext(context);

// Call Activate
SeocGenericResponse seocResponse = seocService.activateSeoc(seocActivateRequest);

// Assert the result as expected
assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);
assertThat(seocResponse.getMessage()).isEqualTo("Seoc status not valid for activation.");

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
}

/**
* Description: Seoc requested for activation, no effective date and status
* datehold
*/
@Test
public void activateSeocFailureNotValidCondition2() throws Exception {
int id = 1;
SeocActivateRequest seocActivateRequest = SeocActivateRequest.Builder
.create(id, TestUtil.getEffectiveDateString()).build();
Seoc seoc1 = SeocObjectGenerator.getSeoc(id, "Test", 1, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
dateHold, null, null);
seoc1.setServices(new ArrayList<PayableService>());
PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

// Update etag in the context
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
SeocThreadLocal.setContext(context);

// Call Activate
SeocGenericResponse seocResponse = seocService.activateSeoc(seocActivateRequest);

// Assert the result as expected
assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);
assertThat(seocResponse.getMessage()).isEqualTo("Seoc status not valid for activation.");

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
}

/**
* Description: Seoc requested for activation has draft status
*/
@Test
public void activateSeocFromDraftSuccess() throws Exception {
int id = 1;
SeocActivateRequest seocActivateRequest = SeocActivateRequest.Builder
.create(id, TestUtil.getEffectiveDateString()).build();
Seoc seoc1 = SeocObjectGenerator.getSeoc(id, "Test", 1, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc1.setHptcs(hptcs);

Set<Seoc> seocs = new HashSet<Seoc>();
seocs.add(seoc1);

int[] seocKeys = new int[0];

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

// Update etag in the context
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
context.setUserId("SEOCSYSTEMUSER");
SeocThreadLocal.setContext(context);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

Mockito.when(genericService.getCurrentSeocConfigVersion()).thenReturn(1);

Mockito.when(seocRepository.findSeocsPublishedWithCategoryOfCare(SeocObjectGenerator.cc1.getDescription()))
.thenReturn(seocKeys);

// Call activate seoc
SeocGenericResponse seocResponse = seocService.activateSeoc(seocActivateRequest);

// Assert that the method returns success
assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);

Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(3)).getStatusByDescription(Mockito.anyString());
Mockito.verify(genericService, Mockito.times(1)).getCurrentSeocConfigVersion();
Mockito.verify(seocRepository, Mockito.times(1)).findSeocsPublishedWithCategoryOfCare(Mockito.anyString());

assertThat(seoc1.getActivatedBy()).isEqualTo("SEOCSYSTEMUSER");
}

/**
* Description: Seoc requested for activation has draft status and future
* effectiveDate
*/
@Test
public void activateSeocFromDraftSuccessFutureEffectiveDate() throws Exception {
int id = 1;
SeocActivateRequest seocActivateRequest = SeocActivateRequest.Builder
.create(id, TestUtil.getEffectiveDateStringFuture()).build();
Seoc seoc1 = SeocObjectGenerator.getSeoc(id, "Test", 1, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc1.setHptcs(hptcs);

Set<Seoc> seocs = new HashSet<Seoc>();
seocs.add(seoc1);

int[] seocKeys = new int[0];

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

// Update etag in the context
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
context.setUserId("SEOCSYSTEMUSER");
SeocThreadLocal.setContext(context);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

Mockito.when(genericService.getCurrentSeocConfigVersion()).thenReturn(1);

Mockito.when(seocRepository.findSeocsPublishedWithCategoryOfCare(SeocObjectGenerator.cc1.getDescription()))
.thenReturn(seocKeys);

// Call activate seoc
SeocGenericResponse seocResponse = seocService.activateSeoc(seocActivateRequest);

// Assert that the method returns success
assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);

Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(3)).getStatusByDescription(Mockito.anyString());
Mockito.verify(genericService, Mockito.times(1)).getCurrentSeocConfigVersion();
Mockito.verify(seocRepository, Mockito.times(1)).findSeocsPublishedWithCategoryOfCare(Mockito.anyString());

assertThat(seoc1.getEffectiveDate().getTime()).isEqualTo(TestUtil.getEffectiveDateFuture().getTime());
assertThat(seoc1.getActivatedBy()).isEqualTo("SEOCSYSTEMUSER");
}

/**
* Description: Seoc activation failed since effectiveDate is in the past
*/
@Test(expected = SeocEffectiveDateNotValidException.class)
public void activateSeocFailurePastEffectiveDate() throws Exception {
int id = 1;
SeocActivateRequest seocActivateRequest = SeocActivateRequest.Builder
.create(id, TestUtil.getEffectiveDateStringPast()).build();
Seoc seoc1 = SeocObjectGenerator.getSeoc(id, "Test", 1, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc1.setHptcs(hptcs);

Set<Seoc> seocs = new HashSet<Seoc>();
seocs.add(seoc1);

int[] seocKeys = new int[0];

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

// Update etag in the context
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
SeocThreadLocal.setContext(context);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

Mockito.when(genericService.getCurrentSeocConfigVersion()).thenReturn(1);

Mockito.when(seocRepository.findSeocsPublishedWithCategoryOfCare(SeocObjectGenerator.cc1.getDescription()))
.thenReturn(seocKeys);

// Call activate seoc
SeocGenericResponse seocResponse = seocService.activateSeoc(seocActivateRequest);

// Assert that the method returns success
assertThat(seocResponse.getStatus()).isEqualTo(HttpStatus.BAD_REQUEST);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());

Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(2)).getStatusByDescription(Mockito.anyString());
Mockito.verify(genericService, Mockito.times(1)).getCurrentSeocConfigVersion();
Mockito.verify(seocRepository, Mockito.times(1)).findSeocsPublishedWithCategoryOfCare(Mockito.anyString());
}

/**
* Description: Constraint violation exceptions occurred during seoc activation
*/
@Test(expected = SeocConstraintViolationException.class)
public void activateSeocFailureWithException() throws Exception {
int id = 1;
SeocActivateRequest seocActivateRequest = SeocActivateRequest.Builder
.create(id, TestUtil.getEffectiveDateString()).build();
Seoc seoc1 = SeocObjectGenerator.getSeoc(id, "Test", 1, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, null, null);
seoc1.setServices(new ArrayList<PayableService>());

Set<Seoc> seocs = new HashSet<Seoc>();
seocs.add(seoc1);

int[] seocKeys = new int[0];

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

Mockito.when(genericService.getCurrentSeocConfigVersion()).thenReturn(1);

Mockito.when(seocRepository.findSeocsPublishedWithCategoryOfCare(SeocObjectGenerator.cc1.getDescription()))
.thenReturn(seocKeys);

// Update etag in the context
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
SeocThreadLocal.setContext(context);

SeocGenericResponse seocResponse = seocService.activateSeoc(seocActivateRequest);

assertThat(seocResponse.getStatus()).isEqualTo(HttpStatus.BAD_REQUEST);

Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(2)).getStatusByDescription(Mockito.anyString());
Mockito.verify(genericService, Mockito.times(1)).getCurrentSeocConfigVersion();
Mockito.verify(seocRepository, Mockito.times(1)).findSeocsPublishedWithCategoryOfCare(Mockito.anyString());

}

/**
* Description: No Seoc available for requested seoc id
*/
@Test
public void activateSeocFailureNoSeoc() throws Exception {
Seoc seoc1 = null;

SeocActivateRequest seocActivateRequest = SeocActivateRequest.Builder
.create(1, TestUtil.getEffectiveDateString()).build();
int id = seocActivateRequest.getSeocId();
Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
SeocThreadLocal.setContext(context);

SeocGenericResponse seocResponse = seocService.activateSeoc(seocActivateRequest);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());

}

/**
* Description: Activating a Pending revision Seoc. More than one Previous Seoc
*/
@Test
public void activateSeocPendingRevisionMoreThanOnePreviousSeoc() throws Exception {
int seocKey = 1;
int id = 1;
SeocActivateRequest seocActivateRequest = SeocActivateRequest.Builder
.create(id, TestUtil.getEffectiveDateString()).build();
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", seocKey, Constants.VERSION_PENDING_REVISION, null, null,
"disclaimer", 5, "Description", true, "ProceduralOverview", 5, null, null, null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, inprogress, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service11 = SeocObjectGenerator.getPayableService(1, "Test Service11", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service12 = SeocObjectGenerator.getPayableService(2, "Test Service12", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service11);
seoc1.getServices().add(service12);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc1.setHptcs(hptcs);

Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
Date endDate = ApiUtil.getUTCZoneDateTime("09-01-2018 05:01:00 AM");
// Discontinued SEOC
Seoc seoc2 = SeocObjectGenerator.getSeoc(2, "Test", seocKey, "1.0.1", effectiveDate, endDate, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1, null);
seoc2.setServices(new ArrayList<PayableService>());

PayableService service21 = SeocObjectGenerator.getPayableService(3, "Test Service21", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc2);
PayableService service22 = SeocObjectGenerator.getPayableService(4, "Test Service22", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc2);

seoc2.getServices().add(service21);
seoc2.getServices().add(service22);

hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc2.setHptcs(hptcs);

// Active SEOC
Seoc seoc3 = SeocObjectGenerator.getSeoc(3, "Test", seocKey, "1.0.2", effectiveDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1, null);
seoc3.setServices(new ArrayList<PayableService>());

PayableService service31 = SeocObjectGenerator.getPayableService(5, "Test Service31", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc3);
PayableService service32 = SeocObjectGenerator.getPayableService(6, "Test Service32", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc3);

seoc3.getServices().add(service31);
seoc3.getServices().add(service32);

hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc3.setHptcs(hptcs);

Set<Seoc> seocs = new HashSet<Seoc>();
seocs.add(seoc2);
seocs.add(seoc3);

Mockito.when(seocRepository.findBySeocKey(1)).thenReturn(seocs);

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

// Set eTag in the context
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
context.setUserId("SEOCSYSTEMUSER");
SeocThreadLocal.setContext(context);

SeocGenericResponse seocResponse = seocService.activateSeoc(seocActivateRequest);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);

Mockito.verify(seocRepository, Mockito.times(1)).findBySeocKey(Mockito.anyInt());
Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(3)).getStatusByDescription(Mockito.anyString());

assertThat(seoc1.getVersionNumber()).isEqualTo("1.0.3");
assertThat(seoc1.getActivatedBy()).isEqualTo("SEOCSYSTEMUSER");

assertThat(seoc3.getDiscontinuedBy()).isEqualTo("SEOCSYSTEMUSER");
}

/**
* Description: Activating a Pending revision Seoc. Previous Seoc not found
*/
@Test
public void activateSeocPendingRevisionPreviousSeocReturnsNull() throws Exception {
int seocKey = 1;
int id = 1;
SeocActivateRequest seocActivateRequest = SeocActivateRequest.Builder
.create(id, TestUtil.getEffectiveDateString()).build();
Seoc seoc1 = SeocObjectGenerator.getSeoc(id, "Test", seocKey, Constants.VERSION_PENDING_REVISION, null, null,
"disclaimer", 5, "Description", true, "ProceduralOverview", 5, null, null, null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, inprogress, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service11 = SeocObjectGenerator.getPayableService(1, "Test Service11", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service12 = SeocObjectGenerator.getPayableService(1, "Test Service12", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service11);
seoc1.getServices().add(service12);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc1.setHptcs(hptcs);

Set<Seoc> seocs = null;

Mockito.when(seocRepository.findBySeocKey(seocKey)).thenReturn(seocs);

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

// Set eTag in the context
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
SeocThreadLocal.setContext(context);

SeocGenericResponse seocResponse = seocService.activateSeoc(seocActivateRequest);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);

assertThat(seocResponse.getMessage()).isEqualTo("Error occured in finding the previous active seoc.");

Mockito.verify(seocRepository, Mockito.times(1)).findBySeocKey(Mockito.anyInt());
Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(2)).getStatusByDescription(Mockito.anyString());

}

/**
* Description: Activating a Pending revision Seoc. Previous Seoc is in Date
* Hold
*/
@Test
public void activateSeocPendingRevisionPreviousSeocDateHold() throws Exception {
int seocKey = 1;
int id = 1;
SeocActivateRequest seocActivateRequest = SeocActivateRequest.Builder
.create(id, TestUtil.getEffectiveDateString()).build();
Seoc seoc1 = SeocObjectGenerator.getSeoc(id, "Test", seocKey, Constants.VERSION_PENDING_REVISION, null, null,
"disclaimer", 5, "Description", true, "ProceduralOverview", 5, null, null, null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, inprogress, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service11 = SeocObjectGenerator.getPayableService(1, "Test Service11", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service12 = SeocObjectGenerator.getPayableService(2, "Test Service12", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service11);
seoc1.getServices().add(service12);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc1.setHptcs(hptcs);

// Get tomorrow's date
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
calendar.add(Calendar.DATE, 1);

Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");

// Active SEOC
Seoc seoc2 = SeocObjectGenerator.getSeoc(2, "Test", seocKey, "1.0.1", effectiveDate,
TestUtil.getEffectiveDatePast(), "disclaimer", 5, "Description", true, "ProceduralOverview", 5, null,
null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1,
null);
seoc2.setServices(new ArrayList<PayableService>());

PayableService service21 = SeocObjectGenerator.getPayableService(3, "Test Service21", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc2);
PayableService service22 = SeocObjectGenerator.getPayableService(4, "Test Service22", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc2);

seoc2.getServices().add(service21);
seoc2.getServices().add(service22);

hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc2.setHptcs(hptcs);

// Date Hold SEOC
Seoc seoc3 = SeocObjectGenerator.getSeoc(3, "Test", seocKey, "1.0.2", TestUtil.getEffectiveDateFuture(), null,
"disclaimer", 5, "Description", true, "ProceduralOverview", 5, null, null, null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1, null);
seoc3.setServices(new ArrayList<PayableService>());

PayableService service31 = SeocObjectGenerator.getPayableService(5, "Test Service31", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc3);
PayableService service32 = SeocObjectGenerator.getPayableService(6, "Test Service32", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc3);

seoc3.getServices().add(service31);
seoc3.getServices().add(service32);

hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc3.setHptcs(hptcs);

Set<Seoc> seocs = new HashSet<Seoc>();
seocs.add(seoc2);
seocs.add(seoc3);

Mockito.when(seocRepository.findBySeocKey(seocKey)).thenReturn(seocs);

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

// Set eTag in the context
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
SeocThreadLocal.setContext(context);

SeocGenericResponse seocResponse = seocService.activateSeoc(seocActivateRequest);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);

Mockito.verify(seocRepository, Mockito.times(1)).findBySeocKey(Mockito.anyInt());
Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(2)).getStatusByDescription(Mockito.anyString());

}

/**
* Description:Activating pending revision. Previous Seoc version number returns
* null.
*/
@Test
public void activateSeocPendingRevisionVersionNumberReturnsNull() throws Exception {
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
int seocKey = 1;
int id = 1;
SeocActivateRequest seocActivateRequest = SeocActivateRequest.Builder
.create(id, TestUtil.getEffectiveDateString()).build();
Seoc seoc1 = SeocObjectGenerator.getSeoc(id, "Test", seocKey, Constants.VERSION_PENDING_REVISION, null, null,
"disclaimer", 5, "Description", true, "ProceduralOverview", 5, null, null, null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, inprogress, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service11 = SeocObjectGenerator.getPayableService(1, "Test Service11", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service12 = SeocObjectGenerator.getPayableService(1, "Test Service12", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service11);
seoc1.getServices().add(service12);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc1.setHptcs(hptcs);

Seoc seoc2 = SeocObjectGenerator.getSeoc(2, "Test", seocKey, null, effectiveDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1, null);
seoc2.setServices(new ArrayList<PayableService>());

PayableService service21 = SeocObjectGenerator.getPayableService(1, "Test Service21", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service22 = SeocObjectGenerator.getPayableService(1, "Test Service22", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);

seoc2.getServices().add(service21);
seoc2.getServices().add(service22);

hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc2.setHptcs(hptcs);

Set<Seoc> seocs = new HashSet<Seoc>();
seocs.add(seoc2);

Mockito.when(seocRepository.findBySeocKey(seocKey)).thenReturn(seocs);

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

// Set eTag in the context
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
SeocThreadLocal.setContext(context);

SeocGenericResponse seocResponse = seocService.activateSeoc(seocActivateRequest);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);

assertThat(seocResponse.getMessage()).isEqualTo("Error occured in finding the previous active seoc.");

Mockito.verify(seocRepository, Mockito.times(1)).findBySeocKey(Mockito.anyInt());
Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(2)).getStatusByDescription(Mockito.anyString());

}

/**
* Description:Activating pending revision. Previous Seoc version number returns
* invalid version number.
*/
@Test
public void activateSeocPendingRevisionIncorrectVersionNumberSize() throws Exception {
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
int seocKey = 1;
// Prepare Seoc 1 - Draft Seoc with id 1
int id = 1;
SeocActivateRequest seocActivateRequest = SeocActivateRequest.Builder
.create(id, TestUtil.getEffectiveDateString()).build();
Seoc seoc1 = SeocObjectGenerator.getSeoc(id, "Test", seocKey, Constants.VERSION_PENDING_REVISION, null, null,
"disclaimer", 5, "Description", true, "ProceduralOverview", 5, null, null, null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, inprogress, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service11 = SeocObjectGenerator.getPayableService(1, "Test Service11", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service12 = SeocObjectGenerator.getPayableService(1, "Test Service12", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service11);
seoc1.getServices().add(service12);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc1.setHptcs(hptcs);

// Seoc 2 - Active Seoc with id 2
Seoc seoc2 = SeocObjectGenerator.getSeoc(2, "Test", seocKey, "1.2,0", effectiveDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, null, null);
seoc2.setServices(new ArrayList<PayableService>());

PayableService service21 = SeocObjectGenerator.getPayableService(1, "Test Service21", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service22 = SeocObjectGenerator.getPayableService(1, "Test Service22", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);

seoc2.getServices().add(service21);
seoc2.getServices().add(service22);

hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc1.setHptcs(hptcs);

Set<Seoc> seocs = new HashSet<Seoc>();
seocs.add(seoc2);

Mockito.when(seocRepository.findBySeocKey(seocKey)).thenReturn(seocs);

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

// Context has etag value of draft seoc
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
SeocThreadLocal.setContext(context);

// Activate should fail as incorrect version number of previous active seoc was
// provided
SeocGenericResponse seocResponse = seocService.activateSeoc(seocActivateRequest);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);

assertThat(seocResponse.getMessage()).isEqualTo("Error occured in finding the previous active seoc.");

Mockito.verify(seocRepository, Mockito.times(1)).findBySeocKey(Mockito.anyInt());
Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(2)).getStatusByDescription(Mockito.anyString());

}

/**
* Description:Activating pending revision. Category of Care changed from
* previous Seoc
*/
@Test
public void activateSeocPendingRevisionChangeCoc() throws Exception {
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
int seocKey = 1;
// Seoc1 - draft seoc - Category of care cc1
int id = 1;
SeocActivateRequest seocActivateRequest = SeocActivateRequest.Builder
.create(id, TestUtil.getEffectiveDateString()).build();
Seoc seoc1 = SeocObjectGenerator.getSeoc(id, "Test", seocKey, Constants.VERSION_PENDING_REVISION, null, null,
"disclaimer", 5, "Description", true, "ProceduralOverview", 5, null, null, null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, inprogress, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service11 = SeocObjectGenerator.getPayableService(1, "Test Service11", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service12 = SeocObjectGenerator.getPayableService(1, "Test Service12", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service11);
seoc1.getServices().add(service12);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc1.setHptcs(hptcs);

// Seoc2 - active seoc - Category of care cc1
Seoc seoc2 = SeocObjectGenerator.getSeoc(2, "Test", seocKey, "1.3.1", effectiveDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1, null);
seoc2.setServices(new ArrayList<PayableService>());

PayableService service21 = SeocObjectGenerator.getPayableService(1, "Test Service21", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service22 = SeocObjectGenerator.getPayableService(1, "Test Service22", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);

seoc2.getServices().add(service21);
seoc2.getServices().add(service22);

hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc2.setHptcs(hptcs);

// Seoc2 - active seoc - - Category of care cc2
Seoc seoc3 = SeocObjectGenerator.getSeoc(3, "Test", seocKey, "1.0.1", effectiveDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc2,
SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp2, null);

seoc3.setServices(new ArrayList<PayableService>());

PayableService service31 = SeocObjectGenerator.getPayableService(1, "Test Service31", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);

seoc3.getServices().add(service31);

hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc3.setHptcs(hptcs);

Set<Seoc> seocs = new HashSet<Seoc>();
seocs.add(seoc2);
seocs.add(seoc3);

int[] seocKeys = { 3 };

Mockito.when(seocRepository.findBySeocKey(seocKey)).thenReturn(seocs);

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

Mockito.when(seocRepository.findSeocsPublishedWithCategoryOfCare(SeocObjectGenerator.cc1.getDescription()))
.thenReturn(seocKeys);

Mockito.when(seocRepository.save(seoc1)).thenReturn(seoc1);

Mockito.when(seocRepository.save(seoc2)).thenReturn(seoc2);

// Set eTag in context
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
SeocThreadLocal.setContext(context);

// Activating a Seoc whose Category of Care changed from the last version. This
// Seoc should get a different version number
SeocGenericResponse seocResponse = seocService.activateSeoc(seocActivateRequest);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);

Mockito.verify(seocRepository, Mockito.times(1)).findBySeocKey(Mockito.anyInt());
Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());
ArgumentCaptor<Seoc> argCaptor = ArgumentCaptor.forClass(Seoc.class);
Mockito.verify(seocRepository, Mockito.times(2)).save(argCaptor.capture());

assertThat(seoc1.getVersionNumber()).isEqualTo("1.1.2");
}

/**
* Description:Activating pending revision. Category of Care not changed from
* previous Seoc
*/
@Test
public void activateSeocPendingRevisionCocNoChange() throws Exception {
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
Date endDate = ApiUtil.getUTCZoneDateTime("09-09-2018 05:01:00 AM");
int seocKey = 1;
int id = 1;
SeocActivateRequest seocActivateRequest = SeocActivateRequest.Builder
.create(id, TestUtil.getEffectiveDateString()).build();
// Seoc1 - draft - categoryOfCare cc1
Seoc seoc1 = SeocObjectGenerator.getSeoc(id, "Test", seocKey, Constants.VERSION_PENDING_REVISION, null, null,
"disclaimer", 5, "Description", true, "ProceduralOverview", 5, null, null, null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, inprogress, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service11 = SeocObjectGenerator.getPayableService(1, "Test Service11", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service12 = SeocObjectGenerator.getPayableService(1, "Test Service12", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service11);
seoc1.getServices().add(service12);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc1.setHptcs(hptcs);
// Seoc2 - discontinued - categoryOfCare cc1
Seoc seoc2 = SeocObjectGenerator.getSeoc(2, "Test", seocKey, "1.3.1", effectiveDate, endDate, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1, null);
seoc2.setServices(new ArrayList<PayableService>());

PayableService service21 = SeocObjectGenerator.getPayableService(1, "Test Service21", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service22 = SeocObjectGenerator.getPayableService(1, "Test Service22", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);

seoc2.getServices().add(service21);
seoc2.getServices().add(service22);

hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc2.setHptcs(hptcs);
// Seoc3 - active - categoryOfCare cc1
Seoc seoc3 = SeocObjectGenerator.getSeoc(3, "Test", seocKey, "1.0.1", effectiveDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, null, null);
seoc3.setServices(new ArrayList<PayableService>());

PayableService service31 = SeocObjectGenerator.getPayableService(1, "Test Service31", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);

seoc3.getServices().add(service31);

hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc3.setHptcs(hptcs);

Set<Seoc> seocs = new HashSet<Seoc>();
seocs.add(seoc2);
seocs.add(seoc3);

Mockito.when(seocRepository.findBySeocKey(seocKey)).thenReturn(seocs);

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

// etag in context
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
SeocThreadLocal.setContext(context);

// Activating a seoc with same category of care as previous should give a
// version number that is a continuation of the previous active seoc series
SeocGenericResponse seocResponse = seocService.activateSeoc(seocActivateRequest);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);

Mockito.verify(seocRepository, Mockito.times(1)).findBySeocKey(Mockito.anyInt());
Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(3)).getStatusByDescription(Mockito.anyString());

}

/**
* Description: Activating pending revision. Future effectiveDate given.
*/
@Test
public void activateSeocPendingRevisionFutureEffectiveDate() throws Exception {
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
Date endDate = ApiUtil.getUTCZoneDateTime("09-09-2018 05:01:00 AM");
int seocKey = 1;
int id = 1;
SeocActivateRequest seocActivateRequest = SeocActivateRequest.Builder
.create(id, TestUtil.getEffectiveDateStringFuture()).build();
// Seoc1 - draft - categoryOfCare cc1
Seoc seoc1 = SeocObjectGenerator.getSeoc(id, "Test", seocKey, Constants.VERSION_PENDING_REVISION, null, null,
"disclaimer", 5, "Description", true, "ProceduralOverview", 5, null, null, null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, inprogress, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service11 = SeocObjectGenerator.getPayableService(1, "Test Service11", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service12 = SeocObjectGenerator.getPayableService(1, "Test Service12", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service11);
seoc1.getServices().add(service12);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc1.setHptcs(hptcs);
// Seoc2 - discontinued - categoryOfCare cc1
Seoc seoc2 = SeocObjectGenerator.getSeoc(2, "Test", seocKey, "1.3.1", effectiveDate, endDate, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1, null);
seoc2.setServices(new ArrayList<PayableService>());

PayableService service21 = SeocObjectGenerator.getPayableService(1, "Test Service21", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service22 = SeocObjectGenerator.getPayableService(1, "Test Service22", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);

seoc2.getServices().add(service21);
seoc2.getServices().add(service22);

hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc2.setHptcs(hptcs);
// Seoc3 - active - categoryOfCare cc1
Seoc seoc3 = SeocObjectGenerator.getSeoc(3, "Test", seocKey, "1.0.1", effectiveDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, null, null);
seoc3.setServices(new ArrayList<PayableService>());

PayableService service31 = SeocObjectGenerator.getPayableService(1, "Test Service31", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);

seoc3.getServices().add(service31);

hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc3.setHptcs(hptcs);

Set<Seoc> seocs = new HashSet<Seoc>();
seocs.add(seoc2);
seocs.add(seoc3);

Mockito.when(seocRepository.findBySeocKey(seocKey)).thenReturn(seocs);

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

// etag in context
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
SeocThreadLocal.setContext(context);

// Activating a seoc with same category of care as previous should give a
// version number that is a continuation of the previous active seoc series
SeocGenericResponse seocResponse = seocService.activateSeoc(seocActivateRequest);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);

Mockito.verify(seocRepository, Mockito.times(1)).findBySeocKey(Mockito.anyInt());
Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(3)).getStatusByDescription(Mockito.anyString());

assertThat(seoc1.getEffectiveDate()).isEqualTo(TestUtil.getEffectiveDateFuture());
assertThat(seoc3.getEndDate()).isEqualTo(TestUtil.getEffectiveDateFuture());

}

/**
* Description: Activate Seoc - etag matches
*/
@Test
public void activateSeocEtagMatchingTrue() throws Exception {
int id = 1;
SeocActivateRequest seocActivateRequest = SeocActivateRequest.Builder
.create(id, TestUtil.getEffectiveDateString()).build();
Seoc seoc1 = SeocObjectGenerator.getSeoc(id, "Test", 1, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc1.setHptcs(hptcs);

Set<Seoc> seocs = new HashSet<Seoc>();
seocs.add(seoc1);

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

// Set etag in context
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
SeocThreadLocal.setContext(context);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

Mockito.when(genericService.getCurrentSeocConfigVersion()).thenReturn(1);

Mockito.when(seocRepository.findSeocsPublishedWithCategoryOfCare(SeocObjectGenerator.cc1.getDescription()))
.thenReturn(new int[0]);

// If etag in context is same as the generated etag. Activate should succeed
SeocGenericResponse seocResponse = seocService.activateSeoc(seocActivateRequest);

String eTagAfterResponse = SeocThreadLocal.getContext().getEtag();
String expectedEtagAfterResponse = SeocServiceHelper.getHashCodeOfSeoc(seoc1);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);
assertThat(eTagAfterResponse).isEqualTo(expectedEtagAfterResponse);

Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());
Mockito.verify(genericService, Mockito.times(3)).getStatusByDescription(Mockito.anyString());
Mockito.verify(genericService, Mockito.times(1)).getCurrentSeocConfigVersion();
Mockito.verify(seocRepository, Mockito.times(1)).findSeocsPublishedWithCategoryOfCare(Mockito.anyString());

}

/**
* Description:Activate Seoc - etag match fails
*/
@Test
public void activateSeocEtagMatchingFalse() throws Exception {
int id = 1;
SeocActivateRequest seocActivateRequest = SeocActivateRequest.Builder
.create(id, TestUtil.getEffectiveDateString()).build();

Seoc seoc0 = SeocObjectGenerator.getSeoc(id, "Test", 1, null, null, null, "disclaimer before activate", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, inprogress, SeocObjectGenerator.qasp1, null);

Seoc seoc1 = SeocObjectGenerator.getSeoc(id, "Test", 1, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc1.setHptcs(hptcs);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

// context has stale etag
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc0));
SeocThreadLocal.setContext(context);

SeocGenericResponse seocResponse = seocService.activateSeoc(seocActivateRequest);

// Activation fails with pre-condition failed status
assertThat(seocResponse.getStatus()).isEqualTo(Constants.PRECONDITION_FAILED);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());

}

/**
* Description: Delete a Seoc with status not Draft. Should not allow to delete
* this seoc.
*/
@Test
public void deleteWithStatusNotDraft() throws Exception {
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 1, "1.0.1", effectiveDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, null, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

String expectedMessage = "Seoc with status " + seoc1.getCalculatedStatus() + " cannot be deleted";

// context has stale etag
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
SeocThreadLocal.setContext(context);
// Call the method to be tested
SeocGenericResponse response = seocService.deleteSeoc(seoc1.getId());

assertThat(expectedMessage).isEqualTo(response.getMessage());

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());

}

/**
* Description: Delete a Seoc with status Draft. Seoc deleted.
*/
@Test
public void deleteWithStatusDraft() throws Exception {
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 1, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, null, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

String expectedMessage = "Successfully deleted the seoc and associated payable services.";

// context has stale etag
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
SeocThreadLocal.setContext(context);

// Call the method to be tested
SeocGenericResponse response = seocService.deleteSeoc(seoc1.getId());

assertThat(expectedMessage).isEqualTo(response.getMessage());

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
}

/**
* Description: Trying to delete seoc which is not available.
*/
@Test
public void deleteSeocSeocNotAvailable() throws Exception {
Seoc seoc1 = null;
int id = 1;

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

// context has stale etag
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
SeocThreadLocal.setContext(context);

// Call the method to te be tested
SeocGenericResponse response = seocService.deleteSeoc(id);

SeocGenericResponse expectedResponse = new SeocGenericResponse();
expectedResponse.setMessage("Seoc not available with id " + id);
expectedResponse.setStatus(Constants.FAILURE);

assertThat(response.getMessage()).isEqualTo(expectedResponse.getMessage());
assertThat(response.getStatus()).isEqualTo(expectedResponse.getStatus());

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
}

/**
* Description: Deleting an existing seoc.
*/
@Test
public void deleteSeocSeocAvailable() throws Exception {
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 1, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, null, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

// context has stale etag
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
SeocThreadLocal.setContext(context);

// Call the method to te be tested
SeocGenericResponse response = seocService.deleteSeoc(1);

SeocGenericResponse expectedResponse = new SeocGenericResponse();
expectedResponse.setStatus(Constants.SUCCESS);
expectedResponse.setMessage("Successfully deleted the seoc and associated payable services.");

assertThat(response.getMessage()).isEqualTo(expectedResponse.getMessage());
assertThat(response.getStatus()).isEqualTo(expectedResponse.getStatus());

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());

}

/**
* Description:Deleting Seoc - Etag match fails
*/
@Test
public void deleteSeocEtagMatchingFalse() throws Exception {

Seoc seoc0 = SeocObjectGenerator.getSeoc(1, "Test", 1, null, null, null, "disclaimer before activate", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, inprogress, SeocObjectGenerator.qasp1, null);

Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 1, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc0));
SeocThreadLocal.setContext(context);

SeocGenericResponse seocResponse = seocService.deleteSeoc(1);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.PRECONDITION_FAILED);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());

}

/**
* Description: Seoc not available in to discontinue.
*/
@Test
public void discontinueSeocFoundSeocNull() {
int id = 1;
Seoc seoc1 = null;

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

SeocGenericResponse seocResponse = seocService.discontinueSeoc(id);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);
assertThat(seocResponse.getMessage()).isEqualTo("Seoc not available with id " + id);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
}

/**
* Description: Seoc to be discontinued is not an active Seoc.
*/
@Test
public void discontinueSeocFoundSeocDraft() {
int id = 1;
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 1, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, null, null);
seoc1.setServices(new ArrayList<PayableService>());

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

SeocGenericResponse seocResponse = seocService.discontinueSeoc(id);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);
assertThat(seocResponse.getMessage()).isEqualTo(
"Seoc is not eligible for discontinuation. Current status of SEOC is " + seoc1.getCalculatedStatus());

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
}

/**
* Description: Active Seoc with pending revision discontinued
*/
@Test
public void discontinueSeocFoundSeocActiveWithPendingRevision() {
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
int id = 1;
int seocKey = 10;
// Seoc1 - active - with pending revision seoc2
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", seocKey, "1.0.2", effectiveDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, null, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

// seoc2 - pending revision of seoc1
Seoc seoc2 = SeocObjectGenerator.getSeoc(2, "Test", seocKey, Constants.VERSION_PENDING_REVISION, null, null,
"disclaimer", 5, "Description", true, "ProceduralOverview", 5, null, null, null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, inprogress, null, null);
seoc2.setServices(new ArrayList<PayableService>());

PayableService service12 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc2);
PayableService service22 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc2);

seoc2.getServices().add(service12);
seoc2.getServices().add(service22);

Set<Seoc> seocPR = new HashSet<Seoc>();
seocPR.add(seoc2);

Date endDate = ApiUtil.today_UTC();
Seoc seoc3 = SeocObjectGenerator.getSeoc(1, "Test", 1, "1.0.1", effectiveDate, endDate, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, null, null);
seoc3.setServices(new ArrayList<PayableService>());

PayableService service13 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc3);
PayableService service23 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc3);

seoc3.getServices().add(service13);
seoc3.getServices().add(service23);

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

Mockito.when(seocRepository.findBySeocKey(seocKey)).thenReturn(seocPR);

// saving after discontinue should return seoc3 - discontinued form of seoc1
Mockito.when(seocRepository.save(seoc1)).thenReturn(seoc3);

SeocGenericResponse seocResponse = seocService.discontinueSeoc(id);

// Assert that the seoc was discontinued successfully
assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());

Mockito.verify(seocRepository, Mockito.times(1)).findBySeocKey(Mockito.anyInt());

ArgumentCaptor<Seoc> argCaptor = ArgumentCaptor.forClass(Seoc.class);
Mockito.verify(seocRepository, Mockito.times(1)).save(argCaptor.capture());

}

/**
* Description: Active Seoc with no pending revision discontinued
*/
@Test
public void discontinueSeocFoundSeocActiveNoPendingRevision() {
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
int id = 1;
int seocKey = 10;
// seoc1 - Active seoc with not pending revision
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", seocKey, "1.0.1", effectiveDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, null, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Set<Seoc> seocPR = new HashSet<Seoc>();

// seoc3 - discontinued form of seoc1
Date endDate = ApiUtil.today_UTC();
Seoc seoc3 = SeocObjectGenerator.getSeoc(1, "Test", 1, "1.0.1", effectiveDate, endDate, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, null, null);
seoc3.setServices(new ArrayList<PayableService>());

PayableService service13 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc3);
PayableService service23 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc3);

seoc3.getServices().add(service13);
seoc3.getServices().add(service23);

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

Mockito.when(seocRepository.findBySeocKey(seocKey)).thenReturn(seocPR);

Mockito.when(seocRepository.save(seoc1)).thenReturn(seoc3);

// Test Call
SeocGenericResponse seocResponse = seocService.discontinueSeoc(id);

assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());

Mockito.verify(seocRepository, Mockito.times(1)).findBySeocKey(Mockito.anyInt());

ArgumentCaptor<Seoc> argCaptor = ArgumentCaptor.forClass(Seoc.class);
Mockito.verify(seocRepository, Mockito.times(1)).save(argCaptor.capture());

}

/**
* Description: Reverse SEOC - SEOC not found
*/
@Test
public void reverseSeocSeocNotFound() {
int id = 1;

Mockito.when(seocRepository.findById(id)).thenReturn(null);

SeocGenericResponse seocResponse = seocService.reverseSeoc(id);

assertThat(seocResponse.getMessage()).isEqualTo("Seoc not available with id " + id);
assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());
}

/**
* Description: Reverse SEOC - etag match fails
*/
@Test
public void reverseSeocEtagMatchingFalse() throws Exception {
Date effectiveDate = TestUtil.getEffectiveDate();

Seoc seoc0 = SeocObjectGenerator.getSeoc(1, "Test", 10, "1.0.1", effectiveDate, null,
"disclaimer before activate", 5, "Description", true, "ProceduralOverview", 5, null, null, null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1, null);

Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 10, "1.0.1", effectiveDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc1.setHptcs(hptcs);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc1);

// context has stale etag
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc0));
SeocThreadLocal.setContext(context);

SeocGenericResponse seocResponse = seocService.reverseSeoc(1);

// Activation fails with pre-condition failed status
assertThat(seocResponse.getStatus()).isEqualTo(Constants.PRECONDITION_FAILED);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());

}

/**
* Description: Reverse SEOC - etag match passes
*/
@Test
public void reverseSeocEtagMatchingTrue() throws Exception {
Date effectiveDate = TestUtil.getEffectiveDate();

Seoc seoc = SeocObjectGenerator.getSeoc(1, "Test", 10, "1.0.1", effectiveDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1, null);
seoc.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc);
PayableService service2 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc);

seoc.getServices().add(service1);
seoc.getServices().add(service2);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc.setHptcs(hptcs);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc);

// context has correct etag
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc));
SeocThreadLocal.setContext(context);

SeocGenericResponse seocResponse = seocService.reverseSeoc(1);

// Activation passes
assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);

Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());

ArgumentCaptor<Seoc> argCaptor = ArgumentCaptor.forClass(Seoc.class);
Mockito.verify(seocRepository, Mockito.times(1)).save(argCaptor.capture());
}

/**
* Description: Reverse SEOC - status is In-Progress
*/
@Test
public void reverseSeocStatusInProgress() throws Exception {
Seoc seoc = SeocObjectGenerator.getSeoc(1, "Test", 10, null, null, null, "disclaimer", 5, "Description", true,
"ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1, SeocObjectGenerator.sl1,
inprogress, SeocObjectGenerator.qasp1, null);
seoc.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc);
PayableService service2 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc);

seoc.getServices().add(service1);
seoc.getServices().add(service2);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc.setHptcs(hptcs);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc);

Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc));
SeocThreadLocal.setContext(context);

SeocGenericResponse seocResponse = seocService.reverseSeoc(1);

// Validation fails, status is In-Progress
assertThat(seocResponse.getMessage()).isEqualTo(
"Seoc is not eligible for reversal. Current status of SEOC is " + Constants.STATUS_INPROGRESS);
assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());

}

/**
* Description: Reverse SEOC - status is Active
*/
@Test
public void reverseSeocStatusActive() throws Exception {
Date effectiveDate = TestUtil.getEffectiveDatePast();
Seoc seoc = SeocObjectGenerator.getSeoc(1, "Test", 10, "1.0.1", effectiveDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1, null);
seoc.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc);
PayableService service2 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc);

seoc.getServices().add(service1);
seoc.getServices().add(service2);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc.setHptcs(hptcs);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc);

Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc));
SeocThreadLocal.setContext(context);

SeocGenericResponse seocResponse = seocService.reverseSeoc(1);

// Validation fails, status is In-Progress
assertThat(seocResponse.getMessage())
.isEqualTo("Seoc is not eligible for reversal. Current status of SEOC is " + Constants.STATUS_ACTIVE);
assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());

}

/**
* Description: Reverse SEOC - status is Discontinued
*/
@Test
public void reverseSeocStatusDiscontinued() throws Exception {
Date effectiveDate = TestUtil.getEffectiveDatePast();
Date endDate = TestUtil.getEffectiveDatePast();
Seoc seoc = SeocObjectGenerator.getSeoc(1, "Test", 10, "1.0.1", effectiveDate, endDate, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1, null);
seoc.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc);
PayableService service2 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc);

seoc.getServices().add(service1);
seoc.getServices().add(service2);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc.setHptcs(hptcs);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc);

Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc));
SeocThreadLocal.setContext(context);

SeocGenericResponse seocResponse = seocService.reverseSeoc(1);

// Validation fails, status is In-Progress
assertThat(seocResponse.getMessage()).isEqualTo(
"Seoc is not eligible for reversal. Current status of SEOC is " + Constants.STATUS_DISCONTINUED);
assertThat(seocResponse.getStatus()).isEqualTo(Constants.FAILURE);

Mockito.verify(seocRepository, Mockito.times(1)).findById(Mockito.anyInt());

}

/**
* Description: Reverse SEOC - New Date Hold SEOC
*/
@Test
public void reverseSeocNewDateHold() throws Exception {
Date effectiveDate = TestUtil.getEffectiveDate();
Seoc seoc = SeocObjectGenerator.getSeoc(1, "Test", 10, "1.0.1", effectiveDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, effectiveDate, "SEOCSYSTEMUSER", null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1, null);
seoc.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc);
PayableService service2 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc);

seoc.getServices().add(service1);
seoc.getServices().add(service2);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc.setHptcs(hptcs);

Mockito.when(seocRepository.findById(1)).thenReturn(seoc);

Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc));
SeocThreadLocal.setContext(context);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

SeocGenericResponse seocResponse = seocService.reverseSeoc(1);

// The SEOC is reverted back to In-Progress
assertThat(seoc.getStatus()).isEqualTo(inprogress);
assertThat(seoc.getVersionNumber()).isEqualTo(null);
assertThat(seoc.getEffectiveDate()).isEqualTo(null);
assertThat(seoc.getActivatedTimestamp()).isEqualTo(null);
assertThat(seoc.getActivatedBy()).isEqualTo(null);

assertThat(seocResponse.getSeocId()).isEqualTo(seoc.getId());
assertThat(seocResponse.getSeocKey()).isEqualTo(seoc.getSeocKey());
assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);

Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());

ArgumentCaptor<Seoc> argCaptor = ArgumentCaptor.forClass(Seoc.class);
Mockito.verify(seocRepository, Mockito.times(1)).save(argCaptor.capture());
}

/**
* Description: Reverse SEOC - Revision Date Hold SEOC
*/
@Test
public void reverseSeocRevisionDateHold() {
int seocKey = 1;
int id = 1;
Date newEffectiveDate = TestUtil.getEffectiveDate();
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-01-2018 05:01:00 AM");
Date endDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");

Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", seocKey, "1.0.3", newEffectiveDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service11 = SeocObjectGenerator.getPayableService(1, "Test Service11", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service12 = SeocObjectGenerator.getPayableService(2, "Test Service12", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service11);
seoc1.getServices().add(service12);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc1.setHptcs(hptcs);

// Discontinued SEOC
Seoc seoc2 = SeocObjectGenerator.getSeoc(2, "Test", seocKey, "1.0.1", effectiveDate, endDate, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, effectiveDate, "SEOCSYSTEMUSER", endDate,
"SYSTEMSEOCUSER", SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1,
null);
seoc2.setServices(new ArrayList<PayableService>());

PayableService service21 = SeocObjectGenerator.getPayableService(3, "Test Service21", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc2);
PayableService service22 = SeocObjectGenerator.getPayableService(4, "Test Service22", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc2);

seoc2.getServices().add(service21);
seoc2.getServices().add(service22);

hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc2.setHptcs(hptcs);

// Active SEOC
Seoc seoc3 = SeocObjectGenerator.getSeoc(3, "Test", seocKey, "1.0.2", endDate, newEffectiveDate, "disclaimer",
5, "Description", true, "ProceduralOverview", 5, endDate, "SEOCSYSTEMUSER", newEffectiveDate,
"SYSTEMSEOCUSER", SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1,
null);
seoc3.setServices(new ArrayList<PayableService>());

PayableService service31 = SeocObjectGenerator.getPayableService(5, "Test Service31", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc3);
PayableService service32 = SeocObjectGenerator.getPayableService(6, "Test Service32", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc3);

seoc3.getServices().add(service31);
seoc3.getServices().add(service32);

hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc3.setHptcs(hptcs);

Set<Seoc> seocs = new HashSet<Seoc>();
seocs.add(seoc2);
seocs.add(seoc3);

Mockito.when(seocRepository.findBySeocKey(1)).thenReturn(seocs);

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

// Set eTag in the context
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
SeocThreadLocal.setContext(context);

SeocGenericResponse seocResponse = seocService.reverseSeoc(1);

// The SEOC is reverted back to In-Progress
assertThat(seoc1.getStatus()).isEqualTo(inprogress);
assertThat(seoc1.getVersionNumber()).isEqualTo(Constants.VERSION_PENDING_REVISION);
assertThat(seoc1.getEffectiveDate()).isEqualTo(null);
assertThat(seoc1.getActivatedTimestamp()).isEqualTo(null);
assertThat(seoc1.getActivatedBy()).isEqualTo(null);

// The previous version is no longer scheduled to be Discontinued
assertThat(seoc3.getEndDate()).isEqualTo(null);
assertThat(seoc3.getDiscontinuedTimestamp()).isEqualTo(null);
assertThat(seoc3.getDiscontinuedBy()).isEqualTo(null);

assertThat(seocResponse.getSeocId()).isEqualTo(seoc1.getId());
assertThat(seocResponse.getSeocKey()).isEqualTo(seoc1.getSeocKey());
assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);

Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());

ArgumentCaptor<Seoc> argCaptor = ArgumentCaptor.forClass(Seoc.class);
Mockito.verify(seocRepository, Mockito.times(2)).save(argCaptor.capture());
}

/**
* Description: Reverse SEOC - Revision Date Hold SEOC, previous version is
* Discontinued
*/
@Test
public void reverseSeocRevisionDateHoldPreviousVersionDiscontinued() {
int seocKey = 1;
int id = 1;
Date newEffectiveDate = TestUtil.getEffectiveDate();
Date previousEndDate = TestUtil.getEffectiveDatePast();
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-01-2018 05:01:00 AM");
Date endDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");

Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", seocKey, "1.0.3", newEffectiveDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, newEffectiveDate, "SEOCSYSTEMUSER", null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service11 = SeocObjectGenerator.getPayableService(1, "Test Service11", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service12 = SeocObjectGenerator.getPayableService(2, "Test Service12", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service11);
seoc1.getServices().add(service12);

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc1.setHptcs(hptcs);

// Discontinued SEOC
Seoc seoc2 = SeocObjectGenerator.getSeoc(2, "Test", seocKey, "1.0.1", effectiveDate, endDate, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, effectiveDate, "SEOCSYSTEMUSER", endDate,
"SYSTEMSEOCUSER", SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1,
null);
seoc2.setServices(new ArrayList<PayableService>());

PayableService service21 = SeocObjectGenerator.getPayableService(3, "Test Service21", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc2);
PayableService service22 = SeocObjectGenerator.getPayableService(4, "Test Service22", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc2);

seoc2.getServices().add(service21);
seoc2.getServices().add(service22);

hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc2.setHptcs(hptcs);

// Discontinued SEOC - previous version
Seoc seoc3 = SeocObjectGenerator.getSeoc(3, "Test", seocKey, "1.0.2", endDate, previousEndDate, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, endDate, "SEOCSYSTEMUSER", previousEndDate,
"SYSTEMSEOCUSER", SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1,
null);
seoc3.setServices(new ArrayList<PayableService>());

PayableService service31 = SeocObjectGenerator.getPayableService(5, "Test Service31", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc3);
PayableService service32 = SeocObjectGenerator.getPayableService(6, "Test Service32", 5, "weeks", 5, "ANY",
null, null, SeocObjectGenerator.cs1Set, seoc3);

seoc3.getServices().add(service31);
seoc3.getServices().add(service32);

hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

seoc3.setHptcs(hptcs);

Set<Seoc> seocs = new HashSet<Seoc>();
seocs.add(seoc2);
seocs.add(seoc3);

Mockito.when(seocRepository.findBySeocKey(1)).thenReturn(seocs);

Mockito.when(seocRepository.findById(id)).thenReturn(seoc1);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_DATEHOLD)).thenReturn(dateHold);

Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);

// Set eTag in the context
Context context = new Context();
context.setEtag(SeocServiceHelper.getHashCodeOfSeoc(seoc1));
SeocThreadLocal.setContext(context);

Date previousDiscontinuedTimestampBeforeReverse = seoc3.getDiscontinuedTimestamp();

SeocGenericResponse seocResponse = seocService.reverseSeoc(1);

// The SEOC is reverted back to In-Progress
assertThat(seoc1.getStatus()).isEqualTo(inprogress);
assertThat(seoc1.getVersionNumber()).isEqualTo(Constants.VERSION_PENDING_REVISION);
assertThat(seoc1.getEffectiveDate()).isEqualTo(null);
assertThat(seoc1.getActivatedTimestamp()).isEqualTo(null);
assertThat(seoc1.getActivatedBy()).isEqualTo(null);

// The previous version should not be modified
assertThat(seoc3.getEndDate().getTime()).isEqualTo(previousEndDate.getTime());
assertThat(seoc3.getDiscontinuedTimestamp().getTime())
.isEqualTo(previousDiscontinuedTimestampBeforeReverse.getTime());
assertThat(seoc3.getDiscontinuedBy()).isEqualTo("SYSTEMSEOCUSER");

assertThat(seocResponse.getSeocId()).isEqualTo(seoc1.getId());
assertThat(seocResponse.getSeocKey()).isEqualTo(seoc1.getSeocKey());
assertThat(seocResponse.getStatus()).isEqualTo(Constants.SUCCESS);

Mockito.verify(seocRepository, Mockito.times(2)).findById(Mockito.anyInt());

ArgumentCaptor<Seoc> argCaptor = ArgumentCaptor.forClass(Seoc.class);
Mockito.verify(seocRepository, Mockito.times(1)).save(argCaptor.capture());
}

@Test
public void getActiveSeocs() {

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

// seoc1 - Active seoc
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 10, "1.2.3", TestUtil.getEffectiveDate(), null,
"disclaimer", 5, "Description", true, "ProceduralOverview", 5, null, null, null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, dateHold, null, null);
seoc1.setServices(new ArrayList<PayableService>());
seoc1.setHptcs(hptcs);

Date activationDate = ApiUtil.getUTCZoneDateTime("09-05-2018 05:01:00 AM");
Seoc seoc2 = SeocObjectGenerator.getSeoc(2, "Test", 10, "1.2.2", activationDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, null, null);
seoc2.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);

seoc2.getServices().add(service1);
seoc2.getServices().add(service2);
seoc2.setHptcs(hptcs);

Set<Seoc> allSeocs = new HashSet<Seoc>();
allSeocs.add(seoc1);
allSeocs.add(seoc2);

Mockito.when(seocRepository.findActiveSeocs()).thenReturn(allSeocs);

List<Seoc> expectedActiveSeocs = seocService.getActiveSeocs();

Set<Seoc> actualActiveSeocs = new HashSet<Seoc>();
actualActiveSeocs.add(seoc2);

assertThat(actualActiveSeocs.size()).isEqualTo(expectedActiveSeocs.size());

assertThat(expectedActiveSeocs).contains(seoc2);

Mockito.verify(seocRepository, Mockito.times(1)).findActiveSeocs();
}

@Test
public void getActiveSeocsNoSeocsAvailable() {
Mockito.when(seocRepository.findActiveSeocs()).thenReturn(null);

List<Seoc> expectedActiveSeocs = seocService.getActiveSeocs();

assertThat(expectedActiveSeocs).isEmpty();

Mockito.verify(seocRepository, Mockito.times(1)).findActiveSeocs();

}

@Test
public void getPublishedSeocs() {

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

// ServiceHptcs on ClinicalService cs1
Set<ServiceHptc> serviceHptcs = new HashSet<ServiceHptc>();
ServiceHptc shptc1 = null;
ServiceHptc shptc2 = null;
ServiceHptc shptc3 = null;
for (String msc : ApiUtil.getMscFromClinicalServices(SeocObjectGenerator.cs1Set)) {
shptc1 = new ServiceHptc(new ServiceHptcId(SeocObjectGenerator.hptc1.getHptc(), msc));
serviceHptcs.add(shptc1);
}
for (String msc : ApiUtil.getMscFromClinicalServices(SeocObjectGenerator.cs1Set)) {
shptc2 = new ServiceHptc(new ServiceHptcId(SeocObjectGenerator.hptc2.getHptc(), msc));
serviceHptcs.add(shptc2);
}
for (String msc : ApiUtil.getMscFromClinicalServices(SeocObjectGenerator.cs2Set)) {
shptc3 = new ServiceHptc(new ServiceHptcId(SeocObjectGenerator.hptc2.getHptc(), msc));
serviceHptcs.add(shptc3);
}

// Seoc activated - future activation date
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 10, "1.2.3", TestUtil.getEffectiveDateFuture(), null,
"disclaimer", 5, "Description", true, "ProceduralOverview", 5, null, null, null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, dateHold, null, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);
seoc1.setHptcs(hptcs);

// Active seoc
Date activationDate = ApiUtil.getUTCZoneDateTime("09-05-2018 05:01:00 AM");
Seoc seoc2 = SeocObjectGenerator.getSeoc(2, "Test", 10, "1.2.2", activationDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, null, null);
seoc2.setServices(new ArrayList<PayableService>());

PayableService service3 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc2);
PayableService service4 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc2);

seoc2.getServices().add(service3);
seoc2.getServices().add(service4);
seoc2.setHptcs(hptcs);

// Discontinued Seoc
Date discontinuedDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
Seoc seoc3 = SeocObjectGenerator.getSeoc(3, "Test", 10, "1.2.1", activationDate, discontinuedDate, "disclaimer",
5, "Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, null, null);
seoc3.setServices(new ArrayList<PayableService>());

PayableService service5 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs2Set, seoc3);
PayableService service6 = SeocObjectGenerator.getPayableService(1, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs2Set, seoc3);

seoc3.getServices().add(service5);
seoc3.getServices().add(service6);
seoc3.setHptcs(hptcs);

Set<Seoc> allSeocs = new HashSet<Seoc>();
allSeocs.add(seoc1);
allSeocs.add(seoc2);
allSeocs.add(seoc3);

Mockito.when(seocRepository.findPublishedSeocs()).thenReturn(allSeocs);
Mockito.when(serviceHptcRepository.findAll()).thenReturn(serviceHptcs);

List<Seoc> actualSeocs = seocService.getPublishedSeocs();

Set<Seoc> expectedSeocs = new HashSet<Seoc>();
expectedSeocs.add(seoc1);
expectedSeocs.add(seoc2);
expectedSeocs.add(seoc3);

assertThat(actualSeocs.size()).isEqualTo(expectedSeocs.size());

assertThat(expectedSeocs).contains(seoc2, seoc3);

// Assert that serviceHptcs are available in the seoc2 i.e. cs1
Seoc expectedSeoc1 = expectedSeocs.stream().filter(s -> s.getId() == seoc1.getId()).findAny().get();
assertThat(expectedSeoc1.getServices().get(0).getServiceHptcs()).contains(shptc1.getHptc(), shptc2.getHptc());

// Assert that serviceHptcs are available in the seoc2 i.e. cs1
Seoc expectedSeoc2 = expectedSeocs.stream().filter(s -> s.getId() == seoc2.getId()).findAny().get();
assertThat(expectedSeoc2.getServices().get(0).getServiceHptcs()).contains(shptc1.getHptc(), shptc2.getHptc());

// Assert that serviceHptcs are not available in the seoc3 i.e. cs2
Seoc expectedSeoc3 = expectedSeocs.stream().filter(s -> s.getId() == seoc3.getId()).findAny().get();
assertThat(expectedSeoc3.getServices().get(0).getServiceHptcs()).contains(shptc3.getHptc());
assertThat(expectedSeoc3.getServices().get(0).getServiceHptcs()).doesNotContain(shptc1.getHptc());

Mockito.verify(serviceHptcRepository, Mockito.times(1)).findAll();
Mockito.verify(seocRepository, Mockito.times(1)).findPublishedSeocs();
}

@Test
public void getPublishedSeocsNoSeocsAvailable() {
Mockito.when(seocRepository.findPublishedSeocs()).thenReturn(null);

List<Seoc> expectedActiveSeocs = seocService.getPublishedSeocs();

assertThat(expectedActiveSeocs).isEmpty();

Mockito.verify(seocRepository, Mockito.times(1)).findPublishedSeocs();

}

@Test
public void getPublishedSeocsRepeatingServiceHptcRecords() {

Set<Hptc> hptcs = new HashSet<Hptc>();
hptcs.add(SeocObjectGenerator.hptc1);

// ServiceHptcs on ClinicalService cs1
Set<ServiceHptc> serviceHptcs = new HashSet<ServiceHptc>();
ServiceHptc shptc1 = null;
ServiceHptc shptc2 = null;
ServiceHptc shptc3 = null;
for (String msc : ApiUtil.getMscFromClinicalServices(SeocObjectGenerator.cs1Set)) {
shptc1 = new ServiceHptc(new ServiceHptcId(SeocObjectGenerator.hptc1.getHptc(), msc));
serviceHptcs.add(shptc1);
}
for (String msc : ApiUtil.getMscFromClinicalServices(SeocObjectGenerator.cs1Set)) {
shptc2 = new ServiceHptc(new ServiceHptcId(SeocObjectGenerator.hptc2.getHptc(), msc));
serviceHptcs.add(shptc2);
}
for (String msc : ApiUtil.getMscFromClinicalServices(SeocObjectGenerator.cs2Set)) {
shptc3 = new ServiceHptc(new ServiceHptcId(SeocObjectGenerator.hptc2.getHptc(), msc));
serviceHptcs.add(shptc3);
}

// Active seoc
Date activationDate = ApiUtil.getUTCZoneDateTime("09-05-2018 05:01:00 AM");
Seoc seoc1 = SeocObjectGenerator.getSeoc(2, "Test", 10, "1.2.2", activationDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, inprogress, null, null);
seoc1.setServices(new ArrayList<PayableService>());

Set<ClinicalService> clinicalServices = new HashSet<ClinicalService>();
clinicalServices.add(SeocObjectGenerator.cs1);
clinicalServices.add(SeocObjectGenerator.cs2);
PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, clinicalServices, seoc1);

seoc1.getServices().add(service1);
seoc1.setHptcs(hptcs);

Set<Seoc> allSeocs = new HashSet<Seoc>();
allSeocs.add(seoc1);

Mockito.when(seocRepository.findPublishedSeocs()).thenReturn(allSeocs);
Mockito.when(serviceHptcRepository.findAll()).thenReturn(serviceHptcs);

List<Seoc> expectedSeocs = seocService.getPublishedSeocs();

Set<Seoc> actualSeocs = new HashSet<Seoc>();
actualSeocs.add(seoc1);

assertThat(actualSeocs.size()).isEqualTo(expectedSeocs.size());

assertThat(expectedSeocs).contains(seoc1);

// Assert that serviceHptcs are not repeated in seoc2 i.e. only one instance of
// shptc2 value
Seoc expectedSeoc3 = expectedSeocs.stream().filter(s -> s.getId() == seoc1.getId()).findAny().get();
assertThat(expectedSeoc3.getServices().get(0).getServiceHptcs().size()).isEqualTo(2);
assertThat(expectedSeoc3.getServices().get(0).getServiceHptcs()).contains(shptc1.getHptc(), shptc2.getHptc());

Mockito.verify(serviceHptcRepository, Mockito.times(1)).findAll();
Mockito.verify(seocRepository, Mockito.times(1)).findPublishedSeocs();
}

/**
* Description: Successfully create new billing code
*/
@Test
public void createBillingCodeCreated() {
CreateBillingCodeRequest billingCodeRequest = CreateBillingCodeRequest.Builder.create().withBillingCode("bc1")
.withCodeType("CT").withDescription("BC1 Desc").withPrecertRequired(false).build();
BillingCode bcReq = new BillingCode();
bcReq.setBillingCode("bc1");
bcReq.setCodeType("CT");
bcReq.setDescription("BC1 Desc");
bcReq.setPrecertRequired(false);

BillingCode bc = new BillingCode();
bc.setBillingCode("bc1");
bc.setCodeType("CT");
bc.setDescription("BC1 Desc");
bc.setPrecertRequired(false);
bc.setId(10);

Mockito.when(genericService.saveBillingCode(bcReq)).thenReturn(bc);
Mockito.when(genericService.getActiveBillingCode(bcReq.getBillingCode())).thenReturn(null);

SeocGenericResponse response = seocService.createBillingCode(billingCodeRequest);

assertThat(response.getAction()).isEqualTo(Constants.CREATED);

ArgumentCaptor<BillingCode> bcCaptor = ArgumentCaptor.forClass(BillingCode.class);
Mockito.verify(genericService, Mockito.times(1)).saveBillingCode(bcCaptor.capture());
Mockito.verify(genericService, Mockito.times(1)).getActiveBillingCode(Mockito.anyString());
Mockito.verifyNoMoreInteractions(genericService);

}

/**
* Description:Creation of new billing code failed due to pre-existing billing
* code
*/
@Test
public void createBillingCodePreexisting() {
CreateBillingCodeRequest billingCodeRequest = CreateBillingCodeRequest.Builder.create().withBillingCode("bc1")
.withCodeType("CT").withDescription("BC1 Desc").withPrecertRequired(false).build();
BillingCode bcReq = new BillingCode();
bcReq.setBillingCode("bc1");
bcReq.setCodeType("CT");
bcReq.setDescription("BC1 Desc");
bcReq.setPrecertRequired(false);

BillingCode bc = new BillingCode();
bc.setBillingCode("bc1");
bc.setCodeType("CT");
bc.setDescription("BC1 Desc");
bc.setPrecertRequired(false);
bc.setId(10);

Mockito.when(genericService.getActiveBillingCode(bcReq.getBillingCode())).thenReturn(bc);

SeocGenericResponse response = seocService.createBillingCode(billingCodeRequest);
assertThat(response.getAction()).isEqualTo(Constants.FAILURE);

Mockito.verify(genericService, Mockito.times(1)).getActiveBillingCode(Mockito.anyString());
Mockito.verifyNoMoreInteractions(genericService);

}

@Test
public void retrieveSeocsByBillingCodeBillingCodeNotFound() {
String billingCode = "code101";
Mockito.when(genericService.getActiveBillingCode(billingCode)).thenReturn(null);
Set<Seoc> seocs = seocService.retrieveSeocsByBillingCode(billingCode);
assertThat(seocs).isNull();
Mockito.verify(genericService, Mockito.times(1)).getActiveBillingCode(Mockito.anyString());
}

@Test
public void retrieveSeocsByBillingCodeServicesNotFound() {
String billingCode = "code102";
BillingCode bc = SeocObjectGenerator.bc2;
Set<PayableService> services = null;

Mockito.when(genericService.getActiveBillingCode(billingCode)).thenReturn(bc);
Mockito.when(serviceRepository.findByBillingCodesId(bc.getId())).thenReturn(services);

Set<Seoc> seocs = seocService.retrieveSeocsByBillingCode(billingCode);
assertThat(seocs).isNull();

Mockito.verify(genericService, Mockito.times(1)).getActiveBillingCode(Mockito.anyString());
Mockito.verify(serviceRepository, Mockito.times(1)).findByBillingCodesId(Mockito.anyInt());
}

@Test
public void retrieveSeocsByBillingCodeSuccess() {
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
// seoc1 - Active seoc with not pending revision
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 1, "1.0.2", effectiveDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, null, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(2, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
service1.setBillingCodes(new HashSet<BillingCode>());
service1.getBillingCodes().add(SeocObjectGenerator.bc1);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

// seoc3 - discontinued form of seoc1
Date endDate = ApiUtil.getUTCZoneDateTime("09-17-2018 05:01:00 AM");
Seoc seoc3 = SeocObjectGenerator.getSeoc(2, "Test", 1, "1.0.1", effectiveDate, endDate, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, null, null);
seoc3.setServices(new ArrayList<PayableService>());

PayableService service13 = SeocObjectGenerator.getPayableService(3, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc3);
PayableService service23 = SeocObjectGenerator.getPayableService(4, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc3);
service23.setBillingCodes(new HashSet<BillingCode>());
service23.getBillingCodes().add(SeocObjectGenerator.bc1);

seoc3.getServices().add(service13);
seoc3.getServices().add(service23);

Set<Seoc> seocs = new HashSet<Seoc>();
seocs.add(seoc1);
seocs.add(seoc3);

String billingCode = "code101";
BillingCode bc = SeocObjectGenerator.bc1;
Set<PayableService> services = new HashSet<PayableService>();

services.add(service1);
services.add(service23);

List<Integer> serviceIds1 = new ArrayList<Integer>();
serviceIds1.add(service1.getId());
serviceIds1.add(service23.getId());

List<Integer> serviceIds2 = new ArrayList<Integer>();
serviceIds2.add(service23.getId());
serviceIds2.add(service1.getId());

Mockito.when(genericService.getActiveBillingCode(billingCode)).thenReturn(bc);
Mockito.when(serviceRepository.findByBillingCodesId(bc.getId())).thenReturn(services);
Mockito.when(seocRepository.findByServicesIdIn(serviceIds1.stream().toArray(Integer[]::new))).thenReturn(seocs);
Mockito.when(seocRepository.findByServicesIdIn(serviceIds2.stream().toArray(Integer[]::new))).thenReturn(seocs);

Set<Seoc> seocsActual = seocService.retrieveSeocsByBillingCode(billingCode);
Set<Seoc> seocsExpected = new HashSet<Seoc>();
seocsExpected.add(seoc1);

assertThat(seocsActual).isEqualTo(seocsExpected);

Mockito.verify(genericService, Mockito.times(1)).getActiveBillingCode(Mockito.anyString());
Mockito.verify(serviceRepository, Mockito.times(1)).findByBillingCodesId(Mockito.anyInt());
ArgumentCaptor<Integer[]> argIntegerCaptor = (ArgumentCaptor<Integer[]>) ArgumentCaptor
.forClass(Integer[].class);
Mockito.verify(seocRepository, Mockito.times(1)).findByServicesIdIn(argIntegerCaptor.capture());
}

@Test
public void discontinueBillingCodeCodeEmpty() {
String code = null;
CreateBillingCodeRequest billingCodeRequest = CreateBillingCodeRequest.Builder.create()
.withPrevBillingCode(code).build();
SeocGenericResponse seocResponse = seocService.manageBillingCode(billingCodeRequest);
assertThat(seocResponse.getAction()).isEqualTo(Constants.FAILURE);
}

@Test
public void discontinueBillingCodeBillingCodeNotAvailable() {
String code = "BC1";
BillingCode bc = null;
CreateBillingCodeRequest billingCodeRequest = CreateBillingCodeRequest.Builder.create()
.withPrevBillingCode(code).build();
Mockito.when(genericService.getActiveBillingCode(code)).thenReturn(bc);

SeocGenericResponse seocResponse = seocService.manageBillingCode(billingCodeRequest);
assertThat(seocResponse.getAction()).isEqualTo(Constants.FAILURE);

Mockito.verify(genericService, Mockito.times(1)).getActiveBillingCode(Mockito.anyString());
}

@Test
public void discontinueBillingCodeRetrieveBillingCodeSuccess() {
BillingCode bc = SeocObjectGenerator.getBillingCode(SeocObjectGenerator.bc1.getId(),
SeocObjectGenerator.bc1.getBillingCode(), SeocObjectGenerator.bc1.getCodeType(),
SeocObjectGenerator.bc1.getDescription(), SeocObjectGenerator.bc1.getPrecertRequired());
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
// seoc1 - Active seoc with pending revision
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 1, "1.0.2", effectiveDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "YES", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(2, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
service1.setBillingCodes(new HashSet<BillingCode>());
service1.getBillingCodes().add(bc);
service1.getBillingCodes().add(SeocObjectGenerator.bc2);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

// seoc2 - In progress form of seoc1
Seoc seoc2 = SeocObjectGenerator.getSeoc(2, "Test", 1, Constants.VERSION_PENDING_REVISION, null, null,
"disclaimer", 5, "Description", true, "ProceduralOverview", 5, null, null, null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, inprogress, SeocObjectGenerator.qasp1, null);
seoc2.setServices(new ArrayList<PayableService>());

PayableService service12 = SeocObjectGenerator.getPayableService(3, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc2);
PayableService service22 = SeocObjectGenerator.getPayableService(4, "Test Service2", 5, "weeks", 5, "YES", null,
null, SeocObjectGenerator.cs1Set, seoc2);
service22.setBillingCodes(new HashSet<BillingCode>());
service22.getBillingCodes().add(bc);

seoc2.getServices().add(service22);
seoc2.getServices().add(service12);

// seoc3 - Active seoc
Seoc seoc3 = SeocObjectGenerator.getSeoc(3, "Test", 2, "1.1.1", TestUtil.getEffectiveDatePast(), null,
"disclaimer", 5, "Description", true, "ProceduralOverview", 5, null, null, null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1, null);
seoc3.setServices(new ArrayList<PayableService>());

PayableService service13 = SeocObjectGenerator.getPayableService(5, "Test Service5", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc3);
PayableService service23 = SeocObjectGenerator.getPayableService(6, "Test Service6", 5, "weeks", 5, "YES", null,
null, SeocObjectGenerator.cs1Set, seoc3);
service23.setBillingCodes(new HashSet<BillingCode>());
service23.getBillingCodes().add(bc);

seoc3.getServices().add(service23);
seoc3.getServices().add(service13);

// seoc4 - Date Hold seoc
Seoc seoc4 = SeocObjectGenerator.getSeoc(4, "Test", 3, "1.2.1", TestUtil.getEffectiveDateFuture(), null,
"disclaimer", 5, "Description", true, "ProceduralOverview", 5, null, null, null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1, null);
seoc4.setServices(new ArrayList<PayableService>());

PayableService service14 = SeocObjectGenerator.getPayableService(7, "Test Service5", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc4);
PayableService service24 = SeocObjectGenerator.getPayableService(8, "Test Service6", 5, "weeks", 5, "YES", null,
null, SeocObjectGenerator.cs1Set, seoc4);
service24.setBillingCodes(new HashSet<BillingCode>());
service24.getBillingCodes().add(bc);

seoc4.getServices().add(service24);
seoc4.getServices().add(service14);

Set<Seoc> seocs = new HashSet<Seoc>();
seocs.add(seoc1);
seocs.add(seoc2);
seocs.add(seoc3);
seocs.add(seoc4);

String billingCode = bc.getBillingCode();
Set<PayableService> services = new HashSet<PayableService>();

services.add(service1);
services.add(service22);
services.add(service23);
services.add(service24);

List<Integer> serviceIds1 = new ArrayList<Integer>();
serviceIds1.add(service24.getId());
serviceIds1.add(service23.getId());
serviceIds1.add(service22.getId());
serviceIds1.add(service1.getId());

List<Integer> serviceIds2 = new ArrayList<Integer>();
serviceIds2.add(service1.getId());
serviceIds2.add(service22.getId());
serviceIds2.add(service23.getId());
serviceIds2.add(service24.getId());

Mockito.when(genericService.getActiveBillingCode(billingCode)).thenReturn(bc);
Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);
Mockito.when(serviceRepository.findByBillingCodesId(bc.getId())).thenReturn(services);
Mockito.when(seocRepository.findByServicesIdIn(serviceIds1.stream().toArray(Integer[]::new))).thenReturn(seocs);
Mockito.when(seocRepository.findByServicesIdIn(serviceIds2.stream().toArray(Integer[]::new))).thenReturn(seocs);

CreateBillingCodeRequest billingCodeRequest = CreateBillingCodeRequest.Builder.create()
.withPrevBillingCode(billingCode).build();

SeocGenericResponse seocResponse = seocService.manageBillingCode(billingCodeRequest);
assertThat(seocResponse.getAction()).isEqualTo(Constants.SUCCESS);
assertThat(service1.getBillingCodes()).contains(bc);
assertThat(service22.getBillingCodes()).doesNotContain(bc);
assertThat(service23.getBillingCodes()).contains(bc);
assertThat(service24.getBillingCodes()).doesNotContain(bc);
assertThat(seoc4.getCalculatedStatus()).isEqualTo(Constants.STATUS_INPROGRESS);
assertThat(bc.getDeactivated()).isTrue();

Mockito.verify(genericService, Mockito.times(2)).getActiveBillingCode(Mockito.anyString());
Mockito.verify(serviceRepository, Mockito.times(1)).findByBillingCodesId(Mockito.anyInt());
ArgumentCaptor<Integer[]> argIntegerCaptor = (ArgumentCaptor<Integer[]>) ArgumentCaptor
.forClass(Integer[].class);
Mockito.verify(seocRepository, Mockito.times(1)).findByServicesIdIn(argIntegerCaptor.capture());
}

@Test
public void updateBillingCodeCodeEmpty() {
String code = null;
CreateBillingCodeRequest billingCodeRequest = CreateBillingCodeRequest.Builder.create()
.withBillingCode("code116").withCodeType(null).withDescription(null).withPrecertRequired(null)
.withPrevBillingCode(code).build();
SeocGenericResponse seocResponse = seocService.manageBillingCode(billingCodeRequest);
assertThat(seocResponse.getAction()).isEqualTo(Constants.FAILURE);
}

@Test
public void updateBillingCodeBillingCodeNotAvailable() {
String code = "BC1";
BillingCode bc = null;
CreateBillingCodeRequest billingCodeRequest = CreateBillingCodeRequest.Builder.create()
.withBillingCode("code116").withCodeType("CPT").withDescription("description116")
.withPrecertRequired(true).withPrevBillingCode(code).build();
Mockito.when(genericService.getActiveBillingCode(code)).thenReturn(bc);

SeocGenericResponse seocResponse = seocService.manageBillingCode(billingCodeRequest);
assertThat(seocResponse.getAction()).isEqualTo(Constants.FAILURE);

Mockito.verify(genericService, Mockito.times(1)).getActiveBillingCode(Mockito.anyString());
}

// TODO: Resolve issue with updated billing code not being added to applicable
// services
@Test
@Ignore
public void updateBillingCodeRetrieveBillingCodeSuccess() {
BillingCode bc = SeocObjectGenerator.getBillingCode(SeocObjectGenerator.bc1.getId(),
SeocObjectGenerator.bc1.getBillingCode(), SeocObjectGenerator.bc1.getCodeType(),
SeocObjectGenerator.bc1.getDescription(), SeocObjectGenerator.bc1.getPrecertRequired());
Date effectiveDate = ApiUtil.getUTCZoneDateTime("09-07-2018 05:01:00 AM");
// seoc1 - Active seoc with pending revision
Seoc seoc1 = SeocObjectGenerator.getSeoc(1, "Test", 1, "1.0.2", effectiveDate, null, "disclaimer", 5,
"Description", true, "ProceduralOverview", 5, null, null, null, null, SeocObjectGenerator.cc1,
SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1, null);
seoc1.setServices(new ArrayList<PayableService>());

PayableService service1 = SeocObjectGenerator.getPayableService(1, "Test Service1", 5, "weeks", 5, "YES", null,
null, SeocObjectGenerator.cs1Set, seoc1);
PayableService service2 = SeocObjectGenerator.getPayableService(2, "Test Service2", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc1);
service1.setBillingCodes(new HashSet<BillingCode>());
service1.getBillingCodes().add(bc);
service1.getBillingCodes().add(SeocObjectGenerator.bc2);

seoc1.getServices().add(service1);
seoc1.getServices().add(service2);

// seoc2 - In progress form of seoc1
Seoc seoc2 = SeocObjectGenerator.getSeoc(2, "Test", 1, Constants.VERSION_PENDING_REVISION, null, null,
"disclaimer", 5, "Description", true, "ProceduralOverview", 5, null, null, null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, inprogress, SeocObjectGenerator.qasp1, null);
seoc2.setServices(new ArrayList<PayableService>());

PayableService service12 = SeocObjectGenerator.getPayableService(3, "Test Service1", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc2);
PayableService service22 = SeocObjectGenerator.getPayableService(4, "Test Service2", 5, "weeks", 5, "YES", null,
null, SeocObjectGenerator.cs1Set, seoc2);
service22.setBillingCodes(new HashSet<BillingCode>());
service22.getBillingCodes().add(bc);

seoc2.getServices().add(service22);
seoc2.getServices().add(service12);

// seoc3 - Active seoc
Seoc seoc3 = SeocObjectGenerator.getSeoc(3, "Test", 2, "1.1.1", TestUtil.getEffectiveDatePast(), null,
"disclaimer", 5, "Description", true, "ProceduralOverview", 5, null, null, null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1, null);
seoc3.setServices(new ArrayList<PayableService>());

PayableService service13 = SeocObjectGenerator.getPayableService(5, "Test Service5", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc3);
PayableService service23 = SeocObjectGenerator.getPayableService(6, "Test Service6", 5, "weeks", 5, "YES", null,
null, SeocObjectGenerator.cs1Set, seoc3);
service23.setBillingCodes(new HashSet<BillingCode>());
service23.getBillingCodes().add(bc);

seoc3.getServices().add(service23);
seoc3.getServices().add(service13);

// seoc4 - Date Hold seoc
Seoc seoc4 = SeocObjectGenerator.getSeoc(4, "Test", 3, "1.2.1", TestUtil.getEffectiveDateFuture(), null,
"disclaimer", 5, "Description", true, "ProceduralOverview", 5, null, null, null, null,
SeocObjectGenerator.cc1, SeocObjectGenerator.sl1, dateHold, SeocObjectGenerator.qasp1, null);
seoc4.setServices(new ArrayList<PayableService>());

PayableService service14 = SeocObjectGenerator.getPayableService(7, "Test Service5", 5, "weeks", 5, "ANY", null,
null, SeocObjectGenerator.cs1Set, seoc4);
PayableService service24 = SeocObjectGenerator.getPayableService(8, "Test Service6", 5, "weeks", 5, "YES", null,
null, SeocObjectGenerator.cs1Set, seoc4);
service24.setBillingCodes(new HashSet<BillingCode>());
service24.getBillingCodes().add(bc);

seoc4.getServices().add(service24);
seoc4.getServices().add(service14);

Set<Seoc> seocs = new HashSet<Seoc>();
seocs.add(seoc1);
seocs.add(seoc2);
seocs.add(seoc3);
seocs.add(seoc4);

String billingCode = bc.getBillingCode();
BillingCode bc2 = SeocObjectGenerator.getBillingCode(0, "code101", bc.getCodeType(), bc.getDescription(),
bc.getPrecertRequired());
Set<PayableService> services = new HashSet<PayableService>();

services.add(service1);
services.add(service22);
services.add(service23);
services.add(service24);

List<Integer> serviceIds1 = new ArrayList<Integer>();
serviceIds1.add(service24.getId());
serviceIds1.add(service23.getId());
serviceIds1.add(service22.getId());
serviceIds1.add(service1.getId());

List<Integer> serviceIds2 = new ArrayList<Integer>();
serviceIds2.add(service1.getId());
serviceIds2.add(service22.getId());
serviceIds2.add(service23.getId());
serviceIds2.add(service24.getId());

Mockito.when(genericService.getActiveBillingCode(billingCode)).thenReturn(bc);
Mockito.when(genericService.getStatusByDescription(Constants.STATUS_INPROGRESS)).thenReturn(inprogress);
Mockito.when(serviceRepository.findByBillingCodesId(bc.getId())).thenReturn(services);
Mockito.when(seocRepository.findByServicesIdIn(serviceIds1.stream().toArray(Integer[]::new))).thenReturn(seocs);
Mockito.when(seocRepository.findByServicesIdIn(serviceIds2.stream().toArray(Integer[]::new))).thenReturn(seocs);

CreateBillingCodeRequest billingCodeRequest = CreateBillingCodeRequest.Builder.create()
.withBillingCode("code101").withCodeType("CPT").withPrecertRequired(true).withDescription("Desc1111")
.withPrevBillingCode(billingCode).build();

SeocGenericResponse seocResponse = seocService.manageBillingCode(billingCodeRequest);
assertThat(seocResponse.getAction()).isEqualTo(Constants.SUCCESS);
assertThat(service1.getBillingCodes()).contains(bc);
assertThat(service1.getBillingCodes()).doesNotContain(bc2);
assertThat(service22.getBillingCodes()).doesNotContain(bc);
assertThat(service22.getBillingCodes()).contains(bc2);
assertThat(service23.getBillingCodes()).contains(bc);
assertThat(service23.getBillingCodes()).doesNotContain(bc2);
assertThat(service24.getBillingCodes()).doesNotContain(bc);
assertThat(service24.getBillingCodes()).contains(bc2);
assertThat(seoc4.getCalculatedStatus()).isEqualTo(Constants.STATUS_INPROGRESS);
assertThat(bc.getDeactivated()).isTrue();

Mockito.verify(genericService, Mockito.times(2)).getActiveBillingCode(Mockito.anyString());
Mockito.verify(serviceRepository, Mockito.times(1)).findByBillingCodesId(Mockito.anyInt());
ArgumentCaptor<Integer[]> argIntegerCaptor = (ArgumentCaptor<Integer[]>) ArgumentCaptor
.forClass(Integer[].class);
Mockito.verify(seocRepository, Mockito.times(1)).findByServicesIdIn(argIntegerCaptor.capture());
}
}