package sap.ai.st.cm.plugins.ciintegration.odataclient; import static org.apache.commons.lang3.StringUtils.join; import static org.easymock.EasyMock.capture; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createMockBuilder; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expectLastCall; import static org.easymock.EasyMock.replay; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; import static sap.ai.st.cm.plugins.ciintegration.odataclient.Matchers.carriesStatusCode; import static sap.ai.st.cm.plugins.ciintegration.odataclient.Matchers.hasServerSideErrorMessage; import static sap.ai.st.cm.plugins.ciintegration.odataclient.MockHelper.getConfiguration; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.olingo.client.api.ODataClient; import org.apache.olingo.client.api.communication.ODataClientErrorException; import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetIteratorRequest; import org.apache.olingo.client.api.communication.request.retrieve.RetrieveRequestFactory; import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; import org.apache.olingo.client.api.domain.ClientEntity; import org.apache.olingo.client.api.domain.ClientEntitySet; import org.apache.olingo.client.api.domain.ClientEntitySetIterator; import org.apache.olingo.client.api.domain.ClientProperty; import org.apache.olingo.client.core.ODataClientImpl; import org.apache.olingo.client.core.domain.ClientObjectFactoryImpl; import org.apache.olingo.client.core.domain.ClientPropertyImpl; import org.apache.olingo.commons.api.ex.ODataError; import org.easymock.Capture; import org.junit.After; import org.junit.Before; import org.junit.Test; import com.google.common.collect.Sets; import com.sap.cmclient.Transport; public class CMODataClientGetTransportsTest extends CMODataClientBaseTest { private static class TransportDescriptor { String transportId, developmentSystemId; boolean modifiable; static TransportDescriptor create(String transportId, String developmentSystemId, boolean modifiable) { TransportDescriptor t = new TransportDescriptor(); t.transportId = transportId; t.developmentSystemId = developmentSystemId; t.modifiable = modifiable; return t; } } private Capture<String> contentType = Capture.newInstance(); @Before public void setup() throws Exception { super.setup(); } @After public void tearDown() throws Exception{ super.tearDown(); } @Test public void testGetTransportsStraightForward() throws Exception { setMock(examinee, setupMock()); List<Transport> changeTransports = examinee.getChangeTransports("8000042445"); assertThat(join(getTransportIds(changeTransports), " "), allOf( containsString("L21K90002J"), containsString("L21K90002L"), containsString("L21K90002N"))); assertThat(changeTransports.get(0).getDescription(), is(equalTo("S 8000038673: HCP CI Jenkins Deploy UC 1"))); assertThat(changeTransports.get(0).getOwner(), is(equalTo(SERVICE_USER))); assertThat(address.getValue().toASCIIString(), is(equalTo(SERVICE_ENDPOINT + "Changes('8000042445')/Transports"))); } /* * No java 8 streams for the lib since the lib is also used from the jenkins plugin which * has (for some reasons (?)) a constrain to java 7. */ private static Collection<String> getTransportIds(Collection<Transport> transports) { Collection<String> transportIds = Sets.newHashSet(); for(Transport t : transports) { transportIds.add(t.getTransportID()); } return transportIds; } @Test public void testGetTransportsChangeIdDoesNotExist() throws Exception { thrown.expect(ODataClientErrorException.class); thrown.expect(carriesStatusCode(400)); // TODO 404 would be better thrown.expect(hasServerSideErrorMessage("Resource not found for segment ''")); // comment statement below for testing against real backend. // Assert for the captures below needs to be commented also in this case. setMock(examinee, setupMock( new ODataClientErrorException( StatusLines.BAD_REQUEST, new ODataError().setMessage("Resource not found for segment ''")))); try { examinee.getChangeTransports("DOES_NOT_EXIST"); } catch(Exception e) { assertThat(address.getValue().toASCIIString(), is(equalTo(SERVICE_ENDPOINT + "Changes('DOES_NOT_EXIST')/Transports"))); throw e; } } @Test public void testGetTransportsChangeIdNotProvided() throws Exception { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("changeID was null or empty"); setMock(examinee, setupMock()); examinee.getChangeTransports(null); } @Test public void testGetChangeTransportsOnClosedClient() throws Exception{ thrown.expect(IllegalStateException.class); thrown.expectMessage("has been closed"); examinee.close(); examinee.getChangeTransports("xx"); } @Test public void testGetChangeTransportWithEmptyDevelopmentSystemId() throws Exception{ Set<TransportDescriptor> transports = new HashSet<TransportDescriptor>(); transports.add(TransportDescriptor.create("L21K90002N", "", false)); setMock(examinee, setupMock(null, transports)); List<Transport> t = examinee.getChangeTransports("L21K90002N"); assertThat(((CMODataTransport)t.get(0)).getDevelopmentSystemID(), is(equalTo(""))); } private ODataClient setupMock() throws Exception { return setupMock(null); } private ODataClient setupMock(Exception e) { Set<TransportDescriptor> transports = new HashSet<TransportDescriptor>(); transports.add(TransportDescriptor.create("L21K90002N", "xxx~123", false)); transports.add(TransportDescriptor.create("L21K90002L", "xxx~123", false)); transports.add(TransportDescriptor.create("L21K90002J", "xxx~123", true)); return setupMock(e, transports); } @SuppressWarnings("unchecked") private ODataClient setupMock(Exception e, Set<TransportDescriptor> transports) { ODataRetrieveResponse<ClientEntitySetIterator<ClientEntitySet, ClientEntity>> responseMock = createMock(ODataRetrieveResponse.class); if(e != null) { expect(responseMock.getBody()).andThrow(e); } else { ClientEntitySetIterator<ClientEntitySet, ClientEntity> iteratorMock = createMock(ClientEntitySetIterator.class); for(TransportDescriptor t : transports) { expect(iteratorMock.hasNext()).andReturn(true); expect(iteratorMock.next()).andReturn(setupTransportMock(t.transportId, t.developmentSystemId, t.modifiable)); } expect(iteratorMock.hasNext()).andReturn(false); expect(responseMock.getBody()).andReturn(iteratorMock); replay(iteratorMock); } responseMock.close(); expectLastCall(); ODataEntitySetIteratorRequest<ClientEntitySet, ClientEntity> oDataEntityRequestMock = createMock(ODataEntitySetIteratorRequest.class); expect(oDataEntityRequestMock.setAccept(capture(contentType))).andReturn(oDataEntityRequestMock); expect(oDataEntityRequestMock.execute()).andReturn(responseMock); RetrieveRequestFactory retrieveRequestFactoryMock = createMock(RetrieveRequestFactory.class); expect(retrieveRequestFactoryMock.getEntitySetIteratorRequest(capture(address))).andReturn(oDataEntityRequestMock); ODataClient clientMock = createMockBuilder(ODataClientImpl.class) .addMockedMethod("getRetrieveRequestFactory") .addMockedMethod("getConfiguration").createMock(); expect(clientMock.getRetrieveRequestFactory()).andReturn(retrieveRequestFactoryMock); expect(clientMock.getConfiguration()).andReturn(getConfiguration()); replay(responseMock, oDataEntityRequestMock, retrieveRequestFactoryMock, clientMock); return clientMock; } private static ClientEntity setupTransportMock(String transportId, String developmentSystemId, boolean isModifiable) { ClientEntity transportMock = createMock(ClientEntity.class); Map<String, String> props = new HashMap<String ,String>(); props.put("TransportID", transportId); props.put("DevelopmentSystemID", developmentSystemId); props.put("IsModifiable", Boolean.valueOf(isModifiable).toString()); props.put("Description", "S 8000038673: HCP CI Jenkins Deploy UC 1"); props.put("Owner", SERVICE_USER); for(Map.Entry<String, String> e : props.entrySet()) { ClientProperty cp = new ClientPropertyImpl(e.getKey(), new ClientObjectFactoryImpl().newPrimitiveValueBuilder().setValue(e.getValue()).build()); expect(transportMock.getProperty(e.getKey())).andReturn(cp); } replay(transportMock); return transportMock; } }