diff --git a/pom.xml b/pom.xml index ca42b464..69f7755a 100644 --- a/pom.xml +++ b/pom.xml @@ -1,4 +1,5 @@ - + 4.0.0 com.commafeed @@ -47,6 +48,19 @@ maven-surefire-plugin 2.22.2 + + org.apache.maven.plugins + maven-failsafe-plugin + 2.22.2 + + + + integration-test + verify + + + + pl.project13.maven git-commit-id-plugin @@ -525,5 +539,15 @@ 5.13.2 test + + io.dropwizard + dropwizard-testing + test + + + org.awaitility + awaitility + test + \ No newline at end of file diff --git a/src/test/java/com/commafeed/integration/FeedIT.java b/src/test/java/com/commafeed/integration/FeedIT.java new file mode 100644 index 00000000..da232124 --- /dev/null +++ b/src/test/java/com/commafeed/integration/FeedIT.java @@ -0,0 +1,100 @@ +package com.commafeed.integration; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.time.Duration; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.Response; + +import org.apache.commons.io.IOUtils; +import org.awaitility.Awaitility; +import org.eclipse.jetty.http.HttpStatus; +import org.glassfish.jersey.client.JerseyClientBuilder; +import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockserver.client.MockServerClient; +import org.mockserver.junit.jupiter.MockServerExtension; +import org.mockserver.model.HttpRequest; +import org.mockserver.model.HttpResponse; + +import com.commafeed.CommaFeedApplication; +import com.commafeed.CommaFeedConfiguration; +import com.commafeed.frontend.model.Category; +import com.commafeed.frontend.model.Entries; +import com.commafeed.frontend.model.Subscription; +import com.commafeed.frontend.model.request.SubscribeRequest; + +import io.dropwizard.testing.ResourceHelpers; +import io.dropwizard.testing.junit5.DropwizardAppExtension; +import io.dropwizard.testing.junit5.DropwizardExtensionsSupport; + +@ExtendWith(DropwizardExtensionsSupport.class) +@ExtendWith(MockServerExtension.class) +class FeedIT { + + private static final DropwizardAppExtension EXT = new DropwizardAppExtension( + CommaFeedApplication.class, ResourceHelpers.resourceFilePath("config.test.yml")) { + @Override + protected JerseyClientBuilder clientBuilder() { + HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic("admin", "admin"); + return super.clientBuilder().register(feature); + } + }; + + private MockServerClient mockServerClient; + + @BeforeEach + void init(MockServerClient mockServerClient) throws IOException { + this.mockServerClient = mockServerClient; + this.mockServerClient.when(HttpRequest.request().withMethod("GET")) + .respond(HttpResponse.response() + .withBody(IOUtils.toString(getClass().getResource("/feed/rss.xml"), StandardCharsets.UTF_8))); + } + + @Test + void test() { + Client client = EXT.client(); + + String feedUrl = "http://localhost:" + this.mockServerClient.getPort(); + + subscribe(client, feedUrl); + Subscription subscription = getSubscription(client, feedUrl); + Awaitility.await() + .atMost(Duration.ofSeconds(15)) + .pollInterval(Duration.ofMillis(500)) + .until(() -> getFeedEntries(client, subscription), e -> e.getEntries().size() == 2); + } + + private void subscribe(Client client, String feedUrl) { + SubscribeRequest subscribeRequest = new SubscribeRequest(); + subscribeRequest.setUrl(feedUrl); + subscribeRequest.setTitle("my title for this feed"); + Response response = client.target(String.format("http://localhost:%d/rest/feed/subscribe", EXT.getLocalPort())) + .request() + .post(Entity.json(subscribeRequest)); + Assertions.assertEquals(HttpStatus.OK_200, response.getStatus()); + } + + private Subscription getSubscription(Client client, String feedUrl) { + Response response = client.target(String.format("http://localhost:%d/rest/category/get", EXT.getLocalPort())).request().get(); + Category category = response.readEntity(Category.class); + Subscription subscription = category.getFeeds().stream().findFirst().orElse(null); + Assertions.assertNotNull(subscription); + return subscription; + } + + private Entries getFeedEntries(Client client, Subscription subscription) { + Response response = client.target(String.format("http://localhost:%d/rest/feed/entries", EXT.getLocalPort())) + .queryParam("id", subscription.getId()) + .queryParam("readType", "unread") + .request() + .get(); + return response.readEntity(Entries.class); + } + +} diff --git a/src/test/resources/config.test.yml b/src/test/resources/config.test.yml new file mode 100644 index 00000000..e8f26d23 --- /dev/null +++ b/src/test/resources/config.test.yml @@ -0,0 +1,106 @@ +# CommaFeed settings +# ------------------ +app: + # url used to access commafeed + publicUrl: http://localhost:8082/ + + # wether to allow user registrations + allowRegistrations: true + + # create a demo account the first time the app starts + createDemoAccount: false + + # put your google analytics tracking code here + googleAnalyticsTrackingCode: + + # put your google server key (used for youtube favicon fetching) + googleAuthKey: + + # number of http threads + backgroundThreads: 3 + + # number of database updating threads + databaseUpdateThreads: 1 + + # settings for sending emails (password recovery) + smtpHost: localhost + smtpPort: 25 + smtpTls: false + smtpUserName: user + smtpPassword: pass + + # Graphite Metric settings + # Allows those who use Graphite to have CommaFeed send metrics for graphing (time in seconds) + graphiteEnabled: false + graphitePrefix: "test.commafeed" + graphiteHost: "localhost" + graphitePort: 2003 + graphiteInterval: 60 + + # wether this commafeed instance has a lot of feeds to refresh + # leave this to false in almost all cases + heavyLoad: false + + # minimum amount of time commafeed will wait before refreshing the same feed + refreshIntervalMinutes: 5 + + # wether to enable pubsub + # probably not needed if refreshIntervalMinutes is low + pubsubhubbub: false + + # if enabled, images in feed entries will be proxied through the server instead of accessed directly by the browser + # useful if commafeed is usually accessed through a restricting proxy + imageProxyEnabled: false + + # database query timeout (in milliseconds), 0 to disable + queryTimeout: 0 + + # time to keep unread statuses (in days), 0 to disable + keepStatusDays: 0 + + # entries to keep per feed, old entries will be deleted, 0 to disable + maxFeedCapacity: 500 + + # cache service to use, possible values are 'noop' and 'redis' + cache: noop + + # announcement string displayed on the main page + announcement: + + # user-agent string that will be used by the http client, leave empty for the default one + userAgent: + +# Database connection +# ------------------- +# for MySQL +# driverClass is com.mysql.jdbc.Driver +# url is jdbc:mysql://localhost/commafeed?autoReconnect=true&failOverReadOnly=false&maxReconnects=20&rewriteBatchedStatements=true +# +# for PostgreSQL +# driverClass is org.postgresql.Driver +# url is jdbc:postgresql://localhost:5432/commafeed +# +# for Microsoft SQL Server +# driverClass is net.sourceforge.jtds.jdbc.Driver +# url is jdbc:jtds:sqlserver://localhost:1433/commafeed;instance= + +database: + driverClass: org.h2.Driver + url: jdbc:h2:mem:commafeed + user: sa + password: sa + properties: + charSet: UTF-8 + validationQuery: "/* CommaFeed Health Check */ SELECT 1" + + +logging: + level: INFO + loggers: + com.commafeed: DEBUG + liquibase: INFO + org.hibernate.SQL: INFO # or ALL for sql debugging + org.hibernate.engine.internal.StatisticalLoggingSessionEventListener: WARN + appenders: + - type: console + \ No newline at end of file diff --git a/src/test/resources/feed/rss.xml b/src/test/resources/feed/rss.xml new file mode 100644 index 00000000..0c3919c9 --- /dev/null +++ b/src/test/resources/feed/rss.xml @@ -0,0 +1,18 @@ + + + + CommaFeed test feed + https://www.commafeed.com + CommaFeed test feed description + + Item 1 + https://www.commafeed.com/1 + Item 1 description + + + Item 2 + https://www.commafeed.com/2 + Item 2 description + + + \ No newline at end of file