// Path: test-utils/src/main/java/me/atam/atam4j/PollingPredicate.java
// public class PollingPredicate<T> {
// 
//     private int maxAttempts;
//     private int retryPollInterval;
//     private Predicate<T> predicate;
//     private Supplier<T> supplier;
// 
//     public PollingPredicate(int maxAttempts, int retryPollInterval, Predicate<T> predicate, Supplier<T> supplier) {
//         this.maxAttempts = maxAttempts;
//         this.retryPollInterval = retryPollInterval;
//         this.predicate = predicate;
//         this.supplier = supplier;
//     }
// 
//     public boolean pollUntilPassedOrMaxAttemptsExceeded() {
//         return eventOccurs();
//     }
// 
//     public void pollUntilPassedOrFail(String errorMessage) {
//         if (!eventOccurs()) {
//             throw new RuntimeException(errorMessage);
//         }
//     }
// 
//     private boolean eventOccurs() {
//         for (int i=0; i< maxAttempts; i++){
//             if (predicate.test(supplier.get())){
//                 return true;
//             }
//             try {
//                 Thread.sleep(retryPollInterval);
//             } catch (InterruptedException e) {
//                 throw new RuntimeException(e);
//             }
//         }
//         return false;
//     }
// }
// 
// Path: atam4j-domain/src/main/java/me/atam/atam4jdomain/TestsRunResult.java
// public final class TestsRunResult {
// 
//     private final Collection<IndividualTestResult> tests;
//     private final Status status;
// 
//     public TestsRunResult(final @JsonProperty("tests")  Collection<IndividualTestResult> tests,
//                           final @JsonProperty("status") Status status) {
//         this.tests = tests;
//         this.status = status;
// 
//     }
// 
//     public TestsRunResult(final Collection<IndividualTestResult> tests) {
//         this.tests = tests;
//         this.status = buildStatus(tests);
//     }
// 
//     public Collection<IndividualTestResult> getTests() {
//         return tests;
//     }
// 
// 
// 
// 
//     public Status getStatus() {
//         return status;
//     }
// 
//     private Status buildStatus(final Collection<IndividualTestResult> testResults) {
//         if (testResults.isEmpty()) {
//             return Status.CATEGORY_NOT_FOUND;
//         }
//         return testResults.stream()
//                           .filter(testReport -> !testReport.isPassed())
//                           .findAny()
//                           .map(failures -> Status.FAILURES)
//                           .orElse(Status.ALL_OK);
//     }
// 
//     public Optional<IndividualTestResult> getTestByClassAndName(String className, String testName) {
//         return tests.stream().filter(t -> t.getTestClass().equals(className)).filter(t -> t.getTestName().equals(testName)).findFirst();
//     }
// 
//     public enum Status {
//         TOO_EARLY("Too early to tell - tests not complete yet"),
//         CATEGORY_NOT_FOUND("This category does not exist"),
//         ALL_OK("All is A OK!"),
//         FAILURES("Failures");
// 
//         private final String message;
// 
//         Status(String message) {
//             this.message = message;
//         }
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
// 
//         TestsRunResult that = (TestsRunResult) o;
// 
//         if (tests != null ? !tests.equals(that.tests) : that.tests != null) return false;
//         return status == that.status;
// 
//     }
// 
//     @Override
//     public int hashCode() {
//         int result = tests != null ? tests.hashCode() : 0;
//         result = 31 * result + (status != null ? status.hashCode() : 0);
//         return result;
//     }
// 
//     @Override
//     public String toString() {
//         return "TestsRunResult{" +
//                 "tests=" + tests +
//                 ", status=" + status +
//                 '}';
//     }
// }
// 
// Path: acceptance-tests/src/main/java/me/atam/atam4jsampleapp/ApplicationConfiguration.java
// public class ApplicationConfiguration extends Configuration {
// 
//     @JsonProperty
//     private int initialDelayInMillis;
// 
//     @JsonProperty
//     private Class[] testClasses;
//     private long periodInMillis;
// 
//     public Class[] getTestClasses(){
//         return testClasses;
//     }
// 
//     public int getInitialDelayInMillis() {
//         return initialDelayInMillis;
//     }
// 
//     public long getPeriodInMillis() {
//         return periodInMillis;
//     }
// }
// 
// Path: acceptance-tests/src/test/java/me/atam/atam4jsampleapp/testsupport/AcceptanceTestTimeouts.java
// public static final int MAX_ATTEMPTS = 2000;
// 
// Path: acceptance-tests/src/test/java/me/atam/atam4jsampleapp/testsupport/AcceptanceTestTimeouts.java
// public static final int RETRY_POLL_INTERVAL = 1;


import io.dropwizard.testing.DropwizardTestSupport;
import me.atam.atam4j.PollingPredicate;
import me.atam.atam4jdomain.TestsRunResult;
import me.atam.atam4jsampleapp.ApplicationConfiguration;
import org.glassfish.jersey.client.JerseyClientBuilder;
import org.junit.After;
import javax.ws.rs.core.Response;
import static me.atam.atam4jsampleapp.testsupport.AcceptanceTestTimeouts.MAX_ATTEMPTS;
import static me.atam.atam4jsampleapp.testsupport.AcceptanceTestTimeouts.RETRY_POLL_INTERVAL;
import static org.junit.Assert.assertTrue;
package me.atam.atam4jsampleapp.testsupport;




public abstract class AcceptanceTest {

    protected DropwizardTestSupport<ApplicationConfiguration> dropwizardTestSupportAppConfig;

    @After
    public void stopApplication() {
        dropwizardTestSupportAppConfig.after();
    }

    public Response getTestRunResultFromServer(String testsURI){
        return new JerseyClientBuilder().build().target(
                testsURI)
                .request()
                .get();
    }

    public String getTestsURI() {
        return String.format("http://localhost:%d/tests", dropwizardTestSupportAppConfig.getLocalPort());
    }

    public Response getResponseFromTestsWithCategoryOnceTestRunHasCompleted(String category) {
        waitUntilTestRunHasCompleted();
        return getTestRunResultFromServer(getTestsURI() + "/" + category);
    }

// Path: test-utils/src/main/java/me/atam/atam4j/PollingPredicate.java
// public class PollingPredicate<T> {
// 
//     private int maxAttempts;
//     private int retryPollInterval;
//     private Predicate<T> predicate;
//     private Supplier<T> supplier;
// 
//     public PollingPredicate(int maxAttempts, int retryPollInterval, Predicate<T> predicate, Supplier<T> supplier) {
//         this.maxAttempts = maxAttempts;
//         this.retryPollInterval = retryPollInterval;
//         this.predicate = predicate;
//         this.supplier = supplier;
//     }
// 
//     public boolean pollUntilPassedOrMaxAttemptsExceeded() {
//         return eventOccurs();
//     }
// 
//     public void pollUntilPassedOrFail(String errorMessage) {
//         if (!eventOccurs()) {
//             throw new RuntimeException(errorMessage);
//         }
//     }
// 
//     private boolean eventOccurs() {
//         for (int i=0; i< maxAttempts; i++){
//             if (predicate.test(supplier.get())){
//                 return true;
//             }
//             try {
//                 Thread.sleep(retryPollInterval);
//             } catch (InterruptedException e) {
//                 throw new RuntimeException(e);
//             }
//         }
//         return false;
//     }
// }
// 
// Path: atam4j-domain/src/main/java/me/atam/atam4jdomain/TestsRunResult.java
// public final class TestsRunResult {
// 
//     private final Collection<IndividualTestResult> tests;
//     private final Status status;
// 
//     public TestsRunResult(final @JsonProperty("tests")  Collection<IndividualTestResult> tests,
//                           final @JsonProperty("status") Status status) {
//         this.tests = tests;
//         this.status = status;
// 
//     }
// 
//     public TestsRunResult(final Collection<IndividualTestResult> tests) {
//         this.tests = tests;
//         this.status = buildStatus(tests);
//     }
// 
//     public Collection<IndividualTestResult> getTests() {
//         return tests;
//     }
// 
// 
// 
// 
//     public Status getStatus() {
//         return status;
//     }
// 
//     private Status buildStatus(final Collection<IndividualTestResult> testResults) {
//         if (testResults.isEmpty()) {
//             return Status.CATEGORY_NOT_FOUND;
//         }
//         return testResults.stream()
//                           .filter(testReport -> !testReport.isPassed())
//                           .findAny()
//                           .map(failures -> Status.FAILURES)
//                           .orElse(Status.ALL_OK);
//     }
// 
//     public Optional<IndividualTestResult> getTestByClassAndName(String className, String testName) {
//         return tests.stream().filter(t -> t.getTestClass().equals(className)).filter(t -> t.getTestName().equals(testName)).findFirst();
//     }
// 
//     public enum Status {
//         TOO_EARLY("Too early to tell - tests not complete yet"),
//         CATEGORY_NOT_FOUND("This category does not exist"),
//         ALL_OK("All is A OK!"),
//         FAILURES("Failures");
// 
//         private final String message;
// 
//         Status(String message) {
//             this.message = message;
//         }
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
// 
//         TestsRunResult that = (TestsRunResult) o;
// 
//         if (tests != null ? !tests.equals(that.tests) : that.tests != null) return false;
//         return status == that.status;
// 
//     }
// 
//     @Override
//     public int hashCode() {
//         int result = tests != null ? tests.hashCode() : 0;
//         result = 31 * result + (status != null ? status.hashCode() : 0);
//         return result;
//     }
// 
//     @Override
//     public String toString() {
//         return "TestsRunResult{" +
//                 "tests=" + tests +
//                 ", status=" + status +
//                 '}';
//     }
// }
// 
// Path: acceptance-tests/src/main/java/me/atam/atam4jsampleapp/ApplicationConfiguration.java
// public class ApplicationConfiguration extends Configuration {
// 
//     @JsonProperty
//     private int initialDelayInMillis;
// 
//     @JsonProperty
//     private Class[] testClasses;
//     private long periodInMillis;
// 
//     public Class[] getTestClasses(){
//         return testClasses;
//     }
// 
//     public int getInitialDelayInMillis() {
//         return initialDelayInMillis;
//     }
// 
//     public long getPeriodInMillis() {
//         return periodInMillis;
//     }
// }
// 
// Path: acceptance-tests/src/test/java/me/atam/atam4jsampleapp/testsupport/AcceptanceTestTimeouts.java
// public static final int MAX_ATTEMPTS = 2000;
// 
// Path: acceptance-tests/src/test/java/me/atam/atam4jsampleapp/testsupport/AcceptanceTestTimeouts.java
// public static final int RETRY_POLL_INTERVAL = 1;


// Path: acceptance-tests/src/test/java/me/atam/atam4jsampleapp/testsupport/AcceptanceTest.java
import io.dropwizard.testing.DropwizardTestSupport;
import me.atam.atam4j.PollingPredicate;
import me.atam.atam4jdomain.TestsRunResult;
import me.atam.atam4jsampleapp.ApplicationConfiguration;
import org.glassfish.jersey.client.JerseyClientBuilder;
import org.junit.After;
import javax.ws.rs.core.Response;
import static me.atam.atam4jsampleapp.testsupport.AcceptanceTestTimeouts.MAX_ATTEMPTS;
import static me.atam.atam4jsampleapp.testsupport.AcceptanceTestTimeouts.RETRY_POLL_INTERVAL;
import static org.junit.Assert.assertTrue;

package me.atam.atam4jsampleapp.testsupport;




public abstract class AcceptanceTest {

    protected DropwizardTestSupport<ApplicationConfiguration> dropwizardTestSupportAppConfig;

    @After
    public void stopApplication() {
        dropwizardTestSupportAppConfig.after();
    }

    public Response getTestRunResultFromServer(String testsURI){
        return new JerseyClientBuilder().build().target(
                testsURI)
                .request()
                .get();
    }

    public String getTestsURI() {
        return String.format("http://localhost:%d/tests", dropwizardTestSupportAppConfig.getLocalPort());
    }

    public Response getResponseFromTestsWithCategoryOnceTestRunHasCompleted(String category) {
        waitUntilTestRunHasCompleted();
        return getTestRunResultFromServer(getTestsURI() + "/" + category);
    }

    public Response getResponseFromTestsEndpointOnceTestsRunHasCompleted() {