package combo; import org.junit.Test; import org.springframework.http.HttpRequest; import org.springframework.web.client.HttpClientErrorException; import java.net.URI; import java.util.LinkedList; import java.util.List; import static com.googlecode.catchexception.CatchException.caughtException; import static com.googlecode.catchexception.apis.CatchExceptionAssertJ.then; import static com.googlecode.catchexception.apis.CatchExceptionAssertJ.when; import static combo.ComboAssertions.assertThat; import static combo.ComboFactory.httpCombo; public final class HttpComboTest { private MockHttpComboServer server; private final URI baseUri = RDG.uri().next(); private final Combo combo = httpCombo(baseUri, setMockHttpComboServerFromHttpComboRestTemplate()); @Test public void publishesFact() { //Given final String topicName = RDG.topicName().next(); final PublishedFact fact = new PublishedFact(RDG.string().next(), RDG.integer().next()); server.respondToPublishedFactWithAccepted(topicName, fact); //When combo.publishFact(topicName, fact); //Then server.verify(); } @Test public void throwsExceptionWhenResponseToPublishedFactIsBadRequest() { //Given final String topicName = RDG.topicName().next(); final PublishedFact fact = new PublishedFact(RDG.string().next(), RDG.integer().next()); server.respondToPublishedFactWithBadRequest(topicName, fact); //When when(combo).publishFact(topicName, fact); //Then then(caughtException()) .isInstanceOf(HttpClientErrorException.class) .hasMessage("400 Bad Request"); } @Test public void consumesFirstFactFromTopic() { //Given final String topicName = RDG.topicName().next(); final SubscriptionId subscriptionId = server.expectServerWillAcceptSubscriptionRequestForTopic(topicName); final int comboTimestamp = RDG.integer().next(); final int comboId = RDG.integer().next(); server.expectServerWillRespondWithNextFactForSubscription(subscriptionId, comboTimestamp, comboId); //When final List<ConsumedFact> facts = consumeFacts(topicName); //Then assertThat(facts.get(0)) .hasId(comboId) .hasTimestamp(comboTimestamp) .hasTopicName(topicName); } @Test public void consumesFirstTwoFactsFromTopic() { //Given final String topicName = RDG.topicName().next(); final SubscriptionId subscriptionId = server.expectServerWillAcceptSubscriptionRequestForTopic(topicName); final int secondFactTimestamp = RDG.integer().next(); final int secondFactId = RDG.integer().next(); server.expectServerWillRespondWithNextFactForSubscription(subscriptionId, uk.org.fyodor.generators.RDG.integer().next(), uk.org.fyodor.generators.RDG.integer().next()); server.expectServerWillRespondWithNextFactForSubscription(subscriptionId, secondFactTimestamp, secondFactId); //When final List<ConsumedFact> facts = consumeFacts(topicName); //Then assertThat(facts.get(1)) .hasId(secondFactId) .hasTimestamp(secondFactTimestamp) .hasTopicName(topicName); } @Test public void consumesZeroFactsWhenThereIsNotContent() { //Given final String topicName = RDG.topicName().next(); server.expectServerWillAcceptSubscriptionRequestForTopic(topicName); server.expectServerWillRespondWithNoContent(); //When final List<ConsumedFact> facts = consumeFacts(topicName); //Then assertThat(facts).isEmpty(); server.verify(); } @Test public void onlyPresentFactsAreConsumed() { //Given final String topicName = RDG.topicName().next(); final SubscriptionId subscriptionId = server.expectServerWillAcceptSubscriptionRequestForTopic(topicName); server.expectServerWillRespondWithNoContent(); server.expectServerWillRespondWithNextFactForSubscription(subscriptionId); server.expectServerWillRespondWithNoContent(); server.expectServerWillRespondWithNoContent(); server.expectServerWillRespondWithNoContent(); server.expectServerWillRespondWithNextFactForSubscription(subscriptionId); server.expectServerWillRespondWithNoContent(); //When final List<ConsumedFact> facts = consumeFacts(topicName); //Then assertThat(facts).hasSize(2); } @Test public void visitorsCanAddRestTemplateInterceptors() { //Given final LinkedList<HttpRequest> httpRequests = new LinkedList<>(); final Combo combo = httpCombo(baseUri, setMockHttpComboServerFromHttpComboRestTemplate(), restTemplate -> restTemplate.getInterceptors().add((request, body, execution) -> { httpRequests.add(request); return execution.execute(request, body); })); //And final String topicName = RDG.topicName().next(); final String fact = "Some Fact"; server.respondToPublishedFactWithAccepted(topicName, fact); //When combo.publishFact(topicName, fact); //Then assertThat(httpRequests).hasSize(1); } private List<ConsumedFact> consumeFacts(final String topicName) { final FactCollector<ConsumedFact> factCollector = new FactCollector<>(); try { combo.subscribeTo(topicName, ConsumedFact.class).forEach(factCollector); } catch (final AssertionError ae) { //Swallow exception, we're using it to terminate the fact request loop } return factCollector.facts(); } private ComboFactory.RestTemplateVisitor setMockHttpComboServerFromHttpComboRestTemplate() { return restTemplate -> this.server = new MockHttpComboServer(restTemplate, baseUri); } }