package at.gv.egiz.moazs; import at.gv.egiz.moazs.msg.MsgClientFactory; import at.gv.egiz.moazs.pipeline.DeliveryPipeline; import at.gv.egiz.moazs.pipeline.SameThreadDeliveryPipeline; import at.gv.egiz.moazs.repository.DeliveryRepository; import at.gv.egiz.moazs.repository.InMemoryDeliveryRepository; import at.gv.egiz.moazs.scheme.Mzs2MsgConverter; import at.gv.egiz.moazs.tnvz.TnvzClient; import at.gv.egiz.moazs.tnvz.TnvzResultVerifier; import at.gv.egiz.moazs.verify.MoaSPSSSignatureVerifier; import at.gv.zustellung.app2mzs.xsd.DeliveryRequestType; import at.gv.zustellung.msg.xsd.App2ZusePort; import at.gv.zustellung.msg.xsd.DeliveryRequestStatusType; import at.gv.zustellung.msg.xsd.MetaData; import at.gv.zustellung.tnvz.xsd.MimeTypeList; import at.gv.zustellung.tnvz.xsd.PersonResultType; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import java.util.List; import static at.gv.egiz.moazs.MoaZSException.moaZSException; import static at.gv.zustellung.app2mzs.xsd.ClientType.clientTypeBuilder; import static at.gv.zustellung.app2mzs.xsd.ConfigType.configTypeBuilder; import static at.gv.zustellung.app2mzs.xsd.DeliveryRequestType.Payload; import static at.gv.zustellung.app2mzs.xsd.DeliveryRequestType.Payload.payloadBuilder; import static at.gv.zustellung.app2mzs.xsd.DeliveryRequestType.deliveryRequestTypeBuilder; import static at.gv.zustellung.msg.xsd.DeliveryRequestStatusType.Success.successBuilder; import static at.gv.zustellung.msg.xsd.DeliveryRequestStatusType.deliveryRequestStatusTypeBuilder; import static at.gv.zustellung.msg.xsd.ErrorInfoType.errorInfoTypeBuilder; import static at.gv.zustellung.msg.xsd.MetaData.metaDataBuilder; import static at.gv.zustellung.tnvz.xsd.MimeTypeList.mimeTypeListBuilder; import static at.gv.zustellung.tnvz.xsd.PersonResultSuccessType.personResultSuccessTypeBuilder; import static at.gv.zustellung.tnvz.xsd.PersonResultType.Error.errorBuilder; import static at.gv.zustellung.tnvz.xsd.PersonResultType.personResultTypeBuilder; import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class SameThreadDeliveryPipelineTest { private DeliveryRepository repository = new InMemoryDeliveryRepository(); @Mock private TnvzClient tnvzClient; @Mock private MsgClientFactory msgClientFactory; @Mock private App2ZusePort msgClient; @Mock private Mzs2MsgConverter converter; @Mock private MoaSPSSSignatureVerifier verifier; private DeliveryPipeline pipeline; @Before public void setup() { pipeline = new SameThreadDeliveryPipeline(repository, tnvzClient, new TnvzResultVerifier(), converter, msgClientFactory, verifier); } @Test public void executePipelineWithoutTnvzRequest() { var appDeliveryId = "no-tnvz-request"; var expectedStatus = setupMocks(appDeliveryId, false, List.of(), List.of("*/*")); pipeline.processRequest(appDeliveryId); verifyZeroInteractions(tnvzClient); var actualStatus = repository.getDeliveryRequestStatus(appDeliveryId).get(); assertThat(actualStatus).isEqualTo(expectedStatus); } @Test public void rejectDeliveryWhenReceiverIsNotAddressable() { var appDeliveryId = "not-addressable"; setupMocks(appDeliveryId, true, List.of(), List.of("*/*")); when(tnvzClient.query(any(), any())).thenReturn(setupTnvzError("400", "Person not found.")); pipeline.processRequest(appDeliveryId); var actualCode = repository.getDeliveryRequestStatus(appDeliveryId).get() .getError().getErrorInfo().getCode(); verify(tnvzClient).query(any(), any()); assertThat(actualCode).isEqualTo("400"); } @Test public void acceptWildcardMimeType() { var appDeliveryId = "wild-card-mimetype"; List acceptedTypes = List.of("*/*"); List attachedTypes = List.of("pdf", "xml", "html", "random/attachedtype"); var expectedStatus = setupMocks(appDeliveryId, true, attachedTypes, acceptedTypes); pipeline.processRequest(appDeliveryId); var actualStatus = repository.getDeliveryRequestStatus(appDeliveryId).get(); verify(tnvzClient).query(any(), any()); assertThat(actualStatus).isEqualTo(expectedStatus); } @Test public void rejectMismatchedMimeTypes() { var appDeliveryId = "mismatched-mimetype"; List acceptedTypes = List.of("xml"); List attachedTypes = List.of("pdf", "xml", "html", "random/attachedtype"); setupMocks(appDeliveryId, true, attachedTypes, acceptedTypes); pipeline.processRequest(appDeliveryId); var actualCode = repository.getDeliveryRequestStatus(appDeliveryId).get() .getError().getErrorInfo().getCode(); verify(tnvzClient).query(any(), any()); assertThat(actualCode).isEqualTo(MoaZSException.ERROR_MZS_MIMETYPE_MISSMATCH); } @Test public void acceptSpecificMimeType() { var appDeliveryId = "specific-mimetype"; List acceptedTypes = List.of("pdf", "xml", "html"); List attachedTypes = List.of("pdf", "xml"); var expectedStatus = setupMocks(appDeliveryId, true, attachedTypes, acceptedTypes); pipeline.processRequest(appDeliveryId); var actualStatus = repository.getDeliveryRequestStatus(appDeliveryId).get(); verify(tnvzClient).query(any(), any()); assertThat(actualStatus).isEqualTo(expectedStatus); } @Test public void rejectInvalidSignature() { var appDeliveryId = "invalid-signature"; setupMocks(appDeliveryId, true, List.of(), List.of("*/*")); doThrow(moaZSException("Signature Invalid!")).when(verifier).verify(any()); pipeline.processRequest(appDeliveryId); var actualCode = repository.getDeliveryRequestStatus(appDeliveryId).get() .getError().getErrorInfo().getCode(); assertThat(actualCode).isEqualTo(MoaZSException.ERROR_MOASP_SIGNATURE_INVALID); } private DeliveryRequestStatusType setupMocks(String appDeliveryId, boolean tnvzRequest, List attachedTypes, List acceptedTypes) { var mzsRequest = setupMzsRequest(appDeliveryId, tnvzRequest, attachedTypes); var msgRequest = setupMsgRequest(appDeliveryId); var status = setupStatus(appDeliveryId); var signedStatus = new byte[0]; repository.add(mzsRequest); repository.addSignedDeliveryRequestStatus(signedStatus, appDeliveryId); when(tnvzClient.query(any(), any())).thenReturn(setupTnvzSuccess(acceptedTypes)); when(converter.convert(eq(mzsRequest) )).thenReturn(msgRequest); when(converter.convert(eq(mzsRequest), any())).thenReturn(msgRequest); when(msgClientFactory.create(any())).thenReturn(msgClient); when(msgClient.delivery(msgRequest)).thenReturn(status); return status; } private PersonResultType setupTnvzError(String code, String text) { var info = errorInfoTypeBuilder() .withCode(code) .withText(text) .build(); var error = errorBuilder() .withErrorInfo(info) .build(); return personResultTypeBuilder() .withError(error) .build(); } private PersonResultType setupTnvzSuccess(List mimeTypes) { var success = personResultSuccessTypeBuilder() .withMimeTypeList(setupMimeTypeList(mimeTypes)) .build(); return personResultTypeBuilder() .withSuccess(success) .build(); } private DeliveryRequestStatusType setupStatus(String appDeliveryId) { var success = successBuilder() .withAppDeliveryID(appDeliveryId) .build(); return deliveryRequestStatusTypeBuilder() .withSuccess(success) .build(); } private DeliveryRequestType setupMzsRequest(String appDeliveryId, boolean tnvzRequest, List mimeTypes) { var msgClient = clientTypeBuilder() .withURL("http://zuse") .build(); var config = configTypeBuilder() .withPerformQueryPersonRequest(tnvzRequest) .withMSGClient(msgClient) .build(); return deliveryRequestTypeBuilder() .withMetaData(setupMetaData(appDeliveryId)) .withConfig(config) .withPayload(setupPayload(mimeTypes)) .build(); } private List setupPayload(List mimeTypes) { return mimeTypes.stream() .map((mtype) -> payloadBuilder().withMIMEType(mtype).build()) .collect(toList()); } private MimeTypeList setupMimeTypeList(List mimeTypes) { return mimeTypeListBuilder().withMimeType(mimeTypes).build(); } private at.gv.zustellung.msg.xsd.DeliveryRequestType setupMsgRequest(String appDeliveryId) { return at.gv.zustellung.msg.xsd.DeliveryRequestType.deliveryRequestTypeBuilder() .withMetaData(setupMetaData(appDeliveryId)) .build(); } private MetaData setupMetaData(String appDeliveryId) { return metaDataBuilder() .withAppDeliveryID(appDeliveryId) .build(); } }