mirror of
https://github.com/Athou/commafeed.git
synced 2026-11-02 02:14:47 +00:00
use google java formatter to avoid downloading eclipse during build
This commit is contained in:
@@ -1,5 +1,19 @@
|
||||
package com.commafeed.integration;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.Category;
|
||||
import com.commafeed.frontend.model.Entries;
|
||||
import com.commafeed.frontend.model.Subscription;
|
||||
import com.commafeed.frontend.model.request.AddCategoryRequest;
|
||||
import com.commafeed.frontend.model.request.InitialSetupRequest;
|
||||
import com.commafeed.frontend.model.request.SubscribeRequest;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.config.ObjectMapperConfig;
|
||||
import io.restassured.http.ContentType;
|
||||
import io.restassured.http.Header;
|
||||
import io.restassured.mapper.ObjectMapperType;
|
||||
import jakarta.ws.rs.client.Client;
|
||||
import jakarta.ws.rs.core.HttpHeaders;
|
||||
import java.io.IOException;
|
||||
import java.net.HttpCookie;
|
||||
import java.net.URL;
|
||||
@@ -7,10 +21,7 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import jakarta.ws.rs.client.Client;
|
||||
import jakarta.ws.rs.core.HttpHeaders;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.awaitility.Awaitility;
|
||||
@@ -21,192 +32,212 @@ import org.mockserver.integration.ClientAndServer;
|
||||
import org.mockserver.model.HttpRequest;
|
||||
import org.mockserver.model.HttpResponse;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.Category;
|
||||
import com.commafeed.frontend.model.Entries;
|
||||
import com.commafeed.frontend.model.Subscription;
|
||||
import com.commafeed.frontend.model.request.AddCategoryRequest;
|
||||
import com.commafeed.frontend.model.request.InitialSetupRequest;
|
||||
import com.commafeed.frontend.model.request.SubscribeRequest;
|
||||
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.config.ObjectMapperConfig;
|
||||
import io.restassured.http.ContentType;
|
||||
import io.restassured.http.Header;
|
||||
import io.restassured.mapper.ObjectMapperType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public abstract class BaseIT {
|
||||
|
||||
private static final HttpRequest FEED_REQUEST = HttpRequest.request().withMethod("GET").withPath("/");
|
||||
private static final HttpRequest FEED_REQUEST =
|
||||
HttpRequest.request().withMethod("GET").withPath("/");
|
||||
|
||||
@Getter
|
||||
private MockServerClient mockServerClient;
|
||||
private Client client;
|
||||
private String feedUrl;
|
||||
private String baseUrl;
|
||||
private String apiBaseUrl;
|
||||
private String webSocketUrl;
|
||||
@Getter private MockServerClient mockServerClient;
|
||||
private Client client;
|
||||
private String feedUrl;
|
||||
private String baseUrl;
|
||||
private String apiBaseUrl;
|
||||
private String webSocketUrl;
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() throws IOException {
|
||||
this.mockServerClient = ClientAndServer.startClientAndServer(0);
|
||||
@BeforeEach
|
||||
void beforeEach() throws IOException {
|
||||
this.mockServerClient = ClientAndServer.startClientAndServer(0);
|
||||
|
||||
this.feedUrl = "http://localhost:" + mockServerClient.getPort() + "/";
|
||||
this.baseUrl = "http://localhost:8085/";
|
||||
this.apiBaseUrl = this.baseUrl + "rest/";
|
||||
this.webSocketUrl = "ws://localhost:8085/ws";
|
||||
this.feedUrl = "http://localhost:" + mockServerClient.getPort() + "/";
|
||||
this.baseUrl = "http://localhost:8085/";
|
||||
this.apiBaseUrl = this.baseUrl + "rest/";
|
||||
this.webSocketUrl = "ws://localhost:8085/ws";
|
||||
|
||||
URL resource = Objects.requireNonNull(getClass().getResource("/feed/rss.xml"));
|
||||
this.mockServerClient.when(FEED_REQUEST)
|
||||
.respond(HttpResponse.response().withBody(IOUtils.toString(resource, StandardCharsets.UTF_8)));
|
||||
URL resource = Objects.requireNonNull(getClass().getResource("/feed/rss.xml"));
|
||||
this.mockServerClient
|
||||
.when(FEED_REQUEST)
|
||||
.respond(
|
||||
HttpResponse.response()
|
||||
.withBody(IOUtils.toString(resource, StandardCharsets.UTF_8)));
|
||||
|
||||
// remove when Quarkus supports Jackson 3
|
||||
RestAssured.config = RestAssured.config().objectMapperConfig(new ObjectMapperConfig(ObjectMapperType.JACKSON_2));
|
||||
}
|
||||
// remove when Quarkus supports Jackson 3
|
||||
RestAssured.config =
|
||||
RestAssured.config()
|
||||
.objectMapperConfig(new ObjectMapperConfig(ObjectMapperType.JACKSON_2));
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void afterEach() {
|
||||
if (this.mockServerClient != null) {
|
||||
this.mockServerClient.close();
|
||||
}
|
||||
@AfterEach
|
||||
void afterEach() {
|
||||
if (this.mockServerClient != null) {
|
||||
this.mockServerClient.close();
|
||||
}
|
||||
|
||||
if (this.client != null) {
|
||||
this.client.close();
|
||||
}
|
||||
}
|
||||
if (this.client != null) {
|
||||
this.client.close();
|
||||
}
|
||||
}
|
||||
|
||||
protected void feedNowReturnsMoreEntries() throws IOException {
|
||||
mockServerClient.clear(FEED_REQUEST);
|
||||
protected void feedNowReturnsMoreEntries() throws IOException {
|
||||
mockServerClient.clear(FEED_REQUEST);
|
||||
|
||||
URL resource = Objects.requireNonNull(getClass().getResource("/feed/rss_2.xml"));
|
||||
mockServerClient.when(FEED_REQUEST).respond(HttpResponse.response().withBody(IOUtils.toString(resource, StandardCharsets.UTF_8)));
|
||||
}
|
||||
URL resource = Objects.requireNonNull(getClass().getResource("/feed/rss_2.xml"));
|
||||
mockServerClient
|
||||
.when(FEED_REQUEST)
|
||||
.respond(
|
||||
HttpResponse.response()
|
||||
.withBody(IOUtils.toString(resource, StandardCharsets.UTF_8)));
|
||||
}
|
||||
|
||||
protected void initialSetup(String userName, String password) {
|
||||
InitialSetupRequest req = new InitialSetupRequest();
|
||||
req.setName(userName);
|
||||
req.setPassword(password);
|
||||
req.setEmail(userName + "@commafeed.com");
|
||||
protected void initialSetup(String userName, String password) {
|
||||
InitialSetupRequest req = new InitialSetupRequest();
|
||||
req.setName(userName);
|
||||
req.setPassword(password);
|
||||
req.setEmail(userName + "@commafeed.com");
|
||||
|
||||
RestAssured.given().body(req).contentType(ContentType.JSON).post("rest/user/initialSetup").then().statusCode(200);
|
||||
}
|
||||
RestAssured.given()
|
||||
.body(req)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/user/initialSetup")
|
||||
.then()
|
||||
.statusCode(200);
|
||||
}
|
||||
|
||||
protected List<HttpCookie> login() {
|
||||
List<Header> setCookieHeaders = RestAssured.given()
|
||||
.auth()
|
||||
.none()
|
||||
.formParams("j_username", TestConstants.ADMIN_USERNAME, "j_password", TestConstants.ADMIN_PASSWORD)
|
||||
.post("j_security_check")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.headers()
|
||||
.getList(HttpHeaders.SET_COOKIE);
|
||||
return setCookieHeaders.stream().flatMap(h -> HttpCookie.parse(h.getValue()).stream()).toList();
|
||||
}
|
||||
protected List<HttpCookie> login() {
|
||||
List<Header> setCookieHeaders =
|
||||
RestAssured.given()
|
||||
.auth()
|
||||
.none()
|
||||
.formParams(
|
||||
"j_username",
|
||||
TestConstants.ADMIN_USERNAME,
|
||||
"j_password",
|
||||
TestConstants.ADMIN_PASSWORD)
|
||||
.post("j_security_check")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.headers()
|
||||
.getList(HttpHeaders.SET_COOKIE);
|
||||
return setCookieHeaders.stream()
|
||||
.flatMap(h -> HttpCookie.parse(h.getValue()).stream())
|
||||
.toList();
|
||||
}
|
||||
|
||||
protected String createCategory(String name) {
|
||||
AddCategoryRequest addCategoryRequest = new AddCategoryRequest();
|
||||
addCategoryRequest.setName(name);
|
||||
return RestAssured.given()
|
||||
.body(addCategoryRequest)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/category/add")
|
||||
.then()
|
||||
.extract()
|
||||
.as(String.class);
|
||||
}
|
||||
protected String createCategory(String name) {
|
||||
AddCategoryRequest addCategoryRequest = new AddCategoryRequest();
|
||||
addCategoryRequest.setName(name);
|
||||
return RestAssured.given()
|
||||
.body(addCategoryRequest)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/category/add")
|
||||
.then()
|
||||
.extract()
|
||||
.as(String.class);
|
||||
}
|
||||
|
||||
protected Category getRootCategory() {
|
||||
return RestAssured.given().get("rest/category/get").then().statusCode(HttpStatus.SC_OK).extract().as(Category.class);
|
||||
}
|
||||
protected Category getRootCategory() {
|
||||
return RestAssured.given()
|
||||
.get("rest/category/get")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(Category.class);
|
||||
}
|
||||
|
||||
protected Long subscribe(String feedUrl) {
|
||||
return subscribe(feedUrl, null);
|
||||
}
|
||||
protected Long subscribe(String feedUrl) {
|
||||
return subscribe(feedUrl, null);
|
||||
}
|
||||
|
||||
protected Long subscribe(String feedUrl, String categoryId) {
|
||||
SubscribeRequest subscribeRequest = new SubscribeRequest();
|
||||
subscribeRequest.setUrl(feedUrl);
|
||||
subscribeRequest.setTitle("my title for this feed");
|
||||
subscribeRequest.setCategoryId(categoryId);
|
||||
return RestAssured.given()
|
||||
.body(subscribeRequest)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/feed/subscribe")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(Long.class);
|
||||
}
|
||||
protected Long subscribe(String feedUrl, String categoryId) {
|
||||
SubscribeRequest subscribeRequest = new SubscribeRequest();
|
||||
subscribeRequest.setUrl(feedUrl);
|
||||
subscribeRequest.setTitle("my title for this feed");
|
||||
subscribeRequest.setCategoryId(categoryId);
|
||||
return RestAssured.given()
|
||||
.body(subscribeRequest)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/feed/subscribe")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(Long.class);
|
||||
}
|
||||
|
||||
protected Long subscribeAndWaitForEntries(String feedUrl) {
|
||||
return subscribeAndWaitForEntries(feedUrl, null);
|
||||
}
|
||||
protected Long subscribeAndWaitForEntries(String feedUrl) {
|
||||
return subscribeAndWaitForEntries(feedUrl, null);
|
||||
}
|
||||
|
||||
protected Long subscribeAndWaitForEntries(String feedUrl, String categoryId) {
|
||||
Long subscriptionId = subscribe(feedUrl, categoryId);
|
||||
Awaitility.await().atMost(Duration.ofSeconds(15)).until(() -> getFeedEntries(subscriptionId), e -> e.getEntries().size() == 2);
|
||||
return subscriptionId;
|
||||
}
|
||||
protected Long subscribeAndWaitForEntries(String feedUrl, String categoryId) {
|
||||
Long subscriptionId = subscribe(feedUrl, categoryId);
|
||||
Awaitility.await()
|
||||
.atMost(Duration.ofSeconds(15))
|
||||
.until(() -> getFeedEntries(subscriptionId), e -> e.getEntries().size() == 2);
|
||||
return subscriptionId;
|
||||
}
|
||||
|
||||
protected Subscription getSubscription(Long subscriptionId) {
|
||||
return RestAssured.given()
|
||||
.get("rest/feed/get/{id}", subscriptionId)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(Subscription.class);
|
||||
}
|
||||
protected Subscription getSubscription(Long subscriptionId) {
|
||||
return RestAssured.given()
|
||||
.get("rest/feed/get/{id}", subscriptionId)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(Subscription.class);
|
||||
}
|
||||
|
||||
protected Entries getFeedEntries(long subscriptionId) {
|
||||
return RestAssured.given()
|
||||
.get("rest/feed/entries?id={id}&readType=all", subscriptionId)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(Entries.class);
|
||||
}
|
||||
protected Entries getFeedEntries(long subscriptionId) {
|
||||
return RestAssured.given()
|
||||
.get("rest/feed/entries?id={id}&readType=all", subscriptionId)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(Entries.class);
|
||||
}
|
||||
|
||||
protected Entries getCategoryEntries(String categoryId) {
|
||||
return RestAssured.given()
|
||||
.get("rest/category/entries?id={id}&readType=all", categoryId)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(Entries.class);
|
||||
}
|
||||
protected Entries getCategoryEntries(String categoryId) {
|
||||
return RestAssured.given()
|
||||
.get("rest/category/entries?id={id}&readType=all", categoryId)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(Entries.class);
|
||||
}
|
||||
|
||||
protected Entries getCategoryEntries(String categoryId, int offset, int limit) {
|
||||
return RestAssured.given()
|
||||
.get("rest/category/entries?id={id}&readType=all&offset={offset}&limit={limit}", categoryId, offset, limit)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(Entries.class);
|
||||
}
|
||||
protected Entries getCategoryEntries(String categoryId, int offset, int limit) {
|
||||
return RestAssured.given()
|
||||
.get(
|
||||
"rest/category/entries?id={id}&readType=all&offset={offset}&limit={limit}",
|
||||
categoryId,
|
||||
offset,
|
||||
limit)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(Entries.class);
|
||||
}
|
||||
|
||||
protected Entries getCategoryEntries(String categoryId, String keywords) {
|
||||
return RestAssured.given()
|
||||
.get("rest/category/entries?id={id}&readType=all&keywords={keywords}", categoryId, keywords)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(Entries.class);
|
||||
}
|
||||
protected Entries getCategoryEntries(String categoryId, String keywords) {
|
||||
return RestAssured.given()
|
||||
.get(
|
||||
"rest/category/entries?id={id}&readType=all&keywords={keywords}",
|
||||
categoryId,
|
||||
keywords)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(Entries.class);
|
||||
}
|
||||
|
||||
protected Entries getTaggedEntries(String tag) {
|
||||
return RestAssured.given()
|
||||
.get("rest/category/entries?id=all&readType=all&tag={tag}", tag)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(Entries.class);
|
||||
}
|
||||
protected Entries getTaggedEntries(String tag) {
|
||||
return RestAssured.given()
|
||||
.get("rest/category/entries?id=all&readType=all&tag={tag}", tag)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(Entries.class);
|
||||
}
|
||||
|
||||
protected int forceRefreshAllFeeds() {
|
||||
return RestAssured.given().get("rest/feed/refreshAll").then().extract().statusCode();
|
||||
}
|
||||
protected int forceRefreshAllFeeds() {
|
||||
return RestAssured.given().get("rest/feed/refreshAll").then().extract().statusCode();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
package com.commafeed.integration;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import com.google.common.net.HttpHeaders;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
@QuarkusTest
|
||||
class CompressionIT {
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "/rest/server/get", "/" })
|
||||
void servedWithCompression(String path) {
|
||||
RestAssured.given().when().get(path).then().statusCode(200).header(HttpHeaders.CONTENT_ENCODING, "gzip");
|
||||
}
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"/rest/server/get", "/"})
|
||||
void servedWithCompression(String path) {
|
||||
RestAssured.given()
|
||||
.when()
|
||||
.get(path)
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.header(HttpHeaders.CONTENT_ENCODING, "gzip");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
package com.commafeed.integration;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.backend.model.UserSettings.PushNotificationType;
|
||||
import com.commafeed.frontend.model.Settings;
|
||||
import com.commafeed.frontend.model.Subscription;
|
||||
import com.commafeed.frontend.model.request.FeedModificationRequest;
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.awaitility.Awaitility;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
@@ -12,64 +19,69 @@ import org.mockserver.model.HttpRequest;
|
||||
import org.mockserver.model.HttpResponse;
|
||||
import org.mockserver.verify.VerificationTimes;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.backend.model.UserSettings.PushNotificationType;
|
||||
import com.commafeed.frontend.model.Settings;
|
||||
import com.commafeed.frontend.model.Subscription;
|
||||
import com.commafeed.frontend.model.request.FeedModificationRequest;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
|
||||
@QuarkusTest
|
||||
class PushNotificationIT extends BaseIT {
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication = RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication =
|
||||
RestAssured.preemptive()
|
||||
.basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
RestAssured.reset();
|
||||
}
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
RestAssured.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
void receivedPushNotifications() throws IOException {
|
||||
// mock ntfy server
|
||||
HttpRequest ntfyPost = HttpRequest.request().withMethod("POST").withPath("/ntfy/integration-test");
|
||||
getMockServerClient().when(ntfyPost).respond(HttpResponse.response().withStatusCode(200));
|
||||
@Test
|
||||
void receivedPushNotifications() throws IOException {
|
||||
// mock ntfy server
|
||||
HttpRequest ntfyPost =
|
||||
HttpRequest.request().withMethod("POST").withPath("/ntfy/integration-test");
|
||||
getMockServerClient().when(ntfyPost).respond(HttpResponse.response().withStatusCode(200));
|
||||
|
||||
// enable push notifications
|
||||
Settings settings = RestAssured.given().get("rest/user/settings").then().extract().as(Settings.class);
|
||||
settings.getPushNotificationSettings().setType(PushNotificationType.NTFY);
|
||||
settings.getPushNotificationSettings().setServerUrl("http://localhost:" + getMockServerClient().getPort() + "/ntfy");
|
||||
settings.getPushNotificationSettings().setTopic("integration-test");
|
||||
RestAssured.given().body(settings).contentType(ContentType.JSON).post("rest/user/settings").then().statusCode(200);
|
||||
// enable push notifications
|
||||
Settings settings =
|
||||
RestAssured.given().get("rest/user/settings").then().extract().as(Settings.class);
|
||||
settings.getPushNotificationSettings().setType(PushNotificationType.NTFY);
|
||||
settings.getPushNotificationSettings()
|
||||
.setServerUrl("http://localhost:" + getMockServerClient().getPort() + "/ntfy");
|
||||
settings.getPushNotificationSettings().setTopic("integration-test");
|
||||
RestAssured.given()
|
||||
.body(settings)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/user/settings")
|
||||
.then()
|
||||
.statusCode(200);
|
||||
|
||||
// subscribe
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
Subscription subscription = getSubscription(subscriptionId);
|
||||
// subscribe
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
Subscription subscription = getSubscription(subscriptionId);
|
||||
|
||||
// enable push notifications
|
||||
FeedModificationRequest req = new FeedModificationRequest();
|
||||
req.setId(subscriptionId);
|
||||
req.setName(subscription.getName());
|
||||
req.setCategoryId(subscription.getCategoryId());
|
||||
req.setPosition(1);
|
||||
req.setPushNotificationsEnabled(true);
|
||||
RestAssured.given().body(req).contentType(ContentType.JSON).post("rest/feed/modify").then().statusCode(HttpStatus.SC_OK);
|
||||
// enable push notifications
|
||||
FeedModificationRequest req = new FeedModificationRequest();
|
||||
req.setId(subscriptionId);
|
||||
req.setName(subscription.getName());
|
||||
req.setCategoryId(subscription.getCategoryId());
|
||||
req.setPosition(1);
|
||||
req.setPushNotificationsEnabled(true);
|
||||
RestAssured.given()
|
||||
.body(req)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/feed/modify")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
|
||||
// receive two additional entries, those will trigger two push notifications
|
||||
feedNowReturnsMoreEntries();
|
||||
forceRefreshAllFeeds();
|
||||
|
||||
// await push notification for the two entries in the feed
|
||||
Awaitility.await()
|
||||
.atMost(Duration.ofSeconds(20))
|
||||
.untilAsserted(() -> getMockServerClient().verify(ntfyPost, VerificationTimes.exactly(2)));
|
||||
}
|
||||
// receive two additional entries, those will trigger two push notifications
|
||||
feedNowReturnsMoreEntries();
|
||||
forceRefreshAllFeeds();
|
||||
|
||||
// await push notification for the two entries in the feed
|
||||
Awaitility.await()
|
||||
.atMost(Duration.ofSeconds(20))
|
||||
.untilAsserted(
|
||||
() -> getMockServerClient().verify(ntfyPost, VerificationTimes.exactly(2)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,5 @@
|
||||
package com.commafeed.integration;
|
||||
|
||||
import java.net.HttpCookie;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import jakarta.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.commafeed.ExceptionMappers.UnauthorizedResponse;
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.Entries;
|
||||
@@ -18,135 +7,154 @@ import com.commafeed.frontend.model.UserModel;
|
||||
import com.commafeed.frontend.model.request.MarkRequest;
|
||||
import com.commafeed.frontend.model.request.ProfileModificationRequest;
|
||||
import com.commafeed.frontend.model.request.SubscribeRequest;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
import jakarta.ws.rs.core.HttpHeaders;
|
||||
import java.net.HttpCookie;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@QuarkusTest
|
||||
class SecurityIT extends BaseIT {
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
|
||||
@Test
|
||||
void notLoggedIn() {
|
||||
UnauthorizedResponse info = RestAssured.given()
|
||||
.get("rest/user/profile")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_UNAUTHORIZED)
|
||||
.extract()
|
||||
.as(UnauthorizedResponse.class);
|
||||
Assertions.assertTrue(info.allowRegistrations());
|
||||
}
|
||||
@Test
|
||||
void notLoggedIn() {
|
||||
UnauthorizedResponse info =
|
||||
RestAssured.given()
|
||||
.get("rest/user/profile")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_UNAUTHORIZED)
|
||||
.extract()
|
||||
.as(UnauthorizedResponse.class);
|
||||
Assertions.assertTrue(info.allowRegistrations());
|
||||
}
|
||||
|
||||
@Test
|
||||
void formLogin() {
|
||||
List<HttpCookie> cookies = login();
|
||||
cookies.forEach(c -> Assertions.assertTrue(c.getMaxAge() > 0));
|
||||
@Test
|
||||
void formLogin() {
|
||||
List<HttpCookie> cookies = login();
|
||||
cookies.forEach(c -> Assertions.assertTrue(c.getMaxAge() > 0));
|
||||
|
||||
RestAssured.given()
|
||||
.header(HttpHeaders.COOKIE, cookies.stream().map(HttpCookie::toString).collect(Collectors.joining(";")))
|
||||
.get("rest/user/profile")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
}
|
||||
RestAssured.given()
|
||||
.header(
|
||||
HttpHeaders.COOKIE,
|
||||
cookies.stream().map(HttpCookie::toString).collect(Collectors.joining(";")))
|
||||
.get("rest/user/profile")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void basicAuthLogin() {
|
||||
RestAssured.given()
|
||||
.auth()
|
||||
.preemptive()
|
||||
.basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD)
|
||||
.get("rest/user/profile")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
}
|
||||
@Test
|
||||
void basicAuthLogin() {
|
||||
RestAssured.given()
|
||||
.auth()
|
||||
.preemptive()
|
||||
.basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD)
|
||||
.get("rest/user/profile")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void wrongPassword() {
|
||||
RestAssured.given()
|
||||
.auth()
|
||||
.preemptive()
|
||||
.basic(TestConstants.ADMIN_USERNAME, "wrong-password")
|
||||
.get("rest/user/profile")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_UNAUTHORIZED);
|
||||
}
|
||||
@Test
|
||||
void wrongPassword() {
|
||||
RestAssured.given()
|
||||
.auth()
|
||||
.preemptive()
|
||||
.basic(TestConstants.ADMIN_USERNAME, "wrong-password")
|
||||
.get("rest/user/profile")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test
|
||||
void missingRole() {
|
||||
RestAssured.given().auth().preemptive().basic("demo", "demo").get("rest/admin/metrics").then().statusCode(HttpStatus.SC_FORBIDDEN);
|
||||
}
|
||||
@Test
|
||||
void missingRole() {
|
||||
RestAssured.given()
|
||||
.auth()
|
||||
.preemptive()
|
||||
.basic("demo", "demo")
|
||||
.get("rest/admin/metrics")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void apiKey() {
|
||||
// create api key
|
||||
ProfileModificationRequest req = new ProfileModificationRequest();
|
||||
req.setCurrentPassword(TestConstants.ADMIN_PASSWORD);
|
||||
req.setNewApiKey(true);
|
||||
RestAssured.given()
|
||||
.auth()
|
||||
.preemptive()
|
||||
.basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD)
|
||||
.body(req)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/user/profile")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
@Test
|
||||
void apiKey() {
|
||||
// create api key
|
||||
ProfileModificationRequest req = new ProfileModificationRequest();
|
||||
req.setCurrentPassword(TestConstants.ADMIN_PASSWORD);
|
||||
req.setNewApiKey(true);
|
||||
RestAssured.given()
|
||||
.auth()
|
||||
.preemptive()
|
||||
.basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD)
|
||||
.body(req)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/user/profile")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
|
||||
// fetch api key
|
||||
String apiKey = RestAssured.given()
|
||||
.auth()
|
||||
.preemptive()
|
||||
.basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD)
|
||||
.get("rest/user/profile")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(UserModel.class)
|
||||
.getApiKey();
|
||||
// fetch api key
|
||||
String apiKey =
|
||||
RestAssured.given()
|
||||
.auth()
|
||||
.preemptive()
|
||||
.basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD)
|
||||
.get("rest/user/profile")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(UserModel.class)
|
||||
.getApiKey();
|
||||
|
||||
// subscribe to a feed
|
||||
SubscribeRequest subscribeRequest = new SubscribeRequest();
|
||||
subscribeRequest.setUrl(getFeedUrl());
|
||||
subscribeRequest.setTitle("my title for this feed");
|
||||
long subscriptionId = RestAssured.given()
|
||||
.auth()
|
||||
.preemptive()
|
||||
.basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD)
|
||||
.body(subscribeRequest)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/feed/subscribe")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(Long.class);
|
||||
// subscribe to a feed
|
||||
SubscribeRequest subscribeRequest = new SubscribeRequest();
|
||||
subscribeRequest.setUrl(getFeedUrl());
|
||||
subscribeRequest.setTitle("my title for this feed");
|
||||
long subscriptionId =
|
||||
RestAssured.given()
|
||||
.auth()
|
||||
.preemptive()
|
||||
.basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD)
|
||||
.body(subscribeRequest)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/feed/subscribe")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(Long.class);
|
||||
|
||||
// get entries with api key
|
||||
Entries entries = RestAssured.given()
|
||||
.queryParam("id", subscriptionId)
|
||||
.queryParam("readType", "unread")
|
||||
.queryParam("apiKey", apiKey)
|
||||
.get("rest/feed/entries")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(Entries.class);
|
||||
Assertions.assertEquals("my title for this feed", entries.getName());
|
||||
// get entries with api key
|
||||
Entries entries =
|
||||
RestAssured.given()
|
||||
.queryParam("id", subscriptionId)
|
||||
.queryParam("readType", "unread")
|
||||
.queryParam("apiKey", apiKey)
|
||||
.get("rest/feed/entries")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(Entries.class);
|
||||
Assertions.assertEquals("my title for this feed", entries.getName());
|
||||
|
||||
// mark entry as read and expect it won't work because it's not a GET request
|
||||
MarkRequest markRequest = new MarkRequest();
|
||||
markRequest.setId("1");
|
||||
markRequest.setRead(true);
|
||||
RestAssured.given()
|
||||
.body(markRequest)
|
||||
.contentType(ContentType.JSON)
|
||||
.queryParam("apiKey", apiKey)
|
||||
.post("rest/entry/mark")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_UNAUTHORIZED);
|
||||
}
|
||||
// mark entry as read and expect it won't work because it's not a GET request
|
||||
MarkRequest markRequest = new MarkRequest();
|
||||
markRequest.setId("1");
|
||||
markRequest.setRead(true);
|
||||
RestAssured.given()
|
||||
.body(markRequest)
|
||||
.contentType(ContentType.JSON)
|
||||
.queryParam("apiKey", apiKey)
|
||||
.post("rest/entry/mark")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_UNAUTHORIZED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,32 @@
|
||||
package com.commafeed.integration;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
@QuarkusTest
|
||||
class StaticFilesIT {
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "/", "/openapi" })
|
||||
void servedWithoutCache(String path) {
|
||||
RestAssured.given().when().get(path).then().statusCode(200).header("Cache-Control", "no-cache");
|
||||
}
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"/", "/openapi"})
|
||||
void servedWithoutCache(String path) {
|
||||
RestAssured.given()
|
||||
.when()
|
||||
.get(path)
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.header("Cache-Control", "no-cache");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "/favicon.ico" })
|
||||
void servedWithCache(String path) {
|
||||
RestAssured.given().when().get(path).then().statusCode(200).header("Cache-Control", "public, immutable, max-age=31536000");
|
||||
}
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"/favicon.ico"})
|
||||
void servedWithCache(String path) {
|
||||
RestAssured.given()
|
||||
.when()
|
||||
.get(path)
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.header("Cache-Control", "public, immutable, max-age=31536000");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
package com.commafeed.integration;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.request.FeedModificationRequest;
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
import jakarta.websocket.ClientEndpointConfig;
|
||||
import jakarta.websocket.CloseReason;
|
||||
import jakarta.websocket.ContainerProvider;
|
||||
import jakarta.websocket.DeploymentException;
|
||||
import jakarta.websocket.Endpoint;
|
||||
import jakarta.websocket.EndpointConfig;
|
||||
import jakarta.websocket.Session;
|
||||
import jakarta.ws.rs.core.HttpHeaders;
|
||||
import java.io.IOException;
|
||||
import java.net.HttpCookie;
|
||||
import java.net.URI;
|
||||
@@ -10,16 +23,7 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import jakarta.websocket.ClientEndpointConfig;
|
||||
import jakarta.websocket.CloseReason;
|
||||
import jakarta.websocket.ContainerProvider;
|
||||
import jakarta.websocket.DeploymentException;
|
||||
import jakarta.websocket.Endpoint;
|
||||
import jakarta.websocket.EndpointConfig;
|
||||
import jakarta.websocket.Session;
|
||||
import jakarta.ws.rs.core.HttpHeaders;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.awaitility.Awaitility;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
@@ -27,137 +31,163 @@ import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.request.FeedModificationRequest;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@QuarkusTest
|
||||
@Slf4j
|
||||
class WebSocketIT extends BaseIT {
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication = RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication =
|
||||
RestAssured.preemptive()
|
||||
.basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
RestAssured.reset();
|
||||
}
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
RestAssured.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
void sessionClosedIfNotLoggedIn() throws DeploymentException, IOException {
|
||||
AtomicBoolean connected = new AtomicBoolean();
|
||||
AtomicReference<CloseReason> closeReasonRef = new AtomicReference<>();
|
||||
try (Session session = ContainerProvider.getWebSocketContainer().connectToServer(new Endpoint() {
|
||||
@Override
|
||||
public void onOpen(Session session, EndpointConfig config) {
|
||||
connected.set(true);
|
||||
}
|
||||
@Test
|
||||
void sessionClosedIfNotLoggedIn() throws DeploymentException, IOException {
|
||||
AtomicBoolean connected = new AtomicBoolean();
|
||||
AtomicReference<CloseReason> closeReasonRef = new AtomicReference<>();
|
||||
try (Session session =
|
||||
ContainerProvider.getWebSocketContainer()
|
||||
.connectToServer(
|
||||
new Endpoint() {
|
||||
@Override
|
||||
public void onOpen(Session session, EndpointConfig config) {
|
||||
connected.set(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(Session session, CloseReason closeReason) {
|
||||
closeReasonRef.set(closeReason);
|
||||
}
|
||||
}, buildConfig(List.of()), URI.create(getWebSocketUrl()))) {
|
||||
Awaitility.await().atMost(15, TimeUnit.SECONDS).untilTrue(connected);
|
||||
log.info("connected to {}", session.getRequestURI());
|
||||
@Override
|
||||
public void onClose(Session session, CloseReason closeReason) {
|
||||
closeReasonRef.set(closeReason);
|
||||
}
|
||||
},
|
||||
buildConfig(List.of()),
|
||||
URI.create(getWebSocketUrl()))) {
|
||||
Awaitility.await().atMost(15, TimeUnit.SECONDS).untilTrue(connected);
|
||||
log.info("connected to {}", session.getRequestURI());
|
||||
|
||||
Awaitility.await().atMost(15, TimeUnit.SECONDS).until(() -> closeReasonRef.get() != null);
|
||||
}
|
||||
}
|
||||
Awaitility.await()
|
||||
.atMost(15, TimeUnit.SECONDS)
|
||||
.until(() -> closeReasonRef.get() != null);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void subscribeAndGetsNotified() throws DeploymentException, IOException {
|
||||
List<HttpCookie> cookies = login();
|
||||
@Test
|
||||
void subscribeAndGetsNotified() throws DeploymentException, IOException {
|
||||
List<HttpCookie> cookies = login();
|
||||
|
||||
AtomicBoolean connected = new AtomicBoolean();
|
||||
AtomicReference<String> messageRef = new AtomicReference<>();
|
||||
try (Session session = ContainerProvider.getWebSocketContainer().connectToServer(new Endpoint() {
|
||||
@Override
|
||||
public void onOpen(Session session, EndpointConfig config) {
|
||||
session.addMessageHandler(String.class, messageRef::set);
|
||||
connected.set(true);
|
||||
}
|
||||
}, buildConfig(cookies), URI.create(getWebSocketUrl()))) {
|
||||
Awaitility.await().atMost(15, TimeUnit.SECONDS).untilTrue(connected);
|
||||
log.info("connected to {}", session.getRequestURI());
|
||||
AtomicBoolean connected = new AtomicBoolean();
|
||||
AtomicReference<String> messageRef = new AtomicReference<>();
|
||||
try (Session session =
|
||||
ContainerProvider.getWebSocketContainer()
|
||||
.connectToServer(
|
||||
new Endpoint() {
|
||||
@Override
|
||||
public void onOpen(Session session, EndpointConfig config) {
|
||||
session.addMessageHandler(String.class, messageRef::set);
|
||||
connected.set(true);
|
||||
}
|
||||
},
|
||||
buildConfig(cookies),
|
||||
URI.create(getWebSocketUrl()))) {
|
||||
Awaitility.await().atMost(15, TimeUnit.SECONDS).untilTrue(connected);
|
||||
log.info("connected to {}", session.getRequestURI());
|
||||
|
||||
Long subscriptionId = subscribe(getFeedUrl());
|
||||
Long subscriptionId = subscribe(getFeedUrl());
|
||||
|
||||
Awaitility.await().atMost(15, TimeUnit.SECONDS).until(() -> messageRef.get() != null);
|
||||
Assertions.assertEquals("new-feed-entries:" + subscriptionId + ":2", messageRef.get());
|
||||
}
|
||||
}
|
||||
Awaitility.await().atMost(15, TimeUnit.SECONDS).until(() -> messageRef.get() != null);
|
||||
Assertions.assertEquals("new-feed-entries:" + subscriptionId + ":2", messageRef.get());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void notNotifiedForFilteredEntries() throws DeploymentException, IOException {
|
||||
List<HttpCookie> cookies = login();
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
@Test
|
||||
void notNotifiedForFilteredEntries() throws DeploymentException, IOException {
|
||||
List<HttpCookie> cookies = login();
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
|
||||
FeedModificationRequest req = new FeedModificationRequest();
|
||||
req.setId(subscriptionId);
|
||||
req.setName("feed-name");
|
||||
req.setFilter("!titleLower.contains('item 4')");
|
||||
RestAssured.given().body(req).contentType(ContentType.JSON).post("rest/feed/modify").then().statusCode(HttpStatus.SC_OK);
|
||||
FeedModificationRequest req = new FeedModificationRequest();
|
||||
req.setId(subscriptionId);
|
||||
req.setName("feed-name");
|
||||
req.setFilter("!titleLower.contains('item 4')");
|
||||
RestAssured.given()
|
||||
.body(req)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/feed/modify")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
|
||||
AtomicBoolean connected = new AtomicBoolean();
|
||||
AtomicReference<String> messageRef = new AtomicReference<>();
|
||||
try (Session session = ContainerProvider.getWebSocketContainer().connectToServer(new Endpoint() {
|
||||
@Override
|
||||
public void onOpen(Session session, EndpointConfig config) {
|
||||
session.addMessageHandler(String.class, messageRef::set);
|
||||
connected.set(true);
|
||||
}
|
||||
}, buildConfig(cookies), URI.create(getWebSocketUrl()))) {
|
||||
Awaitility.await().atMost(15, TimeUnit.SECONDS).untilTrue(connected);
|
||||
log.info("connected to {}", session.getRequestURI());
|
||||
AtomicBoolean connected = new AtomicBoolean();
|
||||
AtomicReference<String> messageRef = new AtomicReference<>();
|
||||
try (Session session =
|
||||
ContainerProvider.getWebSocketContainer()
|
||||
.connectToServer(
|
||||
new Endpoint() {
|
||||
@Override
|
||||
public void onOpen(Session session, EndpointConfig config) {
|
||||
session.addMessageHandler(String.class, messageRef::set);
|
||||
connected.set(true);
|
||||
}
|
||||
},
|
||||
buildConfig(cookies),
|
||||
URI.create(getWebSocketUrl()))) {
|
||||
Awaitility.await().atMost(15, TimeUnit.SECONDS).untilTrue(connected);
|
||||
log.info("connected to {}", session.getRequestURI());
|
||||
|
||||
feedNowReturnsMoreEntries();
|
||||
forceRefreshAllFeeds();
|
||||
feedNowReturnsMoreEntries();
|
||||
forceRefreshAllFeeds();
|
||||
|
||||
Awaitility.await().atMost(15, TimeUnit.SECONDS).until(() -> messageRef.get() != null);
|
||||
Assertions.assertEquals("new-feed-entries:" + subscriptionId + ":1", messageRef.get());
|
||||
}
|
||||
Awaitility.await().atMost(15, TimeUnit.SECONDS).until(() -> messageRef.get() != null);
|
||||
Assertions.assertEquals("new-feed-entries:" + subscriptionId + ":1", messageRef.get());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@Test
|
||||
void pingPong() throws DeploymentException, IOException {
|
||||
List<HttpCookie> cookies = login();
|
||||
|
||||
@Test
|
||||
void pingPong() throws DeploymentException, IOException {
|
||||
List<HttpCookie> cookies = login();
|
||||
AtomicBoolean connected = new AtomicBoolean();
|
||||
AtomicReference<String> messageRef = new AtomicReference<>();
|
||||
try (Session session =
|
||||
ContainerProvider.getWebSocketContainer()
|
||||
.connectToServer(
|
||||
new Endpoint() {
|
||||
@Override
|
||||
public void onOpen(Session session, EndpointConfig config) {
|
||||
session.addMessageHandler(String.class, messageRef::set);
|
||||
connected.set(true);
|
||||
}
|
||||
},
|
||||
buildConfig(cookies),
|
||||
URI.create(getWebSocketUrl()))) {
|
||||
Awaitility.await().atMost(15, TimeUnit.SECONDS).untilTrue(connected);
|
||||
log.info("connected to {}", session.getRequestURI());
|
||||
|
||||
AtomicBoolean connected = new AtomicBoolean();
|
||||
AtomicReference<String> messageRef = new AtomicReference<>();
|
||||
try (Session session = ContainerProvider.getWebSocketContainer().connectToServer(new Endpoint() {
|
||||
@Override
|
||||
public void onOpen(Session session, EndpointConfig config) {
|
||||
session.addMessageHandler(String.class, messageRef::set);
|
||||
connected.set(true);
|
||||
}
|
||||
}, buildConfig(cookies), URI.create(getWebSocketUrl()))) {
|
||||
Awaitility.await().atMost(15, TimeUnit.SECONDS).untilTrue(connected);
|
||||
log.info("connected to {}", session.getRequestURI());
|
||||
session.getAsyncRemote().sendText("ping");
|
||||
|
||||
session.getAsyncRemote().sendText("ping");
|
||||
|
||||
Awaitility.await().atMost(15, TimeUnit.SECONDS).until(() -> messageRef.get() != null);
|
||||
Assertions.assertEquals("pong", messageRef.get());
|
||||
}
|
||||
}
|
||||
|
||||
private ClientEndpointConfig buildConfig(List<HttpCookie> cookies) {
|
||||
return ClientEndpointConfig.Builder.create().configurator(new ClientEndpointConfig.Configurator() {
|
||||
@Override
|
||||
public void beforeRequest(Map<String, List<String>> headers) {
|
||||
headers.put(HttpHeaders.COOKIE,
|
||||
Collections.singletonList(cookies.stream().map(HttpCookie::toString).collect(Collectors.joining(";"))));
|
||||
}
|
||||
}).build();
|
||||
}
|
||||
Awaitility.await().atMost(15, TimeUnit.SECONDS).until(() -> messageRef.get() != null);
|
||||
Assertions.assertEquals("pong", messageRef.get());
|
||||
}
|
||||
}
|
||||
|
||||
private ClientEndpointConfig buildConfig(List<HttpCookie> cookies) {
|
||||
return ClientEndpointConfig.Builder.create()
|
||||
.configurator(
|
||||
new ClientEndpointConfig.Configurator() {
|
||||
@Override
|
||||
public void beforeRequest(Map<String, List<String>> headers) {
|
||||
headers.put(
|
||||
HttpHeaders.COOKIE,
|
||||
Collections.singletonList(
|
||||
cookies.stream()
|
||||
.map(HttpCookie::toString)
|
||||
.collect(Collectors.joining(";"))));
|
||||
}
|
||||
})
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,5 @@
|
||||
package com.commafeed.integration.cleanup;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.backend.service.db.DatabaseCleaningService;
|
||||
import com.commafeed.frontend.model.Entries;
|
||||
@@ -19,194 +8,229 @@ import com.commafeed.frontend.model.request.FeedModificationRequest;
|
||||
import com.commafeed.frontend.model.request.StarRequest;
|
||||
import com.commafeed.frontend.resource.CategoryREST;
|
||||
import com.commafeed.integration.BaseIT;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
import jakarta.inject.Inject;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@QuarkusTest
|
||||
class DatabaseCleaningIT extends BaseIT {
|
||||
|
||||
@Inject
|
||||
DatabaseCleaningService databaseCleaningService;
|
||||
@Inject DatabaseCleaningService databaseCleaningService;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication = RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication =
|
||||
RestAssured.preemptive()
|
||||
.basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
RestAssured.reset();
|
||||
}
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
RestAssured.reset();
|
||||
}
|
||||
|
||||
private void starEntry(String entryId, Long subscriptionId) {
|
||||
StarRequest starRequest = new StarRequest();
|
||||
starRequest.setId(entryId);
|
||||
starRequest.setFeedId(subscriptionId);
|
||||
starRequest.setStarred(true);
|
||||
RestAssured.given().body(starRequest).contentType(ContentType.JSON).post("rest/entry/star").then().statusCode(200);
|
||||
}
|
||||
private void starEntry(String entryId, Long subscriptionId) {
|
||||
StarRequest starRequest = new StarRequest();
|
||||
starRequest.setId(entryId);
|
||||
starRequest.setFeedId(subscriptionId);
|
||||
starRequest.setStarred(true);
|
||||
RestAssured.given()
|
||||
.body(starRequest)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/entry/star")
|
||||
.then()
|
||||
.statusCode(200);
|
||||
}
|
||||
|
||||
private void unstarEntry(String entryId, Long subscriptionId) {
|
||||
StarRequest starRequest = new StarRequest();
|
||||
starRequest.setId(entryId);
|
||||
starRequest.setFeedId(subscriptionId);
|
||||
starRequest.setStarred(false);
|
||||
RestAssured.given().body(starRequest).contentType(ContentType.JSON).post("rest/entry/star").then().statusCode(200);
|
||||
}
|
||||
private void unstarEntry(String entryId, Long subscriptionId) {
|
||||
StarRequest starRequest = new StarRequest();
|
||||
starRequest.setId(entryId);
|
||||
starRequest.setFeedId(subscriptionId);
|
||||
starRequest.setStarred(false);
|
||||
RestAssured.given()
|
||||
.body(starRequest)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/entry/star")
|
||||
.then()
|
||||
.statusCode(200);
|
||||
}
|
||||
|
||||
@Nested
|
||||
class KeepStarredEntries {
|
||||
@Nested
|
||||
class KeepStarredEntries {
|
||||
|
||||
@Test
|
||||
void starredEntriesAreKeptWhenCleaningFeedsExceedingCapacity() {
|
||||
// Subscribe to feed and wait for entries
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
@Test
|
||||
void starredEntriesAreKeptWhenCleaningFeedsExceedingCapacity() {
|
||||
// Subscribe to feed and wait for entries
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
|
||||
// Verify we have 2 entries
|
||||
Entries entriesBefore = getFeedEntries(subscriptionId);
|
||||
Assertions.assertEquals(2, entriesBefore.getEntries().size());
|
||||
// Verify we have 2 entries
|
||||
Entries entriesBefore = getFeedEntries(subscriptionId);
|
||||
Assertions.assertEquals(2, entriesBefore.getEntries().size());
|
||||
|
||||
// Star the first entry
|
||||
Entry entryToStar = entriesBefore.getEntries().getFirst();
|
||||
starEntry(entryToStar.getId(), subscriptionId);
|
||||
// Star the first entry
|
||||
Entry entryToStar = entriesBefore.getEntries().getFirst();
|
||||
starEntry(entryToStar.getId(), subscriptionId);
|
||||
|
||||
// Verify the entry is starred
|
||||
Entries starredEntries = getCategoryEntries(CategoryREST.STARRED);
|
||||
Assertions.assertEquals(1, starredEntries.getEntries().size());
|
||||
Assertions.assertEquals(entryToStar.getId(), starredEntries.getEntries().getFirst().getId());
|
||||
// Verify the entry is starred
|
||||
Entries starredEntries = getCategoryEntries(CategoryREST.STARRED);
|
||||
Assertions.assertEquals(1, starredEntries.getEntries().size());
|
||||
Assertions.assertEquals(
|
||||
entryToStar.getId(), starredEntries.getEntries().getFirst().getId());
|
||||
|
||||
// Run cleanup with capacity of 0 (should delete all non-starred entries)
|
||||
// With keepStarredEntries=true (default), only non-starred entries are counted for capacity.
|
||||
// We have 2 entries, 1 starred and 1 non-starred. With capacity=0, the 1 non-starred entry exceeds capacity.
|
||||
databaseCleaningService.cleanEntriesForFeedsExceedingCapacity(0);
|
||||
// Run cleanup with capacity of 0 (should delete all non-starred entries)
|
||||
// With keepStarredEntries=true (default), only non-starred entries are counted for
|
||||
// capacity.
|
||||
// We have 2 entries, 1 starred and 1 non-starred. With capacity=0, the 1 non-starred
|
||||
// entry
|
||||
// exceeds capacity.
|
||||
databaseCleaningService.cleanEntriesForFeedsExceedingCapacity(0);
|
||||
|
||||
// Verify starred entry is still present
|
||||
Entries starredEntriesAfter = getCategoryEntries(CategoryREST.STARRED);
|
||||
Assertions.assertEquals(1, starredEntriesAfter.getEntries().size());
|
||||
Assertions.assertEquals(entryToStar.getId(), starredEntriesAfter.getEntries().getFirst().getId());
|
||||
// Verify starred entry is still present
|
||||
Entries starredEntriesAfter = getCategoryEntries(CategoryREST.STARRED);
|
||||
Assertions.assertEquals(1, starredEntriesAfter.getEntries().size());
|
||||
Assertions.assertEquals(
|
||||
entryToStar.getId(), starredEntriesAfter.getEntries().getFirst().getId());
|
||||
|
||||
// Verify the non-starred entry was deleted (only starred entry should remain)
|
||||
Entries entriesAfter = getFeedEntries(subscriptionId);
|
||||
Assertions.assertEquals(1, entriesAfter.getEntries().size());
|
||||
Assertions.assertEquals(entryToStar.getId(), entriesAfter.getEntries().getFirst().getId());
|
||||
}
|
||||
// Verify the non-starred entry was deleted (only starred entry should remain)
|
||||
Entries entriesAfter = getFeedEntries(subscriptionId);
|
||||
Assertions.assertEquals(1, entriesAfter.getEntries().size());
|
||||
Assertions.assertEquals(
|
||||
entryToStar.getId(), entriesAfter.getEntries().getFirst().getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void starredEntriesAreKeptWhenCleaningOldEntries() {
|
||||
// Subscribe to feed and wait for entries
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
@Test
|
||||
void starredEntriesAreKeptWhenCleaningOldEntries() {
|
||||
// Subscribe to feed and wait for entries
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
|
||||
// Verify we have 2 entries
|
||||
Entries entriesBefore = getFeedEntries(subscriptionId);
|
||||
Assertions.assertEquals(2, entriesBefore.getEntries().size());
|
||||
// Verify we have 2 entries
|
||||
Entries entriesBefore = getFeedEntries(subscriptionId);
|
||||
Assertions.assertEquals(2, entriesBefore.getEntries().size());
|
||||
|
||||
// Star the first entry (oldest one based on published date in rss.xml)
|
||||
Entry entryToStar = entriesBefore.getEntries().getFirst();
|
||||
starEntry(entryToStar.getId(), subscriptionId);
|
||||
// Star the first entry (oldest one based on published date in rss.xml)
|
||||
Entry entryToStar = entriesBefore.getEntries().getFirst();
|
||||
starEntry(entryToStar.getId(), subscriptionId);
|
||||
|
||||
// Verify the entry is starred
|
||||
Entries starredEntries = getCategoryEntries(CategoryREST.STARRED);
|
||||
Assertions.assertEquals(1, starredEntries.getEntries().size());
|
||||
// Verify the entry is starred
|
||||
Entries starredEntries = getCategoryEntries(CategoryREST.STARRED);
|
||||
Assertions.assertEquals(1, starredEntries.getEntries().size());
|
||||
|
||||
// Run cleanup for entries older than now (should try to delete all entries)
|
||||
// With keepStarredEntries=true (default), the starred entry should be preserved
|
||||
Instant olderThan = Instant.now().plus(Duration.ofDays(1));
|
||||
databaseCleaningService.cleanEntriesOlderThan(olderThan);
|
||||
// Run cleanup for entries older than now (should try to delete all entries)
|
||||
// With keepStarredEntries=true (default), the starred entry should be preserved
|
||||
Instant olderThan = Instant.now().plus(Duration.ofDays(1));
|
||||
databaseCleaningService.cleanEntriesOlderThan(olderThan);
|
||||
|
||||
// Verify starred entry is still present
|
||||
Entries starredEntriesAfter = getCategoryEntries(CategoryREST.STARRED);
|
||||
Assertions.assertEquals(1, starredEntriesAfter.getEntries().size());
|
||||
Assertions.assertEquals(entryToStar.getId(), starredEntriesAfter.getEntries().getFirst().getId());
|
||||
// Verify starred entry is still present
|
||||
Entries starredEntriesAfter = getCategoryEntries(CategoryREST.STARRED);
|
||||
Assertions.assertEquals(1, starredEntriesAfter.getEntries().size());
|
||||
Assertions.assertEquals(
|
||||
entryToStar.getId(), starredEntriesAfter.getEntries().getFirst().getId());
|
||||
|
||||
// Verify the non-starred entry was deleted
|
||||
Entries entriesAfter = getFeedEntries(subscriptionId);
|
||||
Assertions.assertEquals(1, entriesAfter.getEntries().size());
|
||||
Assertions.assertEquals(entryToStar.getId(), entriesAfter.getEntries().getFirst().getId());
|
||||
}
|
||||
// Verify the non-starred entry was deleted
|
||||
Entries entriesAfter = getFeedEntries(subscriptionId);
|
||||
Assertions.assertEquals(1, entriesAfter.getEntries().size());
|
||||
Assertions.assertEquals(
|
||||
entryToStar.getId(), entriesAfter.getEntries().getFirst().getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void multipleStarredEntriesAreAllKept() {
|
||||
// Subscribe to feed and wait for entries
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
@Test
|
||||
void multipleStarredEntriesAreAllKept() {
|
||||
// Subscribe to feed and wait for entries
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
|
||||
// Verify we have 2 entries
|
||||
Entries entriesBefore = getFeedEntries(subscriptionId);
|
||||
Assertions.assertEquals(2, entriesBefore.getEntries().size());
|
||||
// Verify we have 2 entries
|
||||
Entries entriesBefore = getFeedEntries(subscriptionId);
|
||||
Assertions.assertEquals(2, entriesBefore.getEntries().size());
|
||||
|
||||
// Star both entries
|
||||
entriesBefore.getEntries().forEach(entry -> starEntry(entry.getId(), subscriptionId));
|
||||
// Star both entries
|
||||
entriesBefore.getEntries().forEach(entry -> starEntry(entry.getId(), subscriptionId));
|
||||
|
||||
// Verify both entries are starred
|
||||
Entries starredEntries = getCategoryEntries(CategoryREST.STARRED);
|
||||
Assertions.assertEquals(2, starredEntries.getEntries().size());
|
||||
// Verify both entries are starred
|
||||
Entries starredEntries = getCategoryEntries(CategoryREST.STARRED);
|
||||
Assertions.assertEquals(2, starredEntries.getEntries().size());
|
||||
|
||||
// Run cleanup with capacity of 0 (should delete all non-starred entries)
|
||||
databaseCleaningService.cleanEntriesForFeedsExceedingCapacity(0);
|
||||
// Run cleanup with capacity of 0 (should delete all non-starred entries)
|
||||
databaseCleaningService.cleanEntriesForFeedsExceedingCapacity(0);
|
||||
|
||||
// Verify both starred entries are still present
|
||||
Entries starredEntriesAfter = getCategoryEntries(CategoryREST.STARRED);
|
||||
Assertions.assertEquals(2, starredEntriesAfter.getEntries().size());
|
||||
// Verify both starred entries are still present
|
||||
Entries starredEntriesAfter = getCategoryEntries(CategoryREST.STARRED);
|
||||
Assertions.assertEquals(2, starredEntriesAfter.getEntries().size());
|
||||
|
||||
// Verify all entries are preserved (since all are starred)
|
||||
Entries entriesAfter = getFeedEntries(subscriptionId);
|
||||
Assertions.assertEquals(2, entriesAfter.getEntries().size());
|
||||
}
|
||||
// Verify all entries are preserved (since all are starred)
|
||||
Entries entriesAfter = getFeedEntries(subscriptionId);
|
||||
Assertions.assertEquals(2, entriesAfter.getEntries().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void unstarringEntryMakesItEligibleForCleanup() {
|
||||
// Subscribe to feed and wait for entries
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
@Test
|
||||
void unstarringEntryMakesItEligibleForCleanup() {
|
||||
// Subscribe to feed and wait for entries
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
|
||||
// Star the first entry
|
||||
Entries entriesBefore = getFeedEntries(subscriptionId);
|
||||
Entry entry = entriesBefore.getEntries().getFirst();
|
||||
starEntry(entry.getId(), subscriptionId);
|
||||
// Star the first entry
|
||||
Entries entriesBefore = getFeedEntries(subscriptionId);
|
||||
Entry entry = entriesBefore.getEntries().getFirst();
|
||||
starEntry(entry.getId(), subscriptionId);
|
||||
|
||||
// Verify entry is starred
|
||||
Assertions.assertEquals(1, getCategoryEntries(CategoryREST.STARRED).getEntries().size());
|
||||
// Verify entry is starred
|
||||
Assertions.assertEquals(
|
||||
1, getCategoryEntries(CategoryREST.STARRED).getEntries().size());
|
||||
|
||||
// Unstar the entry
|
||||
unstarEntry(entry.getId(), subscriptionId);
|
||||
// Unstar the entry
|
||||
unstarEntry(entry.getId(), subscriptionId);
|
||||
|
||||
// Verify entry is no longer starred
|
||||
Assertions.assertEquals(0, getCategoryEntries(CategoryREST.STARRED).getEntries().size());
|
||||
// Verify entry is no longer starred
|
||||
Assertions.assertEquals(
|
||||
0, getCategoryEntries(CategoryREST.STARRED).getEntries().size());
|
||||
|
||||
// Run cleanup for entries older than now
|
||||
Instant olderThan = Instant.now().plus(Duration.ofDays(1));
|
||||
databaseCleaningService.cleanEntriesOlderThan(olderThan);
|
||||
// Run cleanup for entries older than now
|
||||
Instant olderThan = Instant.now().plus(Duration.ofDays(1));
|
||||
databaseCleaningService.cleanEntriesOlderThan(olderThan);
|
||||
|
||||
// Verify both entries were deleted (neither is starred)
|
||||
Entries entriesAfter = getFeedEntries(subscriptionId);
|
||||
Assertions.assertEquals(0, entriesAfter.getEntries().size());
|
||||
}
|
||||
}
|
||||
// Verify both entries were deleted (neither is starred)
|
||||
Entries entriesAfter = getFeedEntries(subscriptionId);
|
||||
Assertions.assertEquals(0, entriesAfter.getEntries().size());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class AutoMarkAsRead {
|
||||
@Test
|
||||
void entriesAreMarkedAsReadAfterSpecifiedDays() {
|
||||
// Subscribe to feed
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
@Nested
|
||||
class AutoMarkAsRead {
|
||||
@Test
|
||||
void entriesAreMarkedAsReadAfterSpecifiedDays() {
|
||||
// Subscribe to feed
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
|
||||
// verify we have 2 unread entries
|
||||
Entries entries = getFeedEntries(subscriptionId);
|
||||
Assertions.assertEquals(2, entries.getEntries().stream().filter(e -> !e.isRead()).count());
|
||||
// verify we have 2 unread entries
|
||||
Entries entries = getFeedEntries(subscriptionId);
|
||||
Assertions.assertEquals(
|
||||
2, entries.getEntries().stream().filter(e -> !e.isRead()).count());
|
||||
|
||||
// set auto-mark as read
|
||||
FeedModificationRequest req = new FeedModificationRequest();
|
||||
req.setId(subscriptionId);
|
||||
req.setAutoMarkAsReadAfterDays(1);
|
||||
RestAssured.given().body(req).contentType(ContentType.JSON).post("rest/feed/modify").then().statusCode(200);
|
||||
// set auto-mark as read
|
||||
FeedModificationRequest req = new FeedModificationRequest();
|
||||
req.setId(subscriptionId);
|
||||
req.setAutoMarkAsReadAfterDays(1);
|
||||
RestAssured.given()
|
||||
.body(req)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/feed/modify")
|
||||
.then()
|
||||
.statusCode(200);
|
||||
|
||||
// run auto-mark as read
|
||||
databaseCleaningService.autoMarkAsRead();
|
||||
// run auto-mark as read
|
||||
databaseCleaningService.autoMarkAsRead();
|
||||
|
||||
// verify all entries are now read
|
||||
entries = getFeedEntries(subscriptionId);
|
||||
Assertions.assertEquals(0, entries.getEntries().stream().filter(e -> !e.isRead()).count());
|
||||
}
|
||||
}
|
||||
// verify all entries are now read
|
||||
entries = getFeedEntries(subscriptionId);
|
||||
Assertions.assertEquals(
|
||||
0, entries.getEntries().stream().filter(e -> !e.isRead()).count());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
package com.commafeed.integration.rest;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.UserModel;
|
||||
import com.commafeed.frontend.model.request.AdminSaveUserRequest;
|
||||
import com.commafeed.frontend.model.request.IDRequest;
|
||||
import com.commafeed.integration.BaseIT;
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
@@ -9,96 +16,104 @@ import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.UserModel;
|
||||
import com.commafeed.frontend.model.request.AdminSaveUserRequest;
|
||||
import com.commafeed.frontend.model.request.IDRequest;
|
||||
import com.commafeed.integration.BaseIT;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
|
||||
@QuarkusTest
|
||||
class AdminIT extends BaseIT {
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication = RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication =
|
||||
RestAssured.preemptive()
|
||||
.basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
RestAssured.reset();
|
||||
}
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
RestAssured.reset();
|
||||
}
|
||||
|
||||
@Nested
|
||||
class Users {
|
||||
@Test
|
||||
void saveModifyAndDeleteNewUser() {
|
||||
List<UserModel> existingUsers = getAllUsers();
|
||||
@Nested
|
||||
class Users {
|
||||
@Test
|
||||
void saveModifyAndDeleteNewUser() {
|
||||
List<UserModel> existingUsers = getAllUsers();
|
||||
|
||||
long userId = createUser();
|
||||
Assertions.assertEquals(existingUsers.size() + 1, getAllUsers().size());
|
||||
long userId = createUser();
|
||||
Assertions.assertEquals(existingUsers.size() + 1, getAllUsers().size());
|
||||
|
||||
UserModel user = getUser(userId);
|
||||
Assertions.assertEquals("test", user.getName());
|
||||
UserModel user = getUser(userId);
|
||||
Assertions.assertEquals("test", user.getName());
|
||||
|
||||
modifyUser(user);
|
||||
Assertions.assertEquals(existingUsers.size() + 1, getAllUsers().size());
|
||||
modifyUser(user);
|
||||
Assertions.assertEquals(existingUsers.size() + 1, getAllUsers().size());
|
||||
|
||||
deleteUser();
|
||||
Assertions.assertEquals(existingUsers.size(), getAllUsers().size());
|
||||
}
|
||||
deleteUser();
|
||||
Assertions.assertEquals(existingUsers.size(), getAllUsers().size());
|
||||
}
|
||||
|
||||
private long createUser() {
|
||||
AdminSaveUserRequest user = new AdminSaveUserRequest();
|
||||
user.setName("test");
|
||||
user.setPassword("Test1234!");
|
||||
user.setEmail("test@test.com");
|
||||
user.setEnabled(true);
|
||||
String response = RestAssured.given()
|
||||
.body(user)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/admin/user/save")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.asString();
|
||||
return Long.parseLong(response);
|
||||
}
|
||||
private long createUser() {
|
||||
AdminSaveUserRequest user = new AdminSaveUserRequest();
|
||||
user.setName("test");
|
||||
user.setPassword("Test1234!");
|
||||
user.setEmail("test@test.com");
|
||||
user.setEnabled(true);
|
||||
String response =
|
||||
RestAssured.given()
|
||||
.body(user)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/admin/user/save")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.asString();
|
||||
return Long.parseLong(response);
|
||||
}
|
||||
|
||||
private UserModel getUser(long userId) {
|
||||
return RestAssured.given()
|
||||
.get("rest/admin/user/get/{id}", userId)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(UserModel.class);
|
||||
}
|
||||
private UserModel getUser(long userId) {
|
||||
return RestAssured.given()
|
||||
.get("rest/admin/user/get/{id}", userId)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(UserModel.class);
|
||||
}
|
||||
|
||||
private void modifyUser(UserModel user) {
|
||||
user.setEmail("new-email@provider.com");
|
||||
RestAssured.given().body(user).contentType(ContentType.JSON).post("rest/admin/user/save").then().statusCode(HttpStatus.SC_OK);
|
||||
}
|
||||
private void modifyUser(UserModel user) {
|
||||
user.setEmail("new-email@provider.com");
|
||||
RestAssured.given()
|
||||
.body(user)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/admin/user/save")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
}
|
||||
|
||||
private void deleteUser() {
|
||||
List<UserModel> existingUsers = getAllUsers();
|
||||
UserModel user = existingUsers.stream()
|
||||
.filter(u -> u.getName().equals("test"))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new NullPointerException("User not found"));
|
||||
private void deleteUser() {
|
||||
List<UserModel> existingUsers = getAllUsers();
|
||||
UserModel user =
|
||||
existingUsers.stream()
|
||||
.filter(u -> u.getName().equals("test"))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new NullPointerException("User not found"));
|
||||
|
||||
IDRequest req = new IDRequest();
|
||||
req.setId(user.getId());
|
||||
RestAssured.given().body(req).contentType(ContentType.JSON).post("rest/admin/user/delete").then().statusCode(HttpStatus.SC_OK);
|
||||
}
|
||||
|
||||
private List<UserModel> getAllUsers() {
|
||||
return List.of(
|
||||
RestAssured.given().get("rest/admin/user/getAll").then().statusCode(HttpStatus.SC_OK).extract().as(UserModel[].class));
|
||||
}
|
||||
}
|
||||
IDRequest req = new IDRequest();
|
||||
req.setId(user.getId());
|
||||
RestAssured.given()
|
||||
.body(req)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/admin/user/delete")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
}
|
||||
|
||||
private List<UserModel> getAllUsers() {
|
||||
return List.of(
|
||||
RestAssured.given()
|
||||
.get("rest/admin/user/getAll")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(UserModel[].class));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,5 @@
|
||||
package com.commafeed.integration.rest;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.Category;
|
||||
import com.commafeed.frontend.model.Entries;
|
||||
@@ -27,214 +16,273 @@ import com.commafeed.integration.BaseIT;
|
||||
import com.rometools.rome.feed.synd.SyndFeed;
|
||||
import com.rometools.rome.io.FeedException;
|
||||
import com.rometools.rome.io.SyndFeedInput;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
import java.io.StringReader;
|
||||
import java.util.List;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
@QuarkusTest
|
||||
class CategoryIT extends BaseIT {
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication = RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication =
|
||||
RestAssured.preemptive()
|
||||
.basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
RestAssured.reset();
|
||||
}
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
RestAssured.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
void modifyCategory() {
|
||||
String category1Id = createCategory("test-category-1");
|
||||
String category2Id = createCategory("test-category-2");
|
||||
String category3Id = createCategory("test-category-3");
|
||||
@Test
|
||||
void modifyCategory() {
|
||||
String category1Id = createCategory("test-category-1");
|
||||
String category2Id = createCategory("test-category-2");
|
||||
String category3Id = createCategory("test-category-3");
|
||||
|
||||
CategoryModificationRequest request = new CategoryModificationRequest();
|
||||
request.setId(Long.valueOf(category2Id));
|
||||
request.setName("modified-category-2");
|
||||
request.setParentId(category1Id);
|
||||
request.setPosition(2);
|
||||
RestAssured.given().body(request).contentType(ContentType.JSON).post("rest/category/modify").then().statusCode(200);
|
||||
CategoryModificationRequest request = new CategoryModificationRequest();
|
||||
request.setId(Long.valueOf(category2Id));
|
||||
request.setName("modified-category-2");
|
||||
request.setParentId(category1Id);
|
||||
request.setPosition(2);
|
||||
RestAssured.given()
|
||||
.body(request)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/category/modify")
|
||||
.then()
|
||||
.statusCode(200);
|
||||
|
||||
Category root = getRootCategory();
|
||||
Assertions.assertEquals(2, root.getChildren().size());
|
||||
Assertions.assertEquals("test-category-1", root.getChildren().getFirst().getName());
|
||||
Assertions.assertEquals(1, root.getChildren().getFirst().getChildren().size());
|
||||
Assertions.assertEquals("modified-category-2", root.getChildren().getFirst().getChildren().getFirst().getName());
|
||||
Category root = getRootCategory();
|
||||
Assertions.assertEquals(2, root.getChildren().size());
|
||||
Assertions.assertEquals("test-category-1", root.getChildren().getFirst().getName());
|
||||
Assertions.assertEquals(1, root.getChildren().getFirst().getChildren().size());
|
||||
Assertions.assertEquals(
|
||||
"modified-category-2",
|
||||
root.getChildren().getFirst().getChildren().getFirst().getName());
|
||||
|
||||
request = new CategoryModificationRequest();
|
||||
request.setId(Long.valueOf(category3Id));
|
||||
request.setPosition(0);
|
||||
RestAssured.given().body(request).contentType(ContentType.JSON).post("rest/category/modify").then().statusCode(200);
|
||||
request = new CategoryModificationRequest();
|
||||
request.setId(Long.valueOf(category3Id));
|
||||
request.setPosition(0);
|
||||
RestAssured.given()
|
||||
.body(request)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/category/modify")
|
||||
.then()
|
||||
.statusCode(200);
|
||||
|
||||
root = getRootCategory();
|
||||
Assertions.assertEquals(2, root.getChildren().size());
|
||||
Assertions.assertEquals("test-category-3", root.getChildren().get(0).getName());
|
||||
Assertions.assertEquals("test-category-1", root.getChildren().get(1).getName());
|
||||
}
|
||||
root = getRootCategory();
|
||||
Assertions.assertEquals(2, root.getChildren().size());
|
||||
Assertions.assertEquals("test-category-3", root.getChildren().get(0).getName());
|
||||
Assertions.assertEquals("test-category-1", root.getChildren().get(1).getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void collapseCategory() {
|
||||
String categoryId = createCategory("test-category");
|
||||
@Test
|
||||
void collapseCategory() {
|
||||
String categoryId = createCategory("test-category");
|
||||
|
||||
Category root = getRootCategory();
|
||||
Assertions.assertEquals(1, root.getChildren().size());
|
||||
Assertions.assertTrue(root.getChildren().getFirst().isExpanded());
|
||||
Category root = getRootCategory();
|
||||
Assertions.assertEquals(1, root.getChildren().size());
|
||||
Assertions.assertTrue(root.getChildren().getFirst().isExpanded());
|
||||
|
||||
CollapseRequest request = new CollapseRequest();
|
||||
request.setId(Long.valueOf(categoryId));
|
||||
request.setCollapse(true);
|
||||
RestAssured.given().body(request).contentType(ContentType.JSON).post("rest/category/collapse").then().statusCode(200);
|
||||
CollapseRequest request = new CollapseRequest();
|
||||
request.setId(Long.valueOf(categoryId));
|
||||
request.setCollapse(true);
|
||||
RestAssured.given()
|
||||
.body(request)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/category/collapse")
|
||||
.then()
|
||||
.statusCode(200);
|
||||
|
||||
root = getRootCategory();
|
||||
Assertions.assertEquals(1, root.getChildren().size());
|
||||
Assertions.assertFalse(root.getChildren().getFirst().isExpanded());
|
||||
}
|
||||
root = getRootCategory();
|
||||
Assertions.assertEquals(1, root.getChildren().size());
|
||||
Assertions.assertFalse(root.getChildren().getFirst().isExpanded());
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteCategory() {
|
||||
String categoryId = createCategory("test-category");
|
||||
Assertions.assertEquals(1, getRootCategory().getChildren().size());
|
||||
@Test
|
||||
void deleteCategory() {
|
||||
String categoryId = createCategory("test-category");
|
||||
Assertions.assertEquals(1, getRootCategory().getChildren().size());
|
||||
|
||||
IDRequest request = new IDRequest();
|
||||
request.setId(Long.valueOf(categoryId));
|
||||
RestAssured.given().body(request).contentType(ContentType.JSON).post("rest/category/delete").then().statusCode(200);
|
||||
Assertions.assertEquals(0, getRootCategory().getChildren().size());
|
||||
}
|
||||
IDRequest request = new IDRequest();
|
||||
request.setId(Long.valueOf(categoryId));
|
||||
RestAssured.given()
|
||||
.body(request)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/category/delete")
|
||||
.then()
|
||||
.statusCode(200);
|
||||
Assertions.assertEquals(0, getRootCategory().getChildren().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void unreadCount() {
|
||||
String categoryId = createCategory("test-category");
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl(), categoryId);
|
||||
Assertions.assertEquals(2, getCategoryEntries(categoryId).getEntries().size());
|
||||
@Test
|
||||
void unreadCount() {
|
||||
String categoryId = createCategory("test-category");
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl(), categoryId);
|
||||
Assertions.assertEquals(2, getCategoryEntries(categoryId).getEntries().size());
|
||||
|
||||
UnreadCount[] counts = RestAssured.given()
|
||||
.get("rest/category/unreadCount")
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.extract()
|
||||
.as(UnreadCount[].class);
|
||||
UnreadCount[] counts =
|
||||
RestAssured.given()
|
||||
.get("rest/category/unreadCount")
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.extract()
|
||||
.as(UnreadCount[].class);
|
||||
|
||||
Assertions.assertEquals(1, counts.length);
|
||||
Assertions.assertEquals(subscriptionId, counts[0].getFeedId());
|
||||
Assertions.assertEquals(2, counts[0].getUnreadCount());
|
||||
}
|
||||
Assertions.assertEquals(1, counts.length);
|
||||
Assertions.assertEquals(subscriptionId, counts[0].getFeedId());
|
||||
Assertions.assertEquals(2, counts[0].getUnreadCount());
|
||||
}
|
||||
|
||||
@Nested
|
||||
class MarkEntriesAsRead {
|
||||
@Test
|
||||
void all() {
|
||||
subscribeAndWaitForEntries(getFeedUrl());
|
||||
Assertions.assertTrue(getCategoryEntries(CategoryREST.ALL).getEntries().stream().noneMatch(Entry::isRead));
|
||||
@Nested
|
||||
class MarkEntriesAsRead {
|
||||
@Test
|
||||
void all() {
|
||||
subscribeAndWaitForEntries(getFeedUrl());
|
||||
Assertions.assertTrue(
|
||||
getCategoryEntries(CategoryREST.ALL).getEntries().stream()
|
||||
.noneMatch(Entry::isRead));
|
||||
|
||||
MarkRequest request = new MarkRequest();
|
||||
request.setId(CategoryREST.ALL);
|
||||
request.setRead(true);
|
||||
RestAssured.given().body(request).contentType(ContentType.JSON).post("rest/category/mark").then().statusCode(200);
|
||||
Assertions.assertTrue(getCategoryEntries(CategoryREST.ALL).getEntries().stream().allMatch(Entry::isRead));
|
||||
}
|
||||
MarkRequest request = new MarkRequest();
|
||||
request.setId(CategoryREST.ALL);
|
||||
request.setRead(true);
|
||||
RestAssured.given()
|
||||
.body(request)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/category/mark")
|
||||
.then()
|
||||
.statusCode(200);
|
||||
Assertions.assertTrue(
|
||||
getCategoryEntries(CategoryREST.ALL).getEntries().stream()
|
||||
.allMatch(Entry::isRead));
|
||||
}
|
||||
|
||||
@Test
|
||||
void specificCategory() {
|
||||
String categoryId = createCategory("test-category");
|
||||
subscribeAndWaitForEntries(getFeedUrl(), categoryId);
|
||||
Assertions.assertTrue(getCategoryEntries(categoryId).getEntries().stream().noneMatch(Entry::isRead));
|
||||
@Test
|
||||
void specificCategory() {
|
||||
String categoryId = createCategory("test-category");
|
||||
subscribeAndWaitForEntries(getFeedUrl(), categoryId);
|
||||
Assertions.assertTrue(
|
||||
getCategoryEntries(categoryId).getEntries().stream().noneMatch(Entry::isRead));
|
||||
|
||||
MarkRequest request = new MarkRequest();
|
||||
request.setId(categoryId);
|
||||
request.setRead(true);
|
||||
RestAssured.given().body(request).contentType(ContentType.JSON).post("rest/category/mark").then().statusCode(200);
|
||||
Assertions.assertTrue(getCategoryEntries(categoryId).getEntries().stream().allMatch(Entry::isRead));
|
||||
}
|
||||
}
|
||||
MarkRequest request = new MarkRequest();
|
||||
request.setId(categoryId);
|
||||
request.setRead(true);
|
||||
RestAssured.given()
|
||||
.body(request)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/category/mark")
|
||||
.then()
|
||||
.statusCode(200);
|
||||
Assertions.assertTrue(
|
||||
getCategoryEntries(categoryId).getEntries().stream().allMatch(Entry::isRead));
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class GetEntries {
|
||||
@Test
|
||||
void all() {
|
||||
subscribeAndWaitForEntries(getFeedUrl());
|
||||
Entries entries = getCategoryEntries(CategoryREST.ALL);
|
||||
Assertions.assertEquals(2, entries.getEntries().size());
|
||||
}
|
||||
@Nested
|
||||
class GetEntries {
|
||||
@Test
|
||||
void all() {
|
||||
subscribeAndWaitForEntries(getFeedUrl());
|
||||
Entries entries = getCategoryEntries(CategoryREST.ALL);
|
||||
Assertions.assertEquals(2, entries.getEntries().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void pagination() {
|
||||
subscribeAndWaitForEntries(getFeedUrl());
|
||||
@Test
|
||||
void pagination() {
|
||||
subscribeAndWaitForEntries(getFeedUrl());
|
||||
|
||||
Entries firstPage = getCategoryEntries(CategoryREST.ALL, 0, 1);
|
||||
Assertions.assertEquals(1, firstPage.getEntries().size());
|
||||
Assertions.assertTrue(firstPage.isHasMore());
|
||||
Entries firstPage = getCategoryEntries(CategoryREST.ALL, 0, 1);
|
||||
Assertions.assertEquals(1, firstPage.getEntries().size());
|
||||
Assertions.assertTrue(firstPage.isHasMore());
|
||||
|
||||
Entries lastPage = getCategoryEntries(CategoryREST.ALL, 1, 10);
|
||||
Assertions.assertEquals(1, lastPage.getEntries().size());
|
||||
Assertions.assertFalse(lastPage.isHasMore());
|
||||
}
|
||||
Entries lastPage = getCategoryEntries(CategoryREST.ALL, 1, 10);
|
||||
Assertions.assertEquals(1, lastPage.getEntries().size());
|
||||
Assertions.assertFalse(lastPage.isHasMore());
|
||||
}
|
||||
|
||||
@Test
|
||||
void allAsFeed() throws FeedException {
|
||||
subscribeAndWaitForEntries(getFeedUrl());
|
||||
String xml = RestAssured.given()
|
||||
.get("rest/category/entriesAsFeed?id=all")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.contentType(ContentType.XML)
|
||||
.extract()
|
||||
.asString();
|
||||
@Test
|
||||
void allAsFeed() throws FeedException {
|
||||
subscribeAndWaitForEntries(getFeedUrl());
|
||||
String xml =
|
||||
RestAssured.given()
|
||||
.get("rest/category/entriesAsFeed?id=all")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.contentType(ContentType.XML)
|
||||
.extract()
|
||||
.asString();
|
||||
|
||||
InputSource source = new InputSource(new StringReader(xml));
|
||||
SyndFeed feed = new SyndFeedInput().build(source);
|
||||
Assertions.assertEquals(2, feed.getEntries().size());
|
||||
}
|
||||
InputSource source = new InputSource(new StringReader(xml));
|
||||
SyndFeed feed = new SyndFeedInput().build(source);
|
||||
Assertions.assertEquals(2, feed.getEntries().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void starred() {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
Assertions.assertEquals(0, getCategoryEntries(CategoryREST.STARRED).getEntries().size());
|
||||
@Test
|
||||
void starred() {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
Assertions.assertEquals(
|
||||
0, getCategoryEntries(CategoryREST.STARRED).getEntries().size());
|
||||
|
||||
Entry entry = getFeedEntries(subscriptionId).getEntries().getFirst();
|
||||
Entry entry = getFeedEntries(subscriptionId).getEntries().getFirst();
|
||||
|
||||
StarRequest starRequest = new StarRequest();
|
||||
starRequest.setId(entry.getId());
|
||||
starRequest.setFeedId(subscriptionId);
|
||||
starRequest.setStarred(true);
|
||||
RestAssured.given().body(starRequest).contentType(ContentType.JSON).post("rest/entry/star");
|
||||
StarRequest starRequest = new StarRequest();
|
||||
starRequest.setId(entry.getId());
|
||||
starRequest.setFeedId(subscriptionId);
|
||||
starRequest.setStarred(true);
|
||||
RestAssured.given()
|
||||
.body(starRequest)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/entry/star");
|
||||
|
||||
Entries starredEntries = getCategoryEntries(CategoryREST.STARRED);
|
||||
Assertions.assertEquals(1, starredEntries.getEntries().size());
|
||||
Assertions.assertEquals(entry.getId(), starredEntries.getEntries().getFirst().getId());
|
||||
}
|
||||
Entries starredEntries = getCategoryEntries(CategoryREST.STARRED);
|
||||
Assertions.assertEquals(1, starredEntries.getEntries().size());
|
||||
Assertions.assertEquals(entry.getId(), starredEntries.getEntries().getFirst().getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void tagged() {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
Assertions.assertEquals(0, getTaggedEntries("my-tag").getEntries().size());
|
||||
@Test
|
||||
void tagged() {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
Assertions.assertEquals(0, getTaggedEntries("my-tag").getEntries().size());
|
||||
|
||||
Entry entry = getFeedEntries(subscriptionId).getEntries().getFirst();
|
||||
Entry entry = getFeedEntries(subscriptionId).getEntries().getFirst();
|
||||
|
||||
TagRequest tagRequest = new TagRequest();
|
||||
tagRequest.setEntryId(Long.valueOf(entry.getId()));
|
||||
tagRequest.setTags(List.of("my-tag"));
|
||||
RestAssured.given().body(tagRequest).contentType(ContentType.JSON).post("rest/entry/tag");
|
||||
TagRequest tagRequest = new TagRequest();
|
||||
tagRequest.setEntryId(Long.valueOf(entry.getId()));
|
||||
tagRequest.setTags(List.of("my-tag"));
|
||||
RestAssured.given()
|
||||
.body(tagRequest)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/entry/tag");
|
||||
|
||||
Entries taggedEntries = getTaggedEntries("my-tag");
|
||||
Assertions.assertEquals(1, taggedEntries.getEntries().size());
|
||||
Assertions.assertEquals(entry.getId(), taggedEntries.getEntries().getFirst().getId());
|
||||
}
|
||||
Entries taggedEntries = getTaggedEntries("my-tag");
|
||||
Assertions.assertEquals(1, taggedEntries.getEntries().size());
|
||||
Assertions.assertEquals(entry.getId(), taggedEntries.getEntries().getFirst().getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void keywords() {
|
||||
subscribeAndWaitForEntries(getFeedUrl());
|
||||
Assertions.assertEquals(1, getCategoryEntries(CategoryREST.ALL, "Item 2 description").getEntries().size());
|
||||
}
|
||||
@Test
|
||||
void keywords() {
|
||||
subscribeAndWaitForEntries(getFeedUrl());
|
||||
Assertions.assertEquals(
|
||||
1,
|
||||
getCategoryEntries(CategoryREST.ALL, "Item 2 description").getEntries().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void specificCategory() {
|
||||
String categoryId = createCategory("test-category");
|
||||
subscribeAndWaitForEntries(getFeedUrl(), categoryId);
|
||||
Entries entries = getCategoryEntries(categoryId);
|
||||
Assertions.assertEquals(2, entries.getEntries().size());
|
||||
}
|
||||
}
|
||||
@Test
|
||||
void specificCategory() {
|
||||
String categoryId = createCategory("test-category");
|
||||
subscribeAndWaitForEntries(getFeedUrl(), categoryId);
|
||||
Entries entries = getCategoryEntries(categoryId);
|
||||
Assertions.assertEquals(2, entries.getEntries().size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,5 @@
|
||||
package com.commafeed.integration.rest;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.Objects;
|
||||
|
||||
import jakarta.ws.rs.core.HttpHeaders;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.awaitility.Awaitility;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.Entries;
|
||||
import com.commafeed.frontend.model.Entry;
|
||||
@@ -36,278 +14,346 @@ import com.commafeed.integration.BaseIT;
|
||||
import com.rometools.rome.feed.synd.SyndFeed;
|
||||
import com.rometools.rome.io.FeedException;
|
||||
import com.rometools.rome.io.SyndFeedInput;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
import jakarta.ws.rs.core.HttpHeaders;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.Objects;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.awaitility.Awaitility;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
@QuarkusTest
|
||||
class FeedIT extends BaseIT {
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication = RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication =
|
||||
RestAssured.preemptive()
|
||||
.basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
RestAssured.reset();
|
||||
}
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
RestAssured.reset();
|
||||
}
|
||||
|
||||
@Nested
|
||||
class Fetch {
|
||||
@Test
|
||||
void fetchFeed() {
|
||||
FeedInfoRequest req = new FeedInfoRequest();
|
||||
req.setUrl(getFeedUrl());
|
||||
@Nested
|
||||
class Fetch {
|
||||
@Test
|
||||
void fetchFeed() {
|
||||
FeedInfoRequest req = new FeedInfoRequest();
|
||||
req.setUrl(getFeedUrl());
|
||||
|
||||
FeedInfo feedInfo = RestAssured.given()
|
||||
.body(req)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/feed/fetch")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(FeedInfo.class);
|
||||
Assertions.assertEquals("CommaFeed test feed", feedInfo.getTitle());
|
||||
Assertions.assertEquals(getFeedUrl(), feedInfo.getUrl());
|
||||
}
|
||||
}
|
||||
FeedInfo feedInfo =
|
||||
RestAssured.given()
|
||||
.body(req)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/feed/fetch")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(FeedInfo.class);
|
||||
Assertions.assertEquals("CommaFeed test feed", feedInfo.getTitle());
|
||||
Assertions.assertEquals(getFeedUrl(), feedInfo.getUrl());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class Subscribe {
|
||||
@Test
|
||||
void subscribeAndReadEntries() {
|
||||
long subscriptionId = subscribe(getFeedUrl());
|
||||
Awaitility.await().atMost(Duration.ofSeconds(15)).until(() -> getFeedEntries(subscriptionId), e -> e.getEntries().size() == 2);
|
||||
}
|
||||
@Nested
|
||||
class Subscribe {
|
||||
@Test
|
||||
void subscribeAndReadEntries() {
|
||||
long subscriptionId = subscribe(getFeedUrl());
|
||||
Awaitility.await()
|
||||
.atMost(Duration.ofSeconds(15))
|
||||
.until(() -> getFeedEntries(subscriptionId), e -> e.getEntries().size() == 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void subscribeFromUrl() {
|
||||
RestAssured.given()
|
||||
.queryParam("url", getFeedUrl())
|
||||
.redirects()
|
||||
.follow(false)
|
||||
.get("rest/feed/subscribe")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_TEMPORARY_REDIRECT);
|
||||
}
|
||||
@Test
|
||||
void subscribeFromUrl() {
|
||||
RestAssured.given()
|
||||
.queryParam("url", getFeedUrl())
|
||||
.redirects()
|
||||
.follow(false)
|
||||
.get("rest/feed/subscribe")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_TEMPORARY_REDIRECT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void unsubscribeFromUnknownFeed() {
|
||||
Assertions.assertEquals(HttpStatus.SC_NOT_FOUND, unsubsribe(1L));
|
||||
}
|
||||
@Test
|
||||
void unsubscribeFromUnknownFeed() {
|
||||
Assertions.assertEquals(HttpStatus.SC_NOT_FOUND, unsubsribe(1L));
|
||||
}
|
||||
|
||||
@Test
|
||||
void unsubscribeFromKnownFeed() {
|
||||
long subscriptionId = subscribe(getFeedUrl());
|
||||
Assertions.assertEquals(HttpStatus.SC_OK, unsubsribe(subscriptionId));
|
||||
}
|
||||
@Test
|
||||
void unsubscribeFromKnownFeed() {
|
||||
long subscriptionId = subscribe(getFeedUrl());
|
||||
Assertions.assertEquals(HttpStatus.SC_OK, unsubsribe(subscriptionId));
|
||||
}
|
||||
|
||||
private int unsubsribe(long subscriptionId) {
|
||||
IDRequest request = new IDRequest();
|
||||
request.setId(subscriptionId);
|
||||
private int unsubsribe(long subscriptionId) {
|
||||
IDRequest request = new IDRequest();
|
||||
request.setId(subscriptionId);
|
||||
|
||||
return RestAssured.given()
|
||||
.body(request)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/feed/unsubscribe")
|
||||
.then()
|
||||
.extract()
|
||||
.statusCode();
|
||||
}
|
||||
}
|
||||
return RestAssured.given()
|
||||
.body(request)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/feed/unsubscribe")
|
||||
.then()
|
||||
.extract()
|
||||
.statusCode();
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class Mark {
|
||||
@Test
|
||||
void markWithoutDates() {
|
||||
long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
markFeedEntries(subscriptionId, null, null);
|
||||
Assertions.assertTrue(getFeedEntries(subscriptionId).getEntries().stream().allMatch(Entry::isRead));
|
||||
}
|
||||
@Nested
|
||||
class Mark {
|
||||
@Test
|
||||
void markWithoutDates() {
|
||||
long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
markFeedEntries(subscriptionId, null, null);
|
||||
Assertions.assertTrue(
|
||||
getFeedEntries(subscriptionId).getEntries().stream().allMatch(Entry::isRead));
|
||||
}
|
||||
|
||||
@Test
|
||||
void markOlderThan() {
|
||||
long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
markFeedEntries(subscriptionId, LocalDate.of(2023, 12, 28).atStartOfDay().toInstant(ZoneOffset.UTC), null);
|
||||
Assertions.assertEquals(1, getFeedEntries(subscriptionId).getEntries().stream().filter(Entry::isRead).count());
|
||||
}
|
||||
@Test
|
||||
void markOlderThan() {
|
||||
long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
markFeedEntries(
|
||||
subscriptionId,
|
||||
LocalDate.of(2023, 12, 28).atStartOfDay().toInstant(ZoneOffset.UTC),
|
||||
null);
|
||||
Assertions.assertEquals(
|
||||
1,
|
||||
getFeedEntries(subscriptionId).getEntries().stream()
|
||||
.filter(Entry::isRead)
|
||||
.count());
|
||||
}
|
||||
|
||||
@Test
|
||||
void markInsertedBeforeBeforeSubscription() {
|
||||
// mariadb/mysql timestamp precision is 1 second
|
||||
Instant threshold = Instant.now().minus(Duration.ofSeconds(1));
|
||||
@Test
|
||||
void markInsertedBeforeBeforeSubscription() {
|
||||
// mariadb/mysql timestamp precision is 1 second
|
||||
Instant threshold = Instant.now().minus(Duration.ofSeconds(1));
|
||||
|
||||
long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
markFeedEntries(subscriptionId, null, threshold);
|
||||
Assertions.assertTrue(getFeedEntries(subscriptionId).getEntries().stream().noneMatch(Entry::isRead));
|
||||
}
|
||||
long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
markFeedEntries(subscriptionId, null, threshold);
|
||||
Assertions.assertTrue(
|
||||
getFeedEntries(subscriptionId).getEntries().stream().noneMatch(Entry::isRead));
|
||||
}
|
||||
|
||||
@Test
|
||||
void markInsertedBeforeAfterSubscription() {
|
||||
long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
@Test
|
||||
void markInsertedBeforeAfterSubscription() {
|
||||
long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
|
||||
// mariadb/mysql timestamp precision is 1 second
|
||||
Instant threshold = Instant.now().plus(Duration.ofSeconds(1));
|
||||
// mariadb/mysql timestamp precision is 1 second
|
||||
Instant threshold = Instant.now().plus(Duration.ofSeconds(1));
|
||||
|
||||
markFeedEntries(subscriptionId, null, threshold);
|
||||
Assertions.assertTrue(getFeedEntries(subscriptionId).getEntries().stream().allMatch(Entry::isRead));
|
||||
}
|
||||
markFeedEntries(subscriptionId, null, threshold);
|
||||
Assertions.assertTrue(
|
||||
getFeedEntries(subscriptionId).getEntries().stream().allMatch(Entry::isRead));
|
||||
}
|
||||
|
||||
private void markFeedEntries(long subscriptionId, Instant olderThan, Instant insertedBefore) {
|
||||
MarkRequest request = new MarkRequest();
|
||||
request.setId(String.valueOf(subscriptionId));
|
||||
request.setOlderThan(olderThan == null ? null : olderThan.toEpochMilli());
|
||||
request.setInsertedBefore(insertedBefore == null ? null : insertedBefore.toEpochMilli());
|
||||
private void markFeedEntries(
|
||||
long subscriptionId, Instant olderThan, Instant insertedBefore) {
|
||||
MarkRequest request = new MarkRequest();
|
||||
request.setId(String.valueOf(subscriptionId));
|
||||
request.setOlderThan(olderThan == null ? null : olderThan.toEpochMilli());
|
||||
request.setInsertedBefore(
|
||||
insertedBefore == null ? null : insertedBefore.toEpochMilli());
|
||||
|
||||
RestAssured.given().body(request).contentType(ContentType.JSON).post("rest/feed/mark").then().statusCode(HttpStatus.SC_OK);
|
||||
}
|
||||
}
|
||||
RestAssured.given()
|
||||
.body(request)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/feed/mark")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class Refresh {
|
||||
@Nested
|
||||
class Refresh {
|
||||
|
||||
@Test
|
||||
void refreshAll() {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
Assertions.assertEquals(2, getCategoryEntries(CategoryREST.ALL).getEntries().size());
|
||||
@Test
|
||||
void refreshAll() {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
Assertions.assertEquals(2, getCategoryEntries(CategoryREST.ALL).getEntries().size());
|
||||
|
||||
// mariadb/mysql timestamp precision is 1 second
|
||||
Instant threshold = Instant.now().minus(Duration.ofSeconds(1));
|
||||
Assertions.assertEquals(HttpStatus.SC_OK, forceRefreshAllFeeds());
|
||||
// mariadb/mysql timestamp precision is 1 second
|
||||
Instant threshold = Instant.now().minus(Duration.ofSeconds(1));
|
||||
Assertions.assertEquals(HttpStatus.SC_OK, forceRefreshAllFeeds());
|
||||
|
||||
Awaitility.await()
|
||||
.atMost(Duration.ofSeconds(15))
|
||||
.until(() -> getSubscription(subscriptionId), f -> f.getLastRefresh().isAfter(threshold));
|
||||
Assertions.assertEquals(2, getCategoryEntries(CategoryREST.ALL).getEntries().size());
|
||||
Awaitility.await()
|
||||
.atMost(Duration.ofSeconds(15))
|
||||
.until(
|
||||
() -> getSubscription(subscriptionId),
|
||||
f -> f.getLastRefresh().isAfter(threshold));
|
||||
Assertions.assertEquals(2, getCategoryEntries(CategoryREST.ALL).getEntries().size());
|
||||
|
||||
Assertions.assertEquals(HttpStatus.SC_TOO_MANY_REQUESTS, forceRefreshAllFeeds());
|
||||
}
|
||||
}
|
||||
Assertions.assertEquals(HttpStatus.SC_TOO_MANY_REQUESTS, forceRefreshAllFeeds());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class RSS {
|
||||
@Test
|
||||
void allAsFeed() throws FeedException {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
String xml = RestAssured.given()
|
||||
.get("rest/feed/entriesAsFeed?id={id}", subscriptionId)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.contentType(ContentType.XML)
|
||||
.extract()
|
||||
.asString();
|
||||
@Nested
|
||||
class RSS {
|
||||
@Test
|
||||
void allAsFeed() throws FeedException {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
String xml =
|
||||
RestAssured.given()
|
||||
.get("rest/feed/entriesAsFeed?id={id}", subscriptionId)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.contentType(ContentType.XML)
|
||||
.extract()
|
||||
.asString();
|
||||
|
||||
InputSource source = new InputSource(new StringReader(xml));
|
||||
SyndFeed feed = new SyndFeedInput().build(source);
|
||||
Assertions.assertEquals(2, feed.getEntries().size());
|
||||
}
|
||||
}
|
||||
InputSource source = new InputSource(new StringReader(xml));
|
||||
SyndFeed feed = new SyndFeedInput().build(source);
|
||||
Assertions.assertEquals(2, feed.getEntries().size());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class Modify {
|
||||
@Test
|
||||
void modify() {
|
||||
Long subscriptionId = subscribe(getFeedUrl());
|
||||
@Nested
|
||||
class Modify {
|
||||
@Test
|
||||
void modify() {
|
||||
Long subscriptionId = subscribe(getFeedUrl());
|
||||
|
||||
Subscription subscription = getSubscription(subscriptionId);
|
||||
Subscription subscription = getSubscription(subscriptionId);
|
||||
|
||||
FeedModificationRequest req = new FeedModificationRequest();
|
||||
req.setId(subscriptionId);
|
||||
req.setName("new name");
|
||||
req.setCategoryId(subscription.getCategoryId());
|
||||
req.setPosition(1);
|
||||
req.setFilter("url.endsWith('commafeed')");
|
||||
RestAssured.given().body(req).contentType(ContentType.JSON).post("rest/feed/modify").then().statusCode(HttpStatus.SC_OK);
|
||||
FeedModificationRequest req = new FeedModificationRequest();
|
||||
req.setId(subscriptionId);
|
||||
req.setName("new name");
|
||||
req.setCategoryId(subscription.getCategoryId());
|
||||
req.setPosition(1);
|
||||
req.setFilter("url.endsWith('commafeed')");
|
||||
RestAssured.given()
|
||||
.body(req)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/feed/modify")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
|
||||
subscription = getSubscription(subscriptionId);
|
||||
Assertions.assertEquals("new name", subscription.getName());
|
||||
Assertions.assertEquals("url.endsWith('commafeed')", subscription.getFilter());
|
||||
}
|
||||
}
|
||||
subscription = getSubscription(subscriptionId);
|
||||
Assertions.assertEquals("new name", subscription.getName());
|
||||
Assertions.assertEquals("url.endsWith('commafeed')", subscription.getFilter());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class Favicon {
|
||||
@Test
|
||||
void favicon() throws IOException {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
@Nested
|
||||
class Favicon {
|
||||
@Test
|
||||
void favicon() throws IOException {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
|
||||
byte[] icon = RestAssured.given()
|
||||
.get("rest/feed/favicon/{id}", subscriptionId)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.header(HttpHeaders.CACHE_CONTROL, "max-age=2592000")
|
||||
.extract()
|
||||
.response()
|
||||
.asByteArray();
|
||||
byte[] defaultFavicon = IOUtils.toByteArray(Objects.requireNonNull(getClass().getResource("/images/default_favicon.gif")));
|
||||
Assertions.assertArrayEquals(defaultFavicon, icon);
|
||||
}
|
||||
}
|
||||
byte[] icon =
|
||||
RestAssured.given()
|
||||
.get("rest/feed/favicon/{id}", subscriptionId)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.header(HttpHeaders.CACHE_CONTROL, "max-age=2592000")
|
||||
.extract()
|
||||
.response()
|
||||
.asByteArray();
|
||||
byte[] defaultFavicon =
|
||||
IOUtils.toByteArray(
|
||||
Objects.requireNonNull(
|
||||
getClass().getResource("/images/default_favicon.gif")));
|
||||
Assertions.assertArrayEquals(defaultFavicon, icon);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class Opml {
|
||||
@Test
|
||||
void importExportOpml() {
|
||||
importOpml();
|
||||
String opml = RestAssured.given().get("rest/feed/export").then().statusCode(HttpStatus.SC_OK).extract().asString();
|
||||
Assertions.assertTrue(opml.contains("<title>admin subscriptions in CommaFeed</title>"));
|
||||
}
|
||||
@Nested
|
||||
class Opml {
|
||||
@Test
|
||||
void importExportOpml() {
|
||||
importOpml();
|
||||
String opml =
|
||||
RestAssured.given()
|
||||
.get("rest/feed/export")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.asString();
|
||||
Assertions.assertTrue(opml.contains("<title>admin subscriptions in CommaFeed</title>"));
|
||||
}
|
||||
|
||||
void importOpml() {
|
||||
InputStream stream = Objects.requireNonNull(getClass().getResourceAsStream("/opml/opml_v2.0.xml"));
|
||||
void importOpml() {
|
||||
InputStream stream =
|
||||
Objects.requireNonNull(getClass().getResourceAsStream("/opml/opml_v2.0.xml"));
|
||||
|
||||
RestAssured.given()
|
||||
.multiPart("file", "opml_v2.0.xml", stream, MediaType.MULTIPART_FORM_DATA)
|
||||
.post("rest/feed/import")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
}
|
||||
}
|
||||
RestAssured.given()
|
||||
.multiPart("file", "opml_v2.0.xml", stream, MediaType.MULTIPART_FORM_DATA)
|
||||
.post("rest/feed/import")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class Filter {
|
||||
@Test
|
||||
void filterEntriesOnNewFeedItems() throws IOException {
|
||||
// subscribe and wait for initial 2 entries
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
Entries initialEntries = getFeedEntries(subscriptionId);
|
||||
Assertions.assertEquals(2, initialEntries.getEntries().size());
|
||||
@Nested
|
||||
class Filter {
|
||||
@Test
|
||||
void filterEntriesOnNewFeedItems() throws IOException {
|
||||
// subscribe and wait for initial 2 entries
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
Entries initialEntries = getFeedEntries(subscriptionId);
|
||||
Assertions.assertEquals(2, initialEntries.getEntries().size());
|
||||
|
||||
// set up a filter that excludes entries with "item 4" in the title
|
||||
Subscription subscription = getSubscription(subscriptionId);
|
||||
FeedModificationRequest req = new FeedModificationRequest();
|
||||
req.setId(subscriptionId);
|
||||
req.setName(subscription.getName());
|
||||
req.setCategoryId(subscription.getCategoryId());
|
||||
req.setPosition(subscription.getPosition());
|
||||
req.setFilter("!titleLower.contains('item 4')");
|
||||
RestAssured.given().body(req).contentType(ContentType.JSON).post("rest/feed/modify").then().statusCode(HttpStatus.SC_OK);
|
||||
// set up a filter that excludes entries with "item 4" in the title
|
||||
Subscription subscription = getSubscription(subscriptionId);
|
||||
FeedModificationRequest req = new FeedModificationRequest();
|
||||
req.setId(subscriptionId);
|
||||
req.setName(subscription.getName());
|
||||
req.setCategoryId(subscription.getCategoryId());
|
||||
req.setPosition(subscription.getPosition());
|
||||
req.setFilter("!titleLower.contains('item 4')");
|
||||
RestAssured.given()
|
||||
.body(req)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/feed/modify")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
|
||||
// verify filter is set
|
||||
subscription = getSubscription(subscriptionId);
|
||||
Assertions.assertEquals("!titleLower.contains('item 4')", subscription.getFilter());
|
||||
// verify filter is set
|
||||
subscription = getSubscription(subscriptionId);
|
||||
Assertions.assertEquals("!titleLower.contains('item 4')", subscription.getFilter());
|
||||
|
||||
// feed now returns 2 more entries (Item 3 and Item 4)
|
||||
feedNowReturnsMoreEntries();
|
||||
forceRefreshAllFeeds();
|
||||
// feed now returns 2 more entries (Item 3 and Item 4)
|
||||
feedNowReturnsMoreEntries();
|
||||
forceRefreshAllFeeds();
|
||||
|
||||
// wait for new entries to be fetched
|
||||
Awaitility.await().atMost(Duration.ofSeconds(15)).until(() -> getCategoryEntries("all"), e -> e.getEntries().size() == 4);
|
||||
|
||||
// verify that Item 4 was marked as read because it matches the filter
|
||||
Entries unreadEntries = RestAssured.given()
|
||||
.get("rest/feed/entries?id={id}&readType=unread", subscriptionId)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(Entries.class);
|
||||
Assertions.assertEquals(3, unreadEntries.getEntries().size());
|
||||
Assertions.assertTrue(unreadEntries.getEntries().stream().noneMatch(e -> e.getTitle().toLowerCase().contains("item 4")),
|
||||
"Item 4 should be filtered out (marked as read)");
|
||||
}
|
||||
}
|
||||
// wait for new entries to be fetched
|
||||
Awaitility.await()
|
||||
.atMost(Duration.ofSeconds(15))
|
||||
.until(() -> getCategoryEntries("all"), e -> e.getEntries().size() == 4);
|
||||
|
||||
// verify that Item 4 was marked as read because it matches the filter
|
||||
Entries unreadEntries =
|
||||
RestAssured.given()
|
||||
.get("rest/feed/entries?id={id}&readType=unread", subscriptionId)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(Entries.class);
|
||||
Assertions.assertEquals(3, unreadEntries.getEntries().size());
|
||||
Assertions.assertTrue(
|
||||
unreadEntries.getEntries().stream()
|
||||
.noneMatch(e -> e.getTitle().toLowerCase().contains("item 4")),
|
||||
"Item 4 should be filtered out (marked as read)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
package com.commafeed.integration.rest;
|
||||
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.backend.Digests;
|
||||
import com.commafeed.frontend.model.Entry;
|
||||
@@ -15,189 +9,247 @@ import com.commafeed.frontend.model.request.StarRequest;
|
||||
import com.commafeed.frontend.resource.fever.FeverResponse;
|
||||
import com.commafeed.frontend.resource.fever.FeverResponse.FeverItem;
|
||||
import com.commafeed.integration.BaseIT;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
import io.restassured.specification.RequestSpecification;
|
||||
import lombok.Setter;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@QuarkusTest
|
||||
class FeverIT extends BaseIT {
|
||||
|
||||
private FeverClient client;
|
||||
private FeverClient client;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication = RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication =
|
||||
RestAssured.preemptive()
|
||||
.basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
|
||||
// create api key
|
||||
ProfileModificationRequest req = new ProfileModificationRequest();
|
||||
req.setCurrentPassword(TestConstants.ADMIN_PASSWORD);
|
||||
req.setNewApiKey(true);
|
||||
RestAssured.given().body(req).contentType(ContentType.JSON).post("rest/user/profile").then().statusCode(HttpStatus.SC_OK);
|
||||
// create api key
|
||||
ProfileModificationRequest req = new ProfileModificationRequest();
|
||||
req.setCurrentPassword(TestConstants.ADMIN_PASSWORD);
|
||||
req.setNewApiKey(true);
|
||||
RestAssured.given()
|
||||
.body(req)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/user/profile")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
|
||||
// retrieve api key
|
||||
UserModel user = RestAssured.given().get("rest/user/profile").then().statusCode(HttpStatus.SC_OK).extract().as(UserModel.class);
|
||||
this.client = new FeverClient(user.getId(), user.getApiKey());
|
||||
}
|
||||
// retrieve api key
|
||||
UserModel user =
|
||||
RestAssured.given()
|
||||
.get("rest/user/profile")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(UserModel.class);
|
||||
this.client = new FeverClient(user.getId(), user.getApiKey());
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
RestAssured.reset();
|
||||
}
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
RestAssured.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
void invalidApiKey() {
|
||||
client.apiKey = "invalid-key";
|
||||
@Test
|
||||
void invalidApiKey() {
|
||||
client.apiKey = "invalid-key";
|
||||
|
||||
FeverResponse response = client.execute("feeds");
|
||||
Assertions.assertFalse(response.isAuth());
|
||||
}
|
||||
FeverResponse response = client.execute("feeds");
|
||||
Assertions.assertFalse(response.isAuth());
|
||||
}
|
||||
|
||||
@Test
|
||||
void validApiKey() {
|
||||
FeverResponse response = client.execute("feeds");
|
||||
Assertions.assertTrue(response.isAuth());
|
||||
}
|
||||
@Test
|
||||
void validApiKey() {
|
||||
FeverResponse response = client.execute("feeds");
|
||||
Assertions.assertTrue(response.isAuth());
|
||||
}
|
||||
|
||||
@Test
|
||||
void feeds() {
|
||||
subscribe(getFeedUrl());
|
||||
FeverResponse feverResponse = client.execute("feeds");
|
||||
Assertions.assertEquals(1, feverResponse.getFeeds().size());
|
||||
}
|
||||
@Test
|
||||
void feeds() {
|
||||
subscribe(getFeedUrl());
|
||||
FeverResponse feverResponse = client.execute("feeds");
|
||||
Assertions.assertEquals(1, feverResponse.getFeeds().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void unreadEntries() {
|
||||
subscribeAndWaitForEntries(getFeedUrl());
|
||||
FeverResponse feverResponse = client.execute("unread_item_ids");
|
||||
Assertions.assertEquals(2, feverResponse.getUnreadItemIds().size());
|
||||
}
|
||||
@Test
|
||||
void unreadEntries() {
|
||||
subscribeAndWaitForEntries(getFeedUrl());
|
||||
FeverResponse feverResponse = client.execute("unread_item_ids");
|
||||
Assertions.assertEquals(2, feverResponse.getUnreadItemIds().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void entries() {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
FeverResponse feverResponse = client.execute("items");
|
||||
Assertions.assertEquals(2, feverResponse.getItems().size());
|
||||
@Test
|
||||
void entries() {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
FeverResponse feverResponse = client.execute("items");
|
||||
Assertions.assertEquals(2, feverResponse.getItems().size());
|
||||
|
||||
FeverItem item = feverResponse.getItems().getFirst();
|
||||
Assertions.assertEquals(subscriptionId, item.getFeedId());
|
||||
Assertions.assertEquals("Item 2", item.getTitle());
|
||||
Assertions.assertEquals("Item 2 description", item.getHtml());
|
||||
Assertions.assertEquals("https://hostname.local/commafeed/2", item.getUrl());
|
||||
Assertions.assertFalse(item.isSaved());
|
||||
Assertions.assertFalse(item.isRead());
|
||||
}
|
||||
FeverItem item = feverResponse.getItems().getFirst();
|
||||
Assertions.assertEquals(subscriptionId, item.getFeedId());
|
||||
Assertions.assertEquals("Item 2", item.getTitle());
|
||||
Assertions.assertEquals("Item 2 description", item.getHtml());
|
||||
Assertions.assertEquals("https://hostname.local/commafeed/2", item.getUrl());
|
||||
Assertions.assertFalse(item.isSaved());
|
||||
Assertions.assertFalse(item.isRead());
|
||||
}
|
||||
|
||||
@Test
|
||||
void entriesByIds() {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
Entry entry = getFeedEntries(subscriptionId).getEntries().getFirst();
|
||||
@Test
|
||||
void entriesByIds() {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
Entry entry = getFeedEntries(subscriptionId).getEntries().getFirst();
|
||||
|
||||
FeverResponse feverResponse = client.execute("items", new Param("with_ids", entry.getId()));
|
||||
Assertions.assertEquals(1, feverResponse.getItems().size());
|
||||
}
|
||||
FeverResponse feverResponse = client.execute("items", new Param("with_ids", entry.getId()));
|
||||
Assertions.assertEquals(1, feverResponse.getItems().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void savedEntries() {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
Entry entry = getFeedEntries(subscriptionId).getEntries().getFirst();
|
||||
@Test
|
||||
void savedEntries() {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
Entry entry = getFeedEntries(subscriptionId).getEntries().getFirst();
|
||||
|
||||
StarRequest starRequest = new StarRequest();
|
||||
starRequest.setId(entry.getId());
|
||||
starRequest.setFeedId(subscriptionId);
|
||||
starRequest.setStarred(true);
|
||||
RestAssured.given().body(starRequest).contentType(ContentType.JSON).post("rest/entry/star");
|
||||
StarRequest starRequest = new StarRequest();
|
||||
starRequest.setId(entry.getId());
|
||||
starRequest.setFeedId(subscriptionId);
|
||||
starRequest.setStarred(true);
|
||||
RestAssured.given().body(starRequest).contentType(ContentType.JSON).post("rest/entry/star");
|
||||
|
||||
FeverResponse feverResponse = client.execute("saved_item_ids");
|
||||
Assertions.assertEquals(1, feverResponse.getSavedItemIds().size());
|
||||
}
|
||||
FeverResponse feverResponse = client.execute("saved_item_ids");
|
||||
Assertions.assertEquals(1, feverResponse.getSavedItemIds().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void markEntry() {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
Entry entry = getFeedEntries(subscriptionId).getEntries().getFirst();
|
||||
@Test
|
||||
void markEntry() {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
Entry entry = getFeedEntries(subscriptionId).getEntries().getFirst();
|
||||
|
||||
client.execute("_", new Param("mark", "item"), new Param("id", entry.getId()), new Param("as", "read"));
|
||||
Assertions.assertEquals(1, getFeedEntries(subscriptionId).getEntries().stream().filter(Entry::isRead).count());
|
||||
client.execute(
|
||||
"_",
|
||||
new Param("mark", "item"),
|
||||
new Param("id", entry.getId()),
|
||||
new Param("as", "read"));
|
||||
Assertions.assertEquals(
|
||||
1,
|
||||
getFeedEntries(subscriptionId).getEntries().stream().filter(Entry::isRead).count());
|
||||
|
||||
client.execute("_", new Param("mark", "item"), new Param("id", entry.getId()), new Param("as", "unread"));
|
||||
Assertions.assertEquals(0, getFeedEntries(subscriptionId).getEntries().stream().filter(Entry::isRead).count());
|
||||
}
|
||||
client.execute(
|
||||
"_",
|
||||
new Param("mark", "item"),
|
||||
new Param("id", entry.getId()),
|
||||
new Param("as", "unread"));
|
||||
Assertions.assertEquals(
|
||||
0,
|
||||
getFeedEntries(subscriptionId).getEntries().stream().filter(Entry::isRead).count());
|
||||
}
|
||||
|
||||
@Test
|
||||
void markFeed() {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
@Test
|
||||
void markFeed() {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
|
||||
client.execute("_", new Param("mark", "feed"), new Param("id", String.valueOf(subscriptionId)), new Param("as", "read"));
|
||||
client.execute(
|
||||
"_",
|
||||
new Param("mark", "feed"),
|
||||
new Param("id", String.valueOf(subscriptionId)),
|
||||
new Param("as", "read"));
|
||||
|
||||
Assertions.assertTrue(getFeedEntries(subscriptionId).getEntries().stream().allMatch(Entry::isRead));
|
||||
}
|
||||
Assertions.assertTrue(
|
||||
getFeedEntries(subscriptionId).getEntries().stream().allMatch(Entry::isRead));
|
||||
}
|
||||
|
||||
@Test
|
||||
void markCategory() {
|
||||
String categoryId = createCategory("test-category");
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl(), categoryId);
|
||||
@Test
|
||||
void markCategory() {
|
||||
String categoryId = createCategory("test-category");
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl(), categoryId);
|
||||
|
||||
client.execute("_", new Param("mark", "group"), new Param("id", String.valueOf(categoryId)), new Param("as", "read"));
|
||||
client.execute(
|
||||
"_",
|
||||
new Param("mark", "group"),
|
||||
new Param("id", String.valueOf(categoryId)),
|
||||
new Param("as", "read"));
|
||||
|
||||
Assertions.assertTrue(getFeedEntries(subscriptionId).getEntries().stream().allMatch(Entry::isRead));
|
||||
}
|
||||
Assertions.assertTrue(
|
||||
getFeedEntries(subscriptionId).getEntries().stream().allMatch(Entry::isRead));
|
||||
}
|
||||
|
||||
@Test
|
||||
void tagEntry() {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
Entry entry = getFeedEntries(subscriptionId).getEntries().getFirst();
|
||||
@Test
|
||||
void tagEntry() {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
Entry entry = getFeedEntries(subscriptionId).getEntries().getFirst();
|
||||
|
||||
client.execute("_", new Param("mark", "item"), new Param("id", entry.getId()), new Param("as", "saved"));
|
||||
Assertions.assertEquals(1, getFeedEntries(subscriptionId).getEntries().stream().filter(Entry::isStarred).count());
|
||||
client.execute(
|
||||
"_",
|
||||
new Param("mark", "item"),
|
||||
new Param("id", entry.getId()),
|
||||
new Param("as", "saved"));
|
||||
Assertions.assertEquals(
|
||||
1,
|
||||
getFeedEntries(subscriptionId).getEntries().stream()
|
||||
.filter(Entry::isStarred)
|
||||
.count());
|
||||
|
||||
client.execute("_", new Param("mark", "item"), new Param("id", entry.getId()), new Param("as", "unsaved"));
|
||||
Assertions.assertEquals(0, getFeedEntries(subscriptionId).getEntries().stream().filter(Entry::isStarred).count());
|
||||
}
|
||||
client.execute(
|
||||
"_",
|
||||
new Param("mark", "item"),
|
||||
new Param("id", entry.getId()),
|
||||
new Param("as", "unsaved"));
|
||||
Assertions.assertEquals(
|
||||
0,
|
||||
getFeedEntries(subscriptionId).getEntries().stream()
|
||||
.filter(Entry::isStarred)
|
||||
.count());
|
||||
}
|
||||
|
||||
@Test
|
||||
void groups() {
|
||||
createCategory("category-1");
|
||||
FeverResponse feverResponse = client.execute("groups");
|
||||
Assertions.assertEquals(1, feverResponse.getGroups().size());
|
||||
Assertions.assertEquals("category-1", feverResponse.getGroups().getFirst().getTitle());
|
||||
}
|
||||
@Test
|
||||
void groups() {
|
||||
createCategory("category-1");
|
||||
FeverResponse feverResponse = client.execute("groups");
|
||||
Assertions.assertEquals(1, feverResponse.getGroups().size());
|
||||
Assertions.assertEquals("category-1", feverResponse.getGroups().getFirst().getTitle());
|
||||
}
|
||||
|
||||
@Test
|
||||
void links() {
|
||||
FeverResponse feverResponse = client.execute("links");
|
||||
Assertions.assertTrue(feverResponse.getLinks().isEmpty());
|
||||
}
|
||||
@Test
|
||||
void links() {
|
||||
FeverResponse feverResponse = client.execute("links");
|
||||
Assertions.assertTrue(feverResponse.getLinks().isEmpty());
|
||||
}
|
||||
|
||||
private static class FeverClient {
|
||||
private final Long userId;
|
||||
private static class FeverClient {
|
||||
private final Long userId;
|
||||
|
||||
@Setter
|
||||
private String apiKey;
|
||||
@Setter private String apiKey;
|
||||
|
||||
public FeverClient(Long userId, String apiKey) {
|
||||
this.userId = userId;
|
||||
this.apiKey = apiKey;
|
||||
}
|
||||
public FeverClient(Long userId, String apiKey) {
|
||||
this.userId = userId;
|
||||
this.apiKey = apiKey;
|
||||
}
|
||||
|
||||
private FeverResponse execute(String action, Param... params) {
|
||||
RequestSpecification spec = RestAssured.given()
|
||||
.auth()
|
||||
.none()
|
||||
.formParam("api_key", Digests.md5Hex("admin:" + apiKey))
|
||||
.formParam(action, 1);
|
||||
private FeverResponse execute(String action, Param... params) {
|
||||
RequestSpecification spec =
|
||||
RestAssured.given()
|
||||
.auth()
|
||||
.none()
|
||||
.formParam("api_key", Digests.md5Hex("admin:" + apiKey))
|
||||
.formParam(action, 1);
|
||||
|
||||
for (Param param : params) {
|
||||
spec.formParam(param.name(), param.value());
|
||||
}
|
||||
for (Param param : params) {
|
||||
spec.formParam(param.name(), param.value());
|
||||
}
|
||||
|
||||
return spec.post("rest/fever/user/{userId}", userId).then().statusCode(HttpStatus.SC_OK).extract().as(FeverResponse.class);
|
||||
return spec.post("rest/fever/user/{userId}", userId)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.as(FeverResponse.class);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private record Param(String name, String value) {}
|
||||
private record Param(String name, String value) {}
|
||||
}
|
||||
|
||||
@@ -1,29 +1,32 @@
|
||||
package com.commafeed.integration.rest;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.commafeed.frontend.model.ServerInfo;
|
||||
import com.commafeed.integration.BaseIT;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@QuarkusTest
|
||||
class ServerIT extends BaseIT {
|
||||
|
||||
@Test
|
||||
void getServerInfos() {
|
||||
ServerInfo serverInfos = RestAssured.given().get("/rest/server/get").then().statusCode(200).extract().as(ServerInfo.class);
|
||||
Assertions.assertTrue(serverInfos.isAllowRegistrations());
|
||||
Assertions.assertTrue(serverInfos.isSmtpEnabled());
|
||||
Assertions.assertTrue(serverInfos.isDemoAccountEnabled());
|
||||
Assertions.assertTrue(serverInfos.isWebsocketEnabled());
|
||||
Assertions.assertEquals(900000, serverInfos.getWebsocketPingInterval());
|
||||
Assertions.assertEquals(30000, serverInfos.getTreeReloadInterval());
|
||||
Assertions.assertEquals(60000, serverInfos.getForceRefreshCooldownDuration());
|
||||
Assertions.assertEquals(4, serverInfos.getMinimumPasswordLength());
|
||||
Assertions.assertTrue(serverInfos.isPushNotificationsEnabled());
|
||||
|
||||
}
|
||||
@Test
|
||||
void getServerInfos() {
|
||||
ServerInfo serverInfos =
|
||||
RestAssured.given()
|
||||
.get("/rest/server/get")
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.extract()
|
||||
.as(ServerInfo.class);
|
||||
Assertions.assertTrue(serverInfos.isAllowRegistrations());
|
||||
Assertions.assertTrue(serverInfos.isSmtpEnabled());
|
||||
Assertions.assertTrue(serverInfos.isDemoAccountEnabled());
|
||||
Assertions.assertTrue(serverInfos.isWebsocketEnabled());
|
||||
Assertions.assertEquals(900000, serverInfos.getWebsocketPingInterval());
|
||||
Assertions.assertEquals(30000, serverInfos.getTreeReloadInterval());
|
||||
Assertions.assertEquals(60000, serverInfos.getForceRefreshCooldownDuration());
|
||||
Assertions.assertEquals(4, serverInfos.getMinimumPasswordLength());
|
||||
Assertions.assertTrue(serverInfos.isPushNotificationsEnabled());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
package com.commafeed.integration.rest;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.Settings;
|
||||
import com.commafeed.frontend.model.request.PasswordResetConfirmationRequest;
|
||||
import com.commafeed.frontend.model.request.PasswordResetRequest;
|
||||
import com.commafeed.integration.BaseIT;
|
||||
import io.quarkus.mailer.MockMailbox;
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
import io.vertx.ext.mail.MailMessage;
|
||||
import jakarta.inject.Inject;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
@@ -13,88 +21,97 @@ import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.Settings;
|
||||
import com.commafeed.frontend.model.request.PasswordResetConfirmationRequest;
|
||||
import com.commafeed.frontend.model.request.PasswordResetRequest;
|
||||
import com.commafeed.integration.BaseIT;
|
||||
|
||||
import io.quarkus.mailer.MockMailbox;
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
import io.vertx.ext.mail.MailMessage;
|
||||
|
||||
@QuarkusTest
|
||||
class UserIT extends BaseIT {
|
||||
|
||||
@Inject
|
||||
MockMailbox mailbox;
|
||||
@Inject MockMailbox mailbox;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication = RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication =
|
||||
RestAssured.preemptive()
|
||||
.basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
|
||||
mailbox.clear();
|
||||
}
|
||||
mailbox.clear();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
RestAssured.reset();
|
||||
}
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
RestAssured.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
void resetPassword() {
|
||||
PasswordResetRequest req = new PasswordResetRequest();
|
||||
req.setEmail("admin@commafeed.com");
|
||||
RestAssured.given().body(req).contentType(ContentType.JSON).post("rest/user/passwordReset").then().statusCode(200);
|
||||
@Test
|
||||
void resetPassword() {
|
||||
PasswordResetRequest req = new PasswordResetRequest();
|
||||
req.setEmail("admin@commafeed.com");
|
||||
RestAssured.given()
|
||||
.body(req)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/user/passwordReset")
|
||||
.then()
|
||||
.statusCode(200);
|
||||
|
||||
List<MailMessage> mails = mailbox.getMailMessagesSentTo("admin@commafeed.com");
|
||||
Assertions.assertEquals(1, mails.size());
|
||||
List<MailMessage> mails = mailbox.getMailMessagesSentTo("admin@commafeed.com");
|
||||
Assertions.assertEquals(1, mails.size());
|
||||
|
||||
MailMessage message = mails.getFirst();
|
||||
Assertions.assertEquals("CommaFeed - Password recovery", message.getSubject());
|
||||
Assertions.assertTrue(message.getHtml().startsWith("You asked for password recovery for account 'admin'"));
|
||||
Assertions.assertEquals("admin@commafeed.com", message.getTo().getFirst());
|
||||
MailMessage message = mails.getFirst();
|
||||
Assertions.assertEquals("CommaFeed - Password recovery", message.getSubject());
|
||||
Assertions.assertTrue(
|
||||
message.getHtml()
|
||||
.startsWith("You asked for password recovery for account 'admin'"));
|
||||
Assertions.assertEquals("admin@commafeed.com", message.getTo().getFirst());
|
||||
|
||||
Element a = Jsoup.parse(message.getHtml()).select("a").getFirst();
|
||||
String link = a.attr("href");
|
||||
Element a = Jsoup.parse(message.getHtml()).select("a").getFirst();
|
||||
String link = a.attr("href");
|
||||
|
||||
String email = null;
|
||||
String token = null;
|
||||
String queryString = link.substring(link.indexOf('?') + 1);
|
||||
for (String param : queryString.split("&")) {
|
||||
String[] keyValue = param.split("=");
|
||||
if ("email".equals(keyValue[0])) {
|
||||
email = URLDecoder.decode(keyValue[1], StandardCharsets.UTF_8);
|
||||
} else if ("token".equals(keyValue[0])) {
|
||||
token = URLDecoder.decode(keyValue[1], StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
String email = null;
|
||||
String token = null;
|
||||
String queryString = link.substring(link.indexOf('?') + 1);
|
||||
for (String param : queryString.split("&")) {
|
||||
String[] keyValue = param.split("=");
|
||||
if ("email".equals(keyValue[0])) {
|
||||
email = URLDecoder.decode(keyValue[1], StandardCharsets.UTF_8);
|
||||
} else if ("token".equals(keyValue[0])) {
|
||||
token = URLDecoder.decode(keyValue[1], StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
|
||||
Assertions.assertNotNull(email);
|
||||
Assertions.assertNotNull(token);
|
||||
Assertions.assertTrue(link.contains("#/passwordReset?"));
|
||||
Assertions.assertNotNull(email);
|
||||
Assertions.assertNotNull(token);
|
||||
Assertions.assertTrue(link.contains("#/passwordReset?"));
|
||||
|
||||
String newPassword = "MyNewPassword123!";
|
||||
PasswordResetConfirmationRequest confirmReq = new PasswordResetConfirmationRequest();
|
||||
confirmReq.setEmail(email);
|
||||
confirmReq.setToken(token);
|
||||
confirmReq.setPassword(newPassword);
|
||||
RestAssured.given().body(confirmReq).contentType(ContentType.JSON).post("rest/user/passwordResetCallback").then().statusCode(200);
|
||||
String newPassword = "MyNewPassword123!";
|
||||
PasswordResetConfirmationRequest confirmReq = new PasswordResetConfirmationRequest();
|
||||
confirmReq.setEmail(email);
|
||||
confirmReq.setToken(token);
|
||||
confirmReq.setPassword(newPassword);
|
||||
RestAssured.given()
|
||||
.body(confirmReq)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/user/passwordResetCallback")
|
||||
.then()
|
||||
.statusCode(200);
|
||||
|
||||
RestAssured.authentication = RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, newPassword);
|
||||
RestAssured.given().get("rest/user/settings").then().statusCode(200);
|
||||
}
|
||||
RestAssured.authentication =
|
||||
RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, newPassword);
|
||||
RestAssured.given().get("rest/user/settings").then().statusCode(200);
|
||||
}
|
||||
|
||||
@Test
|
||||
void saveSettings() {
|
||||
Settings settings = RestAssured.given().get("rest/user/settings").then().extract().as(Settings.class);
|
||||
settings.setLanguage("test");
|
||||
RestAssured.given().body(settings).contentType(ContentType.JSON).post("rest/user/settings").then().statusCode(200);
|
||||
@Test
|
||||
void saveSettings() {
|
||||
Settings settings =
|
||||
RestAssured.given().get("rest/user/settings").then().extract().as(Settings.class);
|
||||
settings.setLanguage("test");
|
||||
RestAssured.given()
|
||||
.body(settings)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/user/settings")
|
||||
.then()
|
||||
.statusCode(200);
|
||||
|
||||
Settings updatedSettings = RestAssured.given().get("rest/user/settings").then().extract().as(Settings.class);
|
||||
Assertions.assertEquals("test", updatedSettings.getLanguage());
|
||||
}
|
||||
Settings updatedSettings =
|
||||
RestAssured.given().get("rest/user/settings").then().extract().as(Settings.class);
|
||||
Assertions.assertEquals("test", updatedSettings.getLanguage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +1,64 @@
|
||||
package com.commafeed.integration.servlet;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.Settings;
|
||||
import com.commafeed.integration.BaseIT;
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.frontend.model.Settings;
|
||||
import com.commafeed.integration.BaseIT;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
|
||||
@QuarkusTest
|
||||
class CustomCodeIT extends BaseIT {
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication = RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication =
|
||||
RestAssured.preemptive()
|
||||
.basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
RestAssured.reset();
|
||||
}
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
RestAssured.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
// get settings
|
||||
Settings settings = RestAssured.given().get("rest/user/settings").then().statusCode(200).extract().as(Settings.class);
|
||||
@Test
|
||||
void test() {
|
||||
// get settings
|
||||
Settings settings =
|
||||
RestAssured.given()
|
||||
.get("rest/user/settings")
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.extract()
|
||||
.as(Settings.class);
|
||||
|
||||
// update settings
|
||||
settings.setCustomJs("custom-js");
|
||||
settings.setCustomCss("custom-css");
|
||||
RestAssured.given().body(settings).contentType(ContentType.JSON).post("rest/user/settings").then().statusCode(HttpStatus.SC_OK);
|
||||
// update settings
|
||||
settings.setCustomJs("custom-js");
|
||||
settings.setCustomCss("custom-css");
|
||||
RestAssured.given()
|
||||
.body(settings)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/user/settings")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
|
||||
// check custom code servlets
|
||||
RestAssured.given().get("custom_js.js").then().statusCode(HttpStatus.SC_OK).body(CoreMatchers.is("custom-js"));
|
||||
RestAssured.given().get("custom_css.css").then().statusCode(HttpStatus.SC_OK).body(CoreMatchers.is("custom-css"));
|
||||
}
|
||||
// check custom code servlets
|
||||
RestAssured.given()
|
||||
.get("custom_js.js")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.body(CoreMatchers.is("custom-js"));
|
||||
RestAssured.given()
|
||||
.get("custom_css.css")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.body(CoreMatchers.is("custom-css"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +1,49 @@
|
||||
package com.commafeed.integration.servlet;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.integration.BaseIT;
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.Headers;
|
||||
import jakarta.ws.rs.core.HttpHeaders;
|
||||
import java.net.HttpCookie;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import jakarta.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.integration.BaseIT;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.Headers;
|
||||
|
||||
@QuarkusTest
|
||||
class LogoutIT extends BaseIT {
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
List<HttpCookie> cookies = login();
|
||||
Headers responseHeaders = RestAssured.given()
|
||||
.header(HttpHeaders.COOKIE, cookies.stream().map(HttpCookie::toString).collect(Collectors.joining(";")))
|
||||
.redirects()
|
||||
.follow(false)
|
||||
.get("logout")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_TEMPORARY_REDIRECT)
|
||||
.extract()
|
||||
.headers();
|
||||
@Test
|
||||
void test() {
|
||||
List<HttpCookie> cookies = login();
|
||||
Headers responseHeaders =
|
||||
RestAssured.given()
|
||||
.header(
|
||||
HttpHeaders.COOKIE,
|
||||
cookies.stream()
|
||||
.map(HttpCookie::toString)
|
||||
.collect(Collectors.joining(";")))
|
||||
.redirects()
|
||||
.follow(false)
|
||||
.get("logout")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_TEMPORARY_REDIRECT)
|
||||
.extract()
|
||||
.headers();
|
||||
|
||||
List<String> setCookieHeaders = responseHeaders.getValues(HttpHeaders.SET_COOKIE);
|
||||
Assertions.assertTrue(setCookieHeaders.stream().flatMap(c -> HttpCookie.parse(c).stream()).allMatch(c -> c.getMaxAge() == 0));
|
||||
}
|
||||
List<String> setCookieHeaders = responseHeaders.getValues(HttpHeaders.SET_COOKIE);
|
||||
Assertions.assertTrue(
|
||||
setCookieHeaders.stream()
|
||||
.flatMap(c -> HttpCookie.parse(c).stream())
|
||||
.allMatch(c -> c.getMaxAge() == 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +1,41 @@
|
||||
package com.commafeed.integration.servlet;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.integration.BaseIT;
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import jakarta.ws.rs.core.HttpHeaders;
|
||||
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.commafeed.TestConstants;
|
||||
import com.commafeed.integration.BaseIT;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
|
||||
@QuarkusTest
|
||||
class NextUnreadIT extends BaseIT {
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication = RestAssured.preemptive().basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
initialSetup(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
RestAssured.authentication =
|
||||
RestAssured.preemptive()
|
||||
.basic(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
RestAssured.reset();
|
||||
}
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
RestAssured.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
subscribeAndWaitForEntries(getFeedUrl());
|
||||
|
||||
RestAssured.given()
|
||||
.redirects()
|
||||
.follow(false)
|
||||
.get("next")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_TEMPORARY_REDIRECT)
|
||||
.header(HttpHeaders.LOCATION, "https://hostname.local/commafeed/2");
|
||||
}
|
||||
@Test
|
||||
void test() {
|
||||
subscribeAndWaitForEntries(getFeedUrl());
|
||||
|
||||
RestAssured.given()
|
||||
.redirects()
|
||||
.follow(false)
|
||||
.get("next")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_TEMPORARY_REDIRECT)
|
||||
.header(HttpHeaders.LOCATION, "https://hostname.local/commafeed/2");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
package com.commafeed.integration.servlet;
|
||||
|
||||
import com.commafeed.integration.BaseIT;
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.commafeed.integration.BaseIT;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
|
||||
@QuarkusTest
|
||||
class RobotsTxtIT extends BaseIT {
|
||||
@Test
|
||||
void test() {
|
||||
RestAssured.given().get("robots.txt").then().statusCode(200).body(CoreMatchers.is("User-agent: *\nDisallow: /"));
|
||||
}
|
||||
@Test
|
||||
void test() {
|
||||
RestAssured.given()
|
||||
.get("robots.txt")
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.body(CoreMatchers.is("User-agent: *\nDisallow: /"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user