mirror of
https://github.com/Athou/commafeed.git
synced 2026-03-21 21:37:29 +00:00
add even more integration tests
This commit is contained in:
@@ -105,7 +105,7 @@ export const client = {
|
||||
},
|
||||
admin: {
|
||||
getAllUsers: async () => await axiosInstance.get<UserModel[]>("admin/user/getAll"),
|
||||
saveUser: async (req: AdminSaveUserRequest) => await axiosInstance.post("admin/user/save", req),
|
||||
saveUser: async (req: AdminSaveUserRequest) => await axiosInstance.post<number>("admin/user/save", req),
|
||||
deleteUser: async (req: IDRequest) => await axiosInstance.post("admin/user/delete", req),
|
||||
getMetrics: async () => await axiosInstance.get<Metrics>("admin/metrics"),
|
||||
},
|
||||
|
||||
@@ -32,6 +32,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Singleton
|
||||
public class YoutubeFaviconFetcher extends AbstractFaviconFetcher {
|
||||
|
||||
private static final String PART_SNIPPET = "snippet";
|
||||
|
||||
private static final JsonPointer CHANNEL_THUMBNAIL_URL = JsonPointer.compile("/items/0/snippet/thumbnails/default/url");
|
||||
private static final JsonPointer PLAYLIST_CHANNEL_ID = JsonPointer.compile("/items/0/snippet/channelId");
|
||||
|
||||
@@ -86,7 +88,7 @@ public class YoutubeFaviconFetcher extends AbstractFaviconFetcher {
|
||||
bytes = iconResult.getContent();
|
||||
contentType = iconResult.getContentType();
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to retrieve YouTube icon", e);
|
||||
log.debug("Failed to retrieve YouTube icon", e);
|
||||
}
|
||||
|
||||
if (!isValidIconResponse(bytes, contentType)) {
|
||||
@@ -98,7 +100,7 @@ public class YoutubeFaviconFetcher extends AbstractFaviconFetcher {
|
||||
private byte[] fetchForUser(String googleAuthKey, String userId)
|
||||
throws IOException, NotModifiedException, TooManyRequestsException, HostNotAllowedException, SchemeNotAllowedException {
|
||||
URI uri = UriBuilder.fromUri("https://www.googleapis.com/youtube/v3/channels")
|
||||
.queryParam("part", "snippet")
|
||||
.queryParam("part", PART_SNIPPET)
|
||||
.queryParam("key", googleAuthKey)
|
||||
.queryParam("forUsername", userId)
|
||||
.build();
|
||||
@@ -108,7 +110,7 @@ public class YoutubeFaviconFetcher extends AbstractFaviconFetcher {
|
||||
private byte[] fetchForChannel(String googleAuthKey, String channelId)
|
||||
throws IOException, NotModifiedException, TooManyRequestsException, HostNotAllowedException, SchemeNotAllowedException {
|
||||
URI uri = UriBuilder.fromUri("https://www.googleapis.com/youtube/v3/channels")
|
||||
.queryParam("part", "snippet")
|
||||
.queryParam("part", PART_SNIPPET)
|
||||
.queryParam("key", googleAuthKey)
|
||||
.queryParam("id", channelId)
|
||||
.build();
|
||||
@@ -118,7 +120,7 @@ public class YoutubeFaviconFetcher extends AbstractFaviconFetcher {
|
||||
private byte[] fetchForPlaylist(String googleAuthKey, String playlistId)
|
||||
throws IOException, NotModifiedException, TooManyRequestsException, HostNotAllowedException, SchemeNotAllowedException {
|
||||
URI uri = UriBuilder.fromUri("https://www.googleapis.com/youtube/v3/playlists")
|
||||
.queryParam("part", "snippet")
|
||||
.queryParam("part", PART_SNIPPET)
|
||||
.queryParam("key", googleAuthKey)
|
||||
.queryParam("id", playlistId)
|
||||
.build();
|
||||
|
||||
@@ -26,10 +26,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
public class FeedUtils {
|
||||
|
||||
public static String truncate(String string, int length) {
|
||||
if (string != null) {
|
||||
string = string.substring(0, Math.min(length, string.length()));
|
||||
}
|
||||
return string;
|
||||
return StringUtils.truncate(string, length);
|
||||
}
|
||||
|
||||
public static boolean isRTL(String title, String content) {
|
||||
|
||||
@@ -14,7 +14,6 @@ import jakarta.persistence.Table;
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.hibernate.annotations.JdbcTypeCode;
|
||||
|
||||
import com.commafeed.backend.feed.FeedUtils;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import lombok.Getter;
|
||||
@@ -99,15 +98,4 @@ public class FeedEntryContent extends AbstractModel {
|
||||
.append(mediaThumbnailHeight, c.mediaThumbnailHeight)
|
||||
.build();
|
||||
}
|
||||
|
||||
public boolean isRTL() {
|
||||
if (direction == Direction.RTL) {
|
||||
return true;
|
||||
} else if (direction == Direction.LTR) {
|
||||
return false;
|
||||
} else {
|
||||
// detect on the fly for content that was inserted before the direction field was added
|
||||
return FeedUtils.isRTL(title, content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ public class Entry implements Serializable {
|
||||
entry.setTags(status.getTags().stream().map(FeedEntryTag::getName).toList());
|
||||
|
||||
if (content != null) {
|
||||
entry.setRtl(content.isRTL());
|
||||
entry.setRtl(content.getDirection() == FeedEntryContent.Direction.RTL);
|
||||
entry.setTitle(content.getTitle());
|
||||
entry.setContent(proxyImages ? FeedUtils.proxyImages(content.getContent()) : content.getContent());
|
||||
entry.setAuthor(content.getAuthor());
|
||||
|
||||
@@ -80,7 +80,7 @@ public class AdminREST {
|
||||
roles.add(Role.ADMIN);
|
||||
}
|
||||
try {
|
||||
userService.register(req.getName(), req.getPassword(), req.getEmail(), roles, true);
|
||||
id = userService.register(req.getName(), req.getPassword(), req.getEmail(), roles, true).getId();
|
||||
} catch (Exception e) {
|
||||
return Response.status(Status.CONFLICT).entity(e.getMessage()).build();
|
||||
}
|
||||
@@ -113,7 +113,7 @@ public class AdminREST {
|
||||
}
|
||||
|
||||
}
|
||||
return Response.ok().build();
|
||||
return Response.ok(id).build();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package com.commafeed.tools;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
@@ -8,6 +11,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import com.commafeed.CommaFeedConfiguration;
|
||||
|
||||
import io.quarkus.annotation.processor.Outputs;
|
||||
@@ -31,16 +36,22 @@ public class CommaFeedPropertiesGenerator {
|
||||
private final List<String> lines = new ArrayList<>();
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new CommaFeedPropertiesGenerator().generate(args);
|
||||
}
|
||||
|
||||
private void generate(String[] args) throws IOException {
|
||||
Path targetPath = Paths.get(args[0]);
|
||||
|
||||
ResolvedModel resolvedModel = JacksonMappers.yamlObjectReader()
|
||||
.readValue(targetPath.resolve(Outputs.QUARKUS_CONFIG_DOC_MODEL).toFile(), ResolvedModel.class);
|
||||
JavadocElements javadocElements = JacksonMappers.yamlObjectReader()
|
||||
.readValue(targetPath.resolve(Outputs.QUARKUS_CONFIG_DOC_JAVADOC).toFile(), JavadocElements.class);
|
||||
Path modelPath = targetPath.resolve(Outputs.QUARKUS_CONFIG_DOC_MODEL);
|
||||
Path javadocPath = targetPath.resolve(Outputs.QUARKUS_CONFIG_DOC_JAVADOC);
|
||||
Path outputPath = targetPath.resolve("quarkus-generated-doc").resolve("application.properties");
|
||||
|
||||
try (InputStream model = Files.newInputStream(modelPath);
|
||||
InputStream javadoc = Files.newInputStream(javadocPath);
|
||||
OutputStream output = Files.newOutputStream(outputPath)) {
|
||||
new CommaFeedPropertiesGenerator().generate(model, javadoc, output);
|
||||
}
|
||||
}
|
||||
|
||||
void generate(InputStream model, InputStream javadoc, OutputStream output) throws IOException {
|
||||
ResolvedModel resolvedModel = JacksonMappers.yamlObjectReader().readValue(model, ResolvedModel.class);
|
||||
JavadocElements javadocElements = JacksonMappers.yamlObjectReader().readValue(javadoc, JavadocElements.class);
|
||||
|
||||
for (ConfigRoot configRoot : resolvedModel.getConfigRoots()) {
|
||||
for (AbstractConfigItem item : configRoot.getItems()) {
|
||||
@@ -48,7 +59,7 @@ public class CommaFeedPropertiesGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
Files.writeString(targetPath.resolve("quarkus-generated-doc").resolve("application.properties"), String.join("\n", lines));
|
||||
IOUtils.write(String.join("\n", lines), output, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
private void handleAbstractConfigItem(AbstractConfigItem item, JavadocElements javadocElements) {
|
||||
|
||||
@@ -41,10 +41,6 @@ quarkus.native.add-all-charsets=true
|
||||
# fix for https://github.com/Athou/commafeed/issues/1795
|
||||
quarkus.native.additional-build-args=-H:PageSize=65536
|
||||
|
||||
# jacoco
|
||||
## we generate the report ourselves by aggregating the unit tests and integration tests jacoco.exec files
|
||||
quarkus.jacoco.report=false
|
||||
|
||||
|
||||
# dev profile overrides
|
||||
%dev.quarkus.http.port=8083
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
package com.commafeed.backend.favicon;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import com.commafeed.backend.HttpGetter;
|
||||
import com.commafeed.backend.HttpGetter.HttpResult;
|
||||
import com.commafeed.backend.model.Feed;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class FacebookFaviconFetcherTest {
|
||||
|
||||
@Mock
|
||||
private HttpGetter httpGetter;
|
||||
|
||||
private FacebookFaviconFetcher faviconFetcher;
|
||||
|
||||
@BeforeEach
|
||||
void init() {
|
||||
faviconFetcher = new FacebookFaviconFetcher(httpGetter);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFetchWithValidFacebookUrl() throws Exception {
|
||||
Feed feed = new Feed();
|
||||
feed.setUrl("https://www.facebook.com/something?id=validUserId");
|
||||
|
||||
byte[] iconBytes = new byte[1000];
|
||||
String contentType = "image/png";
|
||||
|
||||
HttpResult httpResult = new HttpResult(iconBytes, contentType, null, null, null, Duration.ZERO);
|
||||
Mockito.when(httpGetter.get("https://graph.facebook.com/validUserId/picture?type=square&height=16")).thenReturn(httpResult);
|
||||
|
||||
Favicon result = faviconFetcher.fetch(feed);
|
||||
|
||||
Assertions.assertNotNull(result);
|
||||
Assertions.assertEquals(iconBytes, result.getIcon());
|
||||
Assertions.assertTrue(result.getMediaType().isCompatible(MediaType.valueOf(contentType)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFetchWithNonFacebookUrl() {
|
||||
Feed feed = new Feed();
|
||||
feed.setUrl("https://example.com");
|
||||
|
||||
Assertions.assertNull(faviconFetcher.fetch(feed));
|
||||
Mockito.verifyNoInteractions(httpGetter);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFetchWithFacebookUrlButNoUserId() {
|
||||
Feed feed = new Feed();
|
||||
feed.setUrl("https://www.facebook.com/something");
|
||||
|
||||
Assertions.assertNull(faviconFetcher.fetch(feed));
|
||||
Mockito.verifyNoInteractions(httpGetter);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFetchWithHttpGetterException() throws Exception {
|
||||
Feed feed = new Feed();
|
||||
feed.setUrl("https://www.facebook.com/something?id=validUserId");
|
||||
|
||||
Mockito.when(httpGetter.get("https://graph.facebook.com/validUserId/picture?type=square&height=16"))
|
||||
.thenThrow(new RuntimeException("Network error"));
|
||||
|
||||
Assertions.assertNull(faviconFetcher.fetch(feed));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFetchWithInvalidIconResponse() throws Exception {
|
||||
Feed feed = new Feed();
|
||||
feed.setUrl("https://www.facebook.com/something?id=validUserId");
|
||||
|
||||
// Create a byte array that's too small
|
||||
byte[] iconBytes = new byte[50];
|
||||
String contentType = "image/png";
|
||||
|
||||
HttpResult httpResult = new HttpResult(iconBytes, contentType, null, null, null, Duration.ZERO);
|
||||
Mockito.when(httpGetter.get("https://graph.facebook.com/validUserId/picture?type=square&height=16")).thenReturn(httpResult);
|
||||
|
||||
Assertions.assertNull(faviconFetcher.fetch(feed));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFetchWithBlacklistedContentType() throws Exception {
|
||||
Feed feed = new Feed();
|
||||
feed.setUrl("https://www.facebook.com/something?id=validUserId");
|
||||
|
||||
byte[] iconBytes = new byte[1000];
|
||||
String contentType = "application/xml"; // Blacklisted content type
|
||||
|
||||
HttpResult httpResult = new HttpResult(iconBytes, contentType, null, null, null, Duration.ZERO);
|
||||
Mockito.when(httpGetter.get("https://graph.facebook.com/validUserId/picture?type=square&height=16")).thenReturn(httpResult);
|
||||
|
||||
Assertions.assertNull(faviconFetcher.fetch(feed));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
package com.commafeed.backend.favicon;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.Optional;
|
||||
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import com.commafeed.CommaFeedConfiguration;
|
||||
import com.commafeed.backend.HttpGetter;
|
||||
import com.commafeed.backend.HttpGetter.HttpResult;
|
||||
import com.commafeed.backend.model.Feed;
|
||||
import com.fasterxml.jackson.core.JsonPointer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class YoutubeFaviconFetcherTest {
|
||||
|
||||
@Mock
|
||||
private HttpGetter httpGetter;
|
||||
|
||||
@Mock
|
||||
private CommaFeedConfiguration config;
|
||||
|
||||
@Mock
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
private YoutubeFaviconFetcher faviconFetcher;
|
||||
|
||||
@BeforeEach
|
||||
void init() {
|
||||
faviconFetcher = new YoutubeFaviconFetcher(httpGetter, config, objectMapper);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFetchWithNonYoutubeUrl() {
|
||||
Feed feed = new Feed();
|
||||
feed.setUrl("https://example.com/feed");
|
||||
|
||||
Assertions.assertNull(faviconFetcher.fetch(feed));
|
||||
Mockito.verifyNoInteractions(httpGetter, objectMapper);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFetchWithNoGoogleAuthKey() {
|
||||
Feed feed = new Feed();
|
||||
feed.setUrl("https://youtube.com/feeds/videos.xml?user=someUser");
|
||||
|
||||
Mockito.when(config.googleAuthKey()).thenReturn(Optional.empty());
|
||||
|
||||
Assertions.assertNull(faviconFetcher.fetch(feed));
|
||||
Mockito.verify(config).googleAuthKey();
|
||||
Mockito.verifyNoInteractions(httpGetter, objectMapper);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFetchForUser() throws Exception {
|
||||
Feed feed = new Feed();
|
||||
feed.setUrl("https://youtube.com/feeds/videos.xml?user=testUser");
|
||||
|
||||
Mockito.when(config.googleAuthKey()).thenReturn(Optional.of("test-api-key"));
|
||||
|
||||
byte[] apiResponse = """
|
||||
{"items":[{"snippet":{"thumbnails":{"default":{"url":"https://example.com/icon.png"}}}}]}""".getBytes();
|
||||
HttpResult apiHttpResult = new HttpResult(apiResponse, "application/json", null, null, null, Duration.ZERO);
|
||||
Mockito.when(httpGetter.get("https://www.googleapis.com/youtube/v3/channels?part=snippet&key=test-api-key&forUsername=testUser"))
|
||||
.thenReturn(apiHttpResult);
|
||||
|
||||
JsonNode jsonNode = new ObjectMapper().readTree(apiResponse);
|
||||
Mockito.when(objectMapper.readTree(apiResponse)).thenReturn(jsonNode);
|
||||
|
||||
byte[] iconBytes = new byte[1000];
|
||||
String contentType = "image/png";
|
||||
HttpResult iconHttpResult = new HttpResult(iconBytes, contentType, null, null, null, Duration.ZERO);
|
||||
Mockito.when(httpGetter.get("https://example.com/icon.png")).thenReturn(iconHttpResult);
|
||||
|
||||
Favicon result = faviconFetcher.fetch(feed);
|
||||
|
||||
Assertions.assertNotNull(result);
|
||||
Assertions.assertEquals(iconBytes, result.getIcon());
|
||||
Assertions.assertTrue(result.getMediaType().isCompatible(MediaType.valueOf(contentType)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFetchForChannel() throws Exception {
|
||||
Feed feed = new Feed();
|
||||
feed.setUrl("https://youtube.com/feeds/videos.xml?channel_id=testChannelId");
|
||||
|
||||
Mockito.when(config.googleAuthKey()).thenReturn(Optional.of("test-api-key"));
|
||||
|
||||
byte[] apiResponse = """
|
||||
{"items":[{"snippet":{"thumbnails":{"default":{"url":"https://example.com/icon.png"}}}}]}""".getBytes();
|
||||
HttpResult apiHttpResult = new HttpResult(apiResponse, "application/json", null, null, null, Duration.ZERO);
|
||||
Mockito.when(httpGetter.get("https://www.googleapis.com/youtube/v3/channels?part=snippet&key=test-api-key&id=testChannelId"))
|
||||
.thenReturn(apiHttpResult);
|
||||
|
||||
JsonNode jsonNode = new ObjectMapper().readTree(apiResponse);
|
||||
Mockito.when(objectMapper.readTree(apiResponse)).thenReturn(jsonNode);
|
||||
|
||||
byte[] iconBytes = new byte[1000];
|
||||
String contentType = "image/png";
|
||||
HttpResult iconHttpResult = new HttpResult(iconBytes, contentType, null, null, null, Duration.ZERO);
|
||||
Mockito.when(httpGetter.get("https://example.com/icon.png")).thenReturn(iconHttpResult);
|
||||
|
||||
Favicon result = faviconFetcher.fetch(feed);
|
||||
|
||||
Assertions.assertNotNull(result);
|
||||
Assertions.assertEquals(iconBytes, result.getIcon());
|
||||
Assertions.assertTrue(result.getMediaType().isCompatible(MediaType.valueOf(contentType)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFetchForPlaylist() throws Exception {
|
||||
Feed feed = new Feed();
|
||||
feed.setUrl("https://youtube.com/feeds/videos.xml?playlist_id=testPlaylistId");
|
||||
|
||||
Mockito.when(config.googleAuthKey()).thenReturn(Optional.of("test-api-key"));
|
||||
|
||||
byte[] playlistResponse = """
|
||||
{"items":[{"snippet":{"channelId":"testChannelId"}}]}""".getBytes();
|
||||
HttpResult playlistHttpResult = new HttpResult(playlistResponse, "application/json", null, null, null, Duration.ZERO);
|
||||
Mockito.when(httpGetter.get("https://www.googleapis.com/youtube/v3/playlists?part=snippet&key=test-api-key&id=testPlaylistId"))
|
||||
.thenReturn(playlistHttpResult);
|
||||
|
||||
JsonNode playlistJsonNode = new ObjectMapper().readTree(playlistResponse);
|
||||
Mockito.when(objectMapper.readTree(playlistResponse)).thenReturn(playlistJsonNode);
|
||||
|
||||
byte[] channelResponse = """
|
||||
{"items":[{"snippet":{"thumbnails":{"default":{"url":"https://example.com/icon.png"}}}}]}""".getBytes();
|
||||
HttpResult channelHttpResult = new HttpResult(channelResponse, "application/json", null, null, null, Duration.ZERO);
|
||||
Mockito.when(httpGetter.get("https://www.googleapis.com/youtube/v3/channels?part=snippet&key=test-api-key&id=testChannelId"))
|
||||
.thenReturn(channelHttpResult);
|
||||
|
||||
JsonNode channelJsonNode = new ObjectMapper().readTree(channelResponse);
|
||||
Mockito.when(objectMapper.readTree(channelResponse)).thenReturn(channelJsonNode);
|
||||
|
||||
byte[] iconBytes = new byte[1000];
|
||||
String contentType = "image/png";
|
||||
HttpResult iconHttpResult = new HttpResult(iconBytes, contentType, null, null, null, Duration.ZERO);
|
||||
Mockito.when(httpGetter.get("https://example.com/icon.png")).thenReturn(iconHttpResult);
|
||||
|
||||
Favicon result = faviconFetcher.fetch(feed);
|
||||
|
||||
Assertions.assertNotNull(result);
|
||||
Assertions.assertEquals(iconBytes, result.getIcon());
|
||||
Assertions.assertTrue(result.getMediaType().isCompatible(MediaType.valueOf(contentType)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFetchWithHttpGetterException() throws Exception {
|
||||
Feed feed = new Feed();
|
||||
feed.setUrl("https://youtube.com/feeds/videos.xml?user=testUser");
|
||||
|
||||
Mockito.when(config.googleAuthKey()).thenReturn(Optional.of("test-api-key"));
|
||||
|
||||
Mockito.when(httpGetter.get("https://www.googleapis.com/youtube/v3/channels?part=snippet&key=test-api-key&forUsername=testUser"))
|
||||
.thenThrow(new IOException("Network error"));
|
||||
|
||||
Assertions.assertNull(faviconFetcher.fetch(feed));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFetchWithInvalidIconResponse() throws Exception {
|
||||
Feed feed = new Feed();
|
||||
feed.setUrl("https://youtube.com/feeds/videos.xml?user=testUser");
|
||||
|
||||
Mockito.when(config.googleAuthKey()).thenReturn(Optional.of("test-api-key"));
|
||||
|
||||
byte[] apiResponse = """
|
||||
{"items":[{"snippet":{"thumbnails":{"default":{"url":"https://example.com/icon.png"}}}}]}""".getBytes();
|
||||
HttpResult apiHttpResult = new HttpResult(apiResponse, "application/json", null, null, null, Duration.ZERO);
|
||||
Mockito.when(httpGetter.get("https://www.googleapis.com/youtube/v3/channels?part=snippet&key=test-api-key&forUsername=testUser"))
|
||||
.thenReturn(apiHttpResult);
|
||||
|
||||
JsonNode jsonNode = new ObjectMapper().readTree(apiResponse);
|
||||
Mockito.when(objectMapper.readTree(apiResponse)).thenReturn(jsonNode);
|
||||
|
||||
// Create a byte array that's too small
|
||||
byte[] iconBytes = new byte[50];
|
||||
String contentType = "image/png";
|
||||
HttpResult iconHttpResult = new HttpResult(iconBytes, contentType, null, null, null, Duration.ZERO);
|
||||
Mockito.when(httpGetter.get("https://example.com/icon.png")).thenReturn(iconHttpResult);
|
||||
|
||||
Assertions.assertNull(faviconFetcher.fetch(feed));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFetchWithEmptyApiResponse() throws Exception {
|
||||
Feed feed = new Feed();
|
||||
feed.setUrl("https://youtube.com/feeds/videos.xml?user=testUser");
|
||||
|
||||
Mockito.when(config.googleAuthKey()).thenReturn(Optional.of("test-api-key"));
|
||||
|
||||
byte[] apiResponse = "{}".getBytes();
|
||||
HttpResult apiHttpResult = new HttpResult(apiResponse, "application/json", null, null, null, Duration.ZERO);
|
||||
Mockito.when(httpGetter.get("https://www.googleapis.com/youtube/v3/channels?part=snippet&key=test-api-key&forUsername=testUser"))
|
||||
.thenReturn(apiHttpResult);
|
||||
|
||||
JsonNode jsonNode = Mockito.mock(JsonNode.class);
|
||||
Mockito.when(objectMapper.readTree(apiResponse)).thenReturn(jsonNode);
|
||||
Mockito.when(jsonNode.at(Mockito.any(JsonPointer.class))).thenReturn(jsonNode);
|
||||
Mockito.when(jsonNode.isMissingNode()).thenReturn(true);
|
||||
|
||||
Assertions.assertNull(faviconFetcher.fetch(feed));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
package com.commafeed.backend.model;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class FeedEntryContentTest {
|
||||
|
||||
@Nested
|
||||
class EquivalentTo {
|
||||
|
||||
@Test
|
||||
void shouldReturnFalseWhenComparedWithNull() {
|
||||
Assertions.assertFalse(new FeedEntryContent().equivalentTo(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnTrueWhenComparedWithIdenticalContent() {
|
||||
FeedEntryContent content1 = createContent("title", "content", "author", "categories", "enclosureUrl", "enclosureType",
|
||||
"mediaDescription", "mediaThumbnailUrl", 10, 20);
|
||||
FeedEntryContent content2 = createContent("title", "content", "author", "categories", "enclosureUrl", "enclosureType",
|
||||
"mediaDescription", "mediaThumbnailUrl", 10, 20);
|
||||
Assertions.assertTrue(content1.equivalentTo(content2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnFalseWhenTitleDiffers() {
|
||||
FeedEntryContent content1 = createContent("title1", "content", "author", "categories", "enclosureUrl", "enclosureType",
|
||||
"mediaDescription", "mediaThumbnailUrl", 10, 20);
|
||||
FeedEntryContent content2 = createContent("title2", "content", "author", "categories", "enclosureUrl", "enclosureType",
|
||||
"mediaDescription", "mediaThumbnailUrl", 10, 20);
|
||||
Assertions.assertFalse(content1.equivalentTo(content2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnFalseWhenContentDiffers() {
|
||||
FeedEntryContent content1 = createContent("title", "content1", "author", "categories", "enclosureUrl", "enclosureType",
|
||||
"mediaDescription", "mediaThumbnailUrl", 10, 20);
|
||||
FeedEntryContent content2 = createContent("title", "content2", "author", "categories", "enclosureUrl", "enclosureType",
|
||||
"mediaDescription", "mediaThumbnailUrl", 10, 20);
|
||||
Assertions.assertFalse(content1.equivalentTo(content2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnFalseWhenAuthorDiffers() {
|
||||
FeedEntryContent content1 = createContent("title", "content", "author1", "categories", "enclosureUrl", "enclosureType",
|
||||
"mediaDescription", "mediaThumbnailUrl", 10, 20);
|
||||
FeedEntryContent content2 = createContent("title", "content", "author2", "categories", "enclosureUrl", "enclosureType",
|
||||
"mediaDescription", "mediaThumbnailUrl", 10, 20);
|
||||
Assertions.assertFalse(content1.equivalentTo(content2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnFalseWhenCategoriesDiffer() {
|
||||
FeedEntryContent content1 = createContent("title", "content", "author", "categories1", "enclosureUrl", "enclosureType",
|
||||
"mediaDescription", "mediaThumbnailUrl", 10, 20);
|
||||
FeedEntryContent content2 = createContent("title", "content", "author", "categories2", "enclosureUrl", "enclosureType",
|
||||
"mediaDescription", "mediaThumbnailUrl", 10, 20);
|
||||
Assertions.assertFalse(content1.equivalentTo(content2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnFalseWhenEnclosureUrlDiffers() {
|
||||
FeedEntryContent content1 = createContent("title", "content", "author", "categories", "enclosureUrl1", "enclosureType",
|
||||
"mediaDescription", "mediaThumbnailUrl", 10, 20);
|
||||
FeedEntryContent content2 = createContent("title", "content", "author", "categories", "enclosureUrl2", "enclosureType",
|
||||
"mediaDescription", "mediaThumbnailUrl", 10, 20);
|
||||
Assertions.assertFalse(content1.equivalentTo(content2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnFalseWhenEnclosureTypeDiffers() {
|
||||
FeedEntryContent content1 = createContent("title", "content", "author", "categories", "enclosureUrl", "enclosureType1",
|
||||
"mediaDescription", "mediaThumbnailUrl", 10, 20);
|
||||
FeedEntryContent content2 = createContent("title", "content", "author", "categories", "enclosureUrl", "enclosureType2",
|
||||
"mediaDescription", "mediaThumbnailUrl", 10, 20);
|
||||
Assertions.assertFalse(content1.equivalentTo(content2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnFalseWhenMediaDescriptionDiffers() {
|
||||
FeedEntryContent content1 = createContent("title", "content", "author", "categories", "enclosureUrl", "enclosureType",
|
||||
"mediaDescription1", "mediaThumbnailUrl", 10, 20);
|
||||
FeedEntryContent content2 = createContent("title", "content", "author", "categories", "enclosureUrl", "enclosureType",
|
||||
"mediaDescription2", "mediaThumbnailUrl", 10, 20);
|
||||
Assertions.assertFalse(content1.equivalentTo(content2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnFalseWhenMediaThumbnailUrlDiffers() {
|
||||
FeedEntryContent content1 = createContent("title", "content", "author", "categories", "enclosureUrl", "enclosureType",
|
||||
"mediaDescription", "mediaThumbnailUrl1", 10, 20);
|
||||
FeedEntryContent content2 = createContent("title", "content", "author", "categories", "enclosureUrl", "enclosureType",
|
||||
"mediaDescription", "mediaThumbnailUrl2", 10, 20);
|
||||
Assertions.assertFalse(content1.equivalentTo(content2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnFalseWhenMediaThumbnailWidthDiffers() {
|
||||
FeedEntryContent content1 = createContent("title", "content", "author", "categories", "enclosureUrl", "enclosureType",
|
||||
"mediaDescription", "mediaThumbnailUrl", 10, 20);
|
||||
FeedEntryContent content2 = createContent("title", "content", "author", "categories", "enclosureUrl", "enclosureType",
|
||||
"mediaDescription", "mediaThumbnailUrl", 15, 20);
|
||||
Assertions.assertFalse(content1.equivalentTo(content2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnFalseWhenMediaThumbnailHeightDiffers() {
|
||||
FeedEntryContent content1 = createContent("title", "content", "author", "categories", "enclosureUrl", "enclosureType",
|
||||
"mediaDescription", "mediaThumbnailUrl", 10, 20);
|
||||
FeedEntryContent content2 = createContent("title", "content", "author", "categories", "enclosureUrl", "enclosureType",
|
||||
"mediaDescription", "mediaThumbnailUrl", 10, 25);
|
||||
Assertions.assertFalse(content1.equivalentTo(content2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnTrueWhenNullFieldsAreEqual() {
|
||||
FeedEntryContent content1 = new FeedEntryContent();
|
||||
FeedEntryContent content2 = new FeedEntryContent();
|
||||
Assertions.assertTrue(content1.equivalentTo(content2));
|
||||
}
|
||||
|
||||
private FeedEntryContent createContent(String title, String content, String author, String categories, String enclosureUrl,
|
||||
String enclosureType, String mediaDescription, String mediaThumbnailUrl, Integer mediaThumbnailWidth,
|
||||
Integer mediaThumbnailHeight) {
|
||||
FeedEntryContent feedEntryContent = new FeedEntryContent();
|
||||
feedEntryContent.setTitle(title);
|
||||
feedEntryContent.setContent(content);
|
||||
feedEntryContent.setAuthor(author);
|
||||
feedEntryContent.setCategories(categories);
|
||||
feedEntryContent.setEnclosureUrl(enclosureUrl);
|
||||
feedEntryContent.setEnclosureType(enclosureType);
|
||||
feedEntryContent.setMediaDescription(mediaDescription);
|
||||
feedEntryContent.setMediaThumbnailUrl(mediaThumbnailUrl);
|
||||
feedEntryContent.setMediaThumbnailWidth(mediaThumbnailWidth);
|
||||
feedEntryContent.setMediaThumbnailHeight(mediaThumbnailHeight);
|
||||
return feedEntryContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.commafeed.backend.urlprovider;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class InPageReferenceFeedURLProviderTest {
|
||||
|
||||
private final InPageReferenceFeedURLProvider provider = new InPageReferenceFeedURLProvider();
|
||||
|
||||
@Test
|
||||
void extractsAtomFeedURL() {
|
||||
String url = "http://example.com";
|
||||
String html = """
|
||||
<html>
|
||||
<head>
|
||||
<link type="application/atom+xml" href="/feed.atom">
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>""";
|
||||
|
||||
String result = provider.get(url, html);
|
||||
|
||||
Assertions.assertEquals("http://example.com/feed.atom", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void extractsRSSFeedURL() {
|
||||
String url = "http://example.com";
|
||||
String html = """
|
||||
<html>
|
||||
<head>
|
||||
<link type="application/rss+xml" href="/feed.rss">
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>""";
|
||||
|
||||
String result = provider.get(url, html);
|
||||
|
||||
Assertions.assertEquals("http://example.com/feed.rss", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void prefersAtomOverRSS() {
|
||||
String url = "http://example.com";
|
||||
String html = """
|
||||
<html>
|
||||
<head>
|
||||
<link type="application/atom+xml" href="/feed.atom">
|
||||
<link type="application/rss+xml" href="/feed.rss">
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>""";
|
||||
|
||||
String result = provider.get(url, html);
|
||||
|
||||
Assertions.assertEquals("http://example.com/feed.atom", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsNullForNonHtmlContent() {
|
||||
String url = "http://example.com";
|
||||
String content = """
|
||||
<?xml version="1.0"?>
|
||||
<feed></feed>
|
||||
</xml>""";
|
||||
|
||||
String result = provider.get(url, content);
|
||||
|
||||
Assertions.assertNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsNullForHtmlWithoutFeedLinks() {
|
||||
String url = "http://example.com";
|
||||
String html = """
|
||||
<html>
|
||||
<head>
|
||||
<link type="text/css" href="/style.css">
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>""";
|
||||
|
||||
String result = provider.get(url, html);
|
||||
|
||||
Assertions.assertNull(result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.commafeed.frontend.model;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Date;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.rometools.rome.feed.synd.SyndEntry;
|
||||
|
||||
class EntryTest {
|
||||
|
||||
@Test
|
||||
void asRss() {
|
||||
Entry entry = new Entry();
|
||||
entry.setId("1");
|
||||
entry.setGuid("guid-1");
|
||||
entry.setTitle("Test Entry");
|
||||
entry.setContent("This is a test entry content.");
|
||||
entry.setCategories("test,example");
|
||||
entry.setRtl(false);
|
||||
entry.setAuthor("Author Name");
|
||||
entry.setEnclosureUrl("http://example.com/enclosure.mp3");
|
||||
entry.setEnclosureType("audio/mpeg");
|
||||
entry.setDate(Instant.ofEpochSecond(1));
|
||||
entry.setUrl("http://example.com/test-entry");
|
||||
|
||||
SyndEntry syndEntry = entry.asRss();
|
||||
Assertions.assertEquals("guid-1", syndEntry.getUri());
|
||||
Assertions.assertEquals("Test Entry", syndEntry.getTitle());
|
||||
Assertions.assertEquals("Author Name", syndEntry.getAuthor());
|
||||
Assertions.assertEquals(1, syndEntry.getContents().size());
|
||||
Assertions.assertEquals("This is a test entry content.", syndEntry.getContents().get(0).getValue());
|
||||
Assertions.assertEquals(1, syndEntry.getEnclosures().size());
|
||||
Assertions.assertEquals("http://example.com/enclosure.mp3", syndEntry.getEnclosures().get(0).getUrl());
|
||||
Assertions.assertEquals("audio/mpeg", syndEntry.getEnclosures().get(0).getType());
|
||||
Assertions.assertEquals("http://example.com/test-entry", syndEntry.getLink());
|
||||
Assertions.assertEquals(Date.from(Instant.ofEpochSecond(1)), syndEntry.getPublishedDate());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,7 +10,6 @@ import java.util.Objects;
|
||||
|
||||
import jakarta.ws.rs.client.Client;
|
||||
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;
|
||||
@@ -29,6 +28,7 @@ import com.commafeed.frontend.model.request.AddCategoryRequest;
|
||||
import com.commafeed.frontend.model.request.SubscribeRequest;
|
||||
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
import io.restassured.http.Header;
|
||||
import lombok.Getter;
|
||||
|
||||
@@ -95,7 +95,7 @@ public abstract class BaseIT {
|
||||
addCategoryRequest.setName(name);
|
||||
return RestAssured.given()
|
||||
.body(addCategoryRequest)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/category/add")
|
||||
.then()
|
||||
.extract()
|
||||
@@ -117,7 +117,7 @@ public abstract class BaseIT {
|
||||
subscribeRequest.setCategoryId(categoryId);
|
||||
return RestAssured.given()
|
||||
.body(subscribeRequest)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/feed/subscribe")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
@@ -162,6 +162,24 @@ public abstract class BaseIT {
|
||||
.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 int forceRefreshAllFeeds() {
|
||||
return RestAssured.given().get("rest/feed/refreshAll").then().extract().statusCode();
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import jakarta.ws.rs.core.HttpHeaders;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
@@ -20,6 +19,7 @@ import com.commafeed.frontend.model.request.SubscribeRequest;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
|
||||
@QuarkusTest
|
||||
class SecurityIT extends BaseIT {
|
||||
@@ -79,7 +79,7 @@ class SecurityIT extends BaseIT {
|
||||
.preemptive()
|
||||
.basic("admin", "admin")
|
||||
.body(req)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/user/profile")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
@@ -105,7 +105,7 @@ class SecurityIT extends BaseIT {
|
||||
.preemptive()
|
||||
.basic("admin", "admin")
|
||||
.body(subscribeRequest)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/feed/subscribe")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
@@ -130,7 +130,7 @@ class SecurityIT extends BaseIT {
|
||||
markRequest.setRead(true);
|
||||
RestAssured.given()
|
||||
.body(markRequest)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.contentType(ContentType.JSON)
|
||||
.queryParam("apiKey", apiKey)
|
||||
.post("rest/entry/mark")
|
||||
.then()
|
||||
|
||||
@@ -19,7 +19,6 @@ import jakarta.websocket.Endpoint;
|
||||
import jakarta.websocket.EndpointConfig;
|
||||
import jakarta.websocket.Session;
|
||||
import jakarta.ws.rs.core.HttpHeaders;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.awaitility.Awaitility;
|
||||
@@ -32,6 +31,7 @@ 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
|
||||
@@ -102,7 +102,7 @@ class WebSocketIT extends BaseIT {
|
||||
req.setId(subscriptionId);
|
||||
req.setName("feed-name");
|
||||
req.setFilter("!title.contains('item 4')");
|
||||
RestAssured.given().body(req).contentType(MediaType.APPLICATION_JSON).post("rest/feed/modify").then().statusCode(HttpStatus.SC_OK);
|
||||
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<>();
|
||||
|
||||
@@ -2,8 +2,6 @@ package com.commafeed.integration.rest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
@@ -18,6 +16,7 @@ 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 {
|
||||
@@ -38,42 +37,47 @@ class AdminIT extends BaseIT {
|
||||
void saveModifyAndDeleteNewUser() {
|
||||
List<UserModel> existingUsers = getAllUsers();
|
||||
|
||||
createUser();
|
||||
long userId = createUser();
|
||||
Assertions.assertEquals(existingUsers.size() + 1, getAllUsers().size());
|
||||
|
||||
modifyUser();
|
||||
UserModel user = getUser(userId);
|
||||
Assertions.assertEquals("test", user.getName());
|
||||
|
||||
modifyUser(user);
|
||||
Assertions.assertEquals(existingUsers.size() + 1, getAllUsers().size());
|
||||
|
||||
deleteUser();
|
||||
Assertions.assertEquals(existingUsers.size(), getAllUsers().size());
|
||||
}
|
||||
|
||||
private void createUser() {
|
||||
private long createUser() {
|
||||
User user = new User();
|
||||
user.setName("test");
|
||||
user.setPassword("test".getBytes());
|
||||
user.setEmail("test@test.com");
|
||||
RestAssured.given()
|
||||
String response = RestAssured.given()
|
||||
.body(user)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/admin/user/save")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
.extract()
|
||||
.asString();
|
||||
return Long.parseLong(response);
|
||||
}
|
||||
|
||||
private void modifyUser() {
|
||||
List<UserModel> existingUsers = getAllUsers();
|
||||
UserModel user = existingUsers.stream()
|
||||
.filter(u -> u.getName().equals("test"))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new NullPointerException("User not found"));
|
||||
user.setEmail("new-email@provider.com");
|
||||
RestAssured.given()
|
||||
.body(user)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.post("rest/admin/user/save")
|
||||
private UserModel getUser(long userId) {
|
||||
return RestAssured.given()
|
||||
.get("rest/admin/user/get/{id}", userId)
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
.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 deleteUser() {
|
||||
@@ -85,12 +89,7 @@ class AdminIT extends BaseIT {
|
||||
|
||||
IDRequest req = new IDRequest();
|
||||
req.setId(user.getId());
|
||||
RestAssured.given()
|
||||
.body(req)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.post("rest/admin/user/delete")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
RestAssured.given().body(req).contentType(ContentType.JSON).post("rest/admin/user/delete").then().statusCode(HttpStatus.SC_OK);
|
||||
}
|
||||
|
||||
private List<UserModel> getAllUsers() {
|
||||
|
||||
@@ -1,25 +1,36 @@
|
||||
package com.commafeed.integration.rest;
|
||||
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
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.frontend.model.Category;
|
||||
import com.commafeed.frontend.model.Entries;
|
||||
import com.commafeed.frontend.model.Entry;
|
||||
import com.commafeed.frontend.model.UnreadCount;
|
||||
import com.commafeed.frontend.model.request.CategoryModificationRequest;
|
||||
import com.commafeed.frontend.model.request.CollapseRequest;
|
||||
import com.commafeed.frontend.model.request.IDRequest;
|
||||
import com.commafeed.frontend.model.request.MarkRequest;
|
||||
import com.commafeed.frontend.model.request.StarRequest;
|
||||
import com.commafeed.frontend.model.request.TagRequest;
|
||||
import com.commafeed.frontend.resource.CategoryREST;
|
||||
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.common.mapper.TypeRef;
|
||||
import io.restassured.http.ContentType;
|
||||
|
||||
@QuarkusTest
|
||||
class CategoryIT extends BaseIT {
|
||||
@@ -37,18 +48,30 @@ class CategoryIT extends BaseIT {
|
||||
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");
|
||||
request.setName("modified-category-2");
|
||||
request.setParentId(category1Id);
|
||||
RestAssured.given().body(request).contentType(MediaType.APPLICATION_JSON).post("rest/category/modify").then().statusCode(200);
|
||||
request.setPosition(2);
|
||||
RestAssured.given().body(request).contentType(ContentType.JSON).post("rest/category/modify").then().statusCode(200);
|
||||
|
||||
Category root = getRootCategory();
|
||||
Assertions.assertEquals(1, root.getChildren().size());
|
||||
Assertions.assertEquals(2, root.getChildren().size());
|
||||
Assertions.assertEquals("test-category-1", root.getChildren().get(0).getName());
|
||||
Assertions.assertEquals(1, root.getChildren().get(0).getChildren().size());
|
||||
Assertions.assertEquals("modified-category", root.getChildren().get(0).getChildren().get(0).getName());
|
||||
Assertions.assertEquals("modified-category-2", root.getChildren().get(0).getChildren().get(0).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);
|
||||
|
||||
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
|
||||
@@ -62,7 +85,7 @@ class CategoryIT extends BaseIT {
|
||||
CollapseRequest request = new CollapseRequest();
|
||||
request.setId(Long.valueOf(categoryId));
|
||||
request.setCollapse(true);
|
||||
RestAssured.given().body(request).contentType(MediaType.APPLICATION_JSON).post("rest/category/collapse").then().statusCode(200);
|
||||
RestAssured.given().body(request).contentType(ContentType.JSON).post("rest/category/collapse").then().statusCode(200);
|
||||
|
||||
root = getRootCategory();
|
||||
Assertions.assertEquals(1, root.getChildren().size());
|
||||
@@ -76,10 +99,57 @@ class CategoryIT extends BaseIT {
|
||||
|
||||
IDRequest request = new IDRequest();
|
||||
request.setId(Long.valueOf(categoryId));
|
||||
RestAssured.given().body(request).contentType(MediaType.APPLICATION_JSON).post("rest/category/delete").then().statusCode(200);
|
||||
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());
|
||||
|
||||
List<UnreadCount> counts = RestAssured.given()
|
||||
.get("rest/category/unreadCount")
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.extract()
|
||||
.as(new TypeRef<List<UnreadCount>>() {
|
||||
});
|
||||
|
||||
Assertions.assertEquals(1, counts.size());
|
||||
Assertions.assertEquals(subscriptionId, counts.get(0).getFeedId());
|
||||
Assertions.assertEquals(2, counts.get(0).getUnreadCount());
|
||||
}
|
||||
|
||||
@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));
|
||||
}
|
||||
|
||||
@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));
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class GetEntries {
|
||||
@Test
|
||||
@@ -89,6 +159,22 @@ class CategoryIT extends BaseIT {
|
||||
Assertions.assertEquals(2, entries.getEntries().size());
|
||||
}
|
||||
|
||||
@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());
|
||||
}
|
||||
|
||||
@Test
|
||||
void starred() {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
@@ -100,13 +186,36 @@ class CategoryIT extends BaseIT {
|
||||
starRequest.setId(entry.getId());
|
||||
starRequest.setFeedId(subscriptionId);
|
||||
starRequest.setStarred(true);
|
||||
RestAssured.given().body(starRequest).contentType(MediaType.APPLICATION_JSON).post("rest/entry/star");
|
||||
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().get(0).getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void tagged() {
|
||||
Long subscriptionId = subscribeAndWaitForEntries(getFeedUrl());
|
||||
Assertions.assertEquals(0, getTaggedEntries("my-tag").getEntries().size());
|
||||
|
||||
Entry entry = getFeedEntries(subscriptionId).getEntries().get(0);
|
||||
|
||||
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().get(0).getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void keywords() {
|
||||
subscribeAndWaitForEntries(getFeedUrl());
|
||||
Assertions.assertEquals(1, getCategoryEntries(CategoryREST.ALL, "Item 2 description").getEntries().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void specificCategory() {
|
||||
String categoryId = createCategory("test-category");
|
||||
|
||||
@@ -2,6 +2,7 @@ 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;
|
||||
@@ -19,6 +20,7 @@ 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.frontend.model.Entry;
|
||||
import com.commafeed.frontend.model.FeedInfo;
|
||||
@@ -28,9 +30,13 @@ import com.commafeed.frontend.model.request.FeedModificationRequest;
|
||||
import com.commafeed.frontend.model.request.IDRequest;
|
||||
import com.commafeed.frontend.model.request.MarkRequest;
|
||||
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;
|
||||
|
||||
@QuarkusTest
|
||||
class FeedIT extends BaseIT {
|
||||
@@ -54,7 +60,7 @@ class FeedIT extends BaseIT {
|
||||
|
||||
FeedInfo feedInfo = RestAssured.given()
|
||||
.body(req)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/feed/fetch")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK)
|
||||
@@ -101,7 +107,7 @@ class FeedIT extends BaseIT {
|
||||
|
||||
return RestAssured.given()
|
||||
.body(request)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/feed/unsubscribe")
|
||||
.then()
|
||||
.extract()
|
||||
@@ -152,12 +158,7 @@ class FeedIT extends BaseIT {
|
||||
request.setOlderThan(olderThan == null ? null : olderThan.toEpochMilli());
|
||||
request.setInsertedBefore(insertedBefore == null ? null : insertedBefore.toEpochMilli());
|
||||
|
||||
RestAssured.given()
|
||||
.body(request)
|
||||
.contentType(MediaType.APPLICATION_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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,6 +181,25 @@ class FeedIT extends BaseIT {
|
||||
}
|
||||
}
|
||||
|
||||
@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());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class Modify {
|
||||
@Test
|
||||
@@ -192,12 +212,8 @@ class FeedIT extends BaseIT {
|
||||
req.setId(subscriptionId);
|
||||
req.setName("new name");
|
||||
req.setCategoryId(subscription.getCategoryId());
|
||||
RestAssured.given()
|
||||
.body(req)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.post("rest/feed/modify")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
req.setPosition(1);
|
||||
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());
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.commafeed.integration.rest;
|
||||
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
@@ -16,6 +14,7 @@ import com.commafeed.integration.BaseIT;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
|
||||
@QuarkusTest
|
||||
class FeverIT extends BaseIT {
|
||||
@@ -31,7 +30,7 @@ class FeverIT extends BaseIT {
|
||||
ProfileModificationRequest req = new ProfileModificationRequest();
|
||||
req.setCurrentPassword("admin");
|
||||
req.setNewApiKey(true);
|
||||
RestAssured.given().body(req).contentType(MediaType.APPLICATION_JSON).post("rest/user/profile").then().statusCode(HttpStatus.SC_OK);
|
||||
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);
|
||||
@@ -70,6 +69,27 @@ class FeverIT extends BaseIT {
|
||||
Assertions.assertEquals(2, feverResponse.getUnreadItemIds().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void entries() {
|
||||
subscribeAndWaitForEntries(getFeedUrl());
|
||||
FeverResponse feverResponse = fetch("items");
|
||||
Assertions.assertEquals(2, feverResponse.getItems().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void groups() {
|
||||
createCategory("category-1");
|
||||
FeverResponse feverResponse = fetch("groups");
|
||||
Assertions.assertEquals(1, feverResponse.getGroups().size());
|
||||
Assertions.assertEquals("category-1", feverResponse.getGroups().get(0).getTitle());
|
||||
}
|
||||
|
||||
@Test
|
||||
void links() {
|
||||
FeverResponse feverResponse = fetch("links");
|
||||
Assertions.assertTrue(feverResponse.getLinks().isEmpty());
|
||||
}
|
||||
|
||||
private FeverResponse fetch(String what) {
|
||||
return fetch(what, apiKey);
|
||||
}
|
||||
|
||||
@@ -3,19 +3,22 @@ package com.commafeed.integration.rest;
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Element;
|
||||
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.frontend.model.Settings;
|
||||
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
|
||||
@@ -40,7 +43,7 @@ class UserIT extends BaseIT {
|
||||
void resetPassword() {
|
||||
PasswordResetRequest req = new PasswordResetRequest();
|
||||
req.setEmail("admin@commafeed.com");
|
||||
RestAssured.given().body(req).contentType(MediaType.APPLICATION_JSON).post("rest/user/passwordReset").then().statusCode(200);
|
||||
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());
|
||||
@@ -49,5 +52,20 @@ class UserIT extends BaseIT {
|
||||
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().get(0));
|
||||
|
||||
Element a = Jsoup.parse(message.getHtml()).select("a").get(0);
|
||||
String link = a.attr("href");
|
||||
String newPasswordResponse = RestAssured.given().urlEncodingEnabled(false).get(link).then().statusCode(200).extract().asString();
|
||||
Assertions.assertTrue(newPasswordResponse.contains("Your new password is:"));
|
||||
}
|
||||
|
||||
@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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.commafeed.integration.servlet;
|
||||
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
@@ -13,6 +11,7 @@ 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 {
|
||||
@@ -35,12 +34,7 @@ class CustomCodeIT extends BaseIT {
|
||||
// update settings
|
||||
settings.setCustomJs("custom-js");
|
||||
settings.setCustomCss("custom-css");
|
||||
RestAssured.given()
|
||||
.body(settings)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.post("rest/user/settings")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
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"));
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.commafeed.tools;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.google.common.io.Resources;
|
||||
|
||||
class CommaFeedPropertiesGeneratorTest {
|
||||
|
||||
@Test
|
||||
void testGenerate() throws Exception {
|
||||
InputStream model = getClass().getResourceAsStream("/properties/quarkus-config-model.yaml");
|
||||
InputStream javadoc = getClass().getResourceAsStream("/properties/quarkus-config-javadoc.yaml");
|
||||
URL output = getClass().getResource("/properties/output.properties");
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
new CommaFeedPropertiesGenerator().generate(model, javadoc, baos);
|
||||
|
||||
Assertions.assertLinesMatch(Resources.readLines(output, StandardCharsets.UTF_8).stream(),
|
||||
baos.toString(StandardCharsets.UTF_8).lines());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
# we generate the jacoco report ourselves by aggregating the unit tests and integration tests jacoco.exec files
|
||||
quarkus.jacoco.report=false
|
||||
150
commafeed-server/src/test/resources/properties/output.properties
Normal file
150
commafeed-server/src/test/resources/properties/output.properties
Normal file
@@ -0,0 +1,150 @@
|
||||
# Whether to expose a robots.txt file that disallows web crawlers and search engine indexers.
|
||||
commafeed.hide-from-web-crawlers=true
|
||||
|
||||
# If enabled, images in feed entries will be proxied through the server instead of accessed directly by the browser.
|
||||
#
|
||||
# This is useful if commafeed is accessed through a restricting proxy that blocks some feeds that are followed.
|
||||
commafeed.image-proxy-enabled=false
|
||||
|
||||
# Enable password recovery via email.
|
||||
#
|
||||
# Quarkus mailer will need to be configured.
|
||||
commafeed.password-recovery-enabled=false
|
||||
|
||||
# Message displayed in a notification at the bottom of the page.
|
||||
commafeed.announcement=
|
||||
|
||||
# Google Analytics tracking code.
|
||||
commafeed.google-analytics-tracking-code=
|
||||
|
||||
# Google Auth key for fetching Youtube channel favicons.
|
||||
commafeed.google-auth-key=
|
||||
|
||||
# User-Agent string that will be used by the http client, leave empty for the default one.
|
||||
commafeed.http-client.user-agent=
|
||||
|
||||
# Time to wait for a connection to be established.
|
||||
commafeed.http-client.connect-timeout=5s
|
||||
|
||||
# Time to wait for SSL handshake to complete.
|
||||
commafeed.http-client.ssl-handshake-timeout=5s
|
||||
|
||||
# Time to wait between two packets before timeout.
|
||||
commafeed.http-client.socket-timeout=10s
|
||||
|
||||
# Time to wait for the full response to be received.
|
||||
commafeed.http-client.response-timeout=10s
|
||||
|
||||
# Time to live for a connection in the pool.
|
||||
commafeed.http-client.connection-time-to-live=30s
|
||||
|
||||
# Time between eviction runs for idle connections.
|
||||
commafeed.http-client.idle-connections-eviction-interval=1m
|
||||
|
||||
# If a feed is larger than this, it will be discarded to prevent memory issues while parsing the feed.
|
||||
commafeed.http-client.max-response-size=5m
|
||||
|
||||
# Prevent access to local addresses to mitigate server-side request forgery (SSRF) attacks, which could potentially expose internal
|
||||
# resources.
|
||||
#
|
||||
# You may want to disable this if you subscribe to feeds that are only available on your local network and you trust all users of
|
||||
# your CommaFeed instance.
|
||||
commafeed.http-client.block-local-addresses=true
|
||||
|
||||
# Whether to enable the cache. This cache is used to avoid spamming feeds in short bursts (e.g. when subscribing to a feed for the
|
||||
# first time or when clicking "fetch all my feeds now").
|
||||
commafeed.http-client.cache.enabled=true
|
||||
|
||||
# Maximum amount of memory the cache can use.
|
||||
commafeed.http-client.cache.maximum-memory-size=10m
|
||||
|
||||
# Duration after which an entry is removed from the cache.
|
||||
commafeed.http-client.cache.expiration=1m
|
||||
|
||||
# Default amount of time CommaFeed will wait before refreshing a feed.
|
||||
commafeed.feed-refresh.interval=5m
|
||||
|
||||
# Maximum amount of time CommaFeed will wait before refreshing a feed. This is used as an upper bound when:
|
||||
#
|
||||
# <ul>
|
||||
# <li>an error occurs while refreshing a feed and we're backing off exponentially</li>
|
||||
# <li>we receive a Cache-Control header from the feed</li>
|
||||
# <li>we receive a Retry-After header from the feed</li>
|
||||
# </ul>
|
||||
commafeed.feed-refresh.max-interval=4h
|
||||
|
||||
# If enabled, CommaFeed will calculate the next refresh time based on the feed's average time between entries and the time since
|
||||
# the last entry was published. The interval will be sometimes between the default refresh interval
|
||||
# (`commafeed.feed-refresh.interval`) and the maximum refresh interval (`commafeed.feed-refresh.max-interval`).
|
||||
#
|
||||
# See {@link FeedRefreshIntervalCalculator} for details.
|
||||
commafeed.feed-refresh.interval-empirical=true
|
||||
|
||||
# Number of retries before backoff is applied.
|
||||
commafeed.feed-refresh.errors.retries-before-backoff=3
|
||||
|
||||
# Duration to wait before retrying after an error. Will be multiplied by the number of errors since the last successful fetch.
|
||||
commafeed.feed-refresh.errors.backoff-interval=1h
|
||||
|
||||
# Amount of http threads used to fetch feeds.
|
||||
commafeed.feed-refresh.http-threads=3
|
||||
|
||||
# Amount of threads used to insert new entries in the database.
|
||||
commafeed.feed-refresh.database-threads=1
|
||||
|
||||
# Duration after which a user is considered inactive. Feeds for inactive users are not refreshed until they log in again.
|
||||
#
|
||||
# 0 to disable.
|
||||
commafeed.feed-refresh.user-inactivity-period=0s
|
||||
|
||||
# Duration after which the evaluation of a filtering expresion to mark an entry as read is considered to have timed out.
|
||||
commafeed.feed-refresh.filtering-expression-evaluation-timeout=500ms
|
||||
|
||||
# Duration after which the "Fetch all my feeds now" action is available again after use to avoid spamming feeds.
|
||||
commafeed.feed-refresh.force-refresh-cooldown-duration=0s
|
||||
|
||||
# Timeout applied to all database queries.
|
||||
#
|
||||
# 0 to disable.
|
||||
commafeed.database.query-timeout=0s
|
||||
|
||||
# Maximum age of feed entries in the database. Older entries will be deleted.
|
||||
#
|
||||
# 0 to disable.
|
||||
commafeed.database.cleanup.entries-max-age=365d
|
||||
|
||||
# Maximum age of feed entry statuses (read/unread) in the database. Older statuses will be deleted.
|
||||
#
|
||||
# 0 to disable.
|
||||
commafeed.database.cleanup.statuses-max-age=0s
|
||||
|
||||
# Maximum number of entries per feed to keep in the database.
|
||||
#
|
||||
# 0 to disable.
|
||||
commafeed.database.cleanup.max-feed-capacity=500
|
||||
|
||||
# Limit the number of feeds a user can subscribe to.
|
||||
#
|
||||
# 0 to disable.
|
||||
commafeed.database.cleanup.max-feeds-per-user=0
|
||||
|
||||
# Rows to delete per query while cleaning up old entries.
|
||||
commafeed.database.cleanup.batch-size=100
|
||||
|
||||
# Whether to let users create accounts for themselves.
|
||||
commafeed.users.allow-registrations=false
|
||||
|
||||
# Whether to enable strict password validation (1 uppercase char, 1 lowercase char, 1 digit, 1 special char).
|
||||
commafeed.users.strict-password-policy=true
|
||||
|
||||
# Whether to create a demo account the first time the app starts.
|
||||
commafeed.users.create-demo-account=false
|
||||
|
||||
# Enable websocket connection so the server can notify web clients that there are new entries for feeds.
|
||||
commafeed.websocket.enabled=true
|
||||
|
||||
# Interval at which the client will send a ping message on the websocket to keep the connection alive.
|
||||
commafeed.websocket.ping-interval=15m
|
||||
|
||||
# If the websocket connection is disabled or the connection is lost, the client will reload the feed tree at this interval.
|
||||
commafeed.websocket.tree-reload-interval=30s
|
||||
@@ -0,0 +1,186 @@
|
||||
---
|
||||
extension:
|
||||
groupId: "com.commafeed"
|
||||
artifactId: "commafeed-server"
|
||||
name: "CommaFeed Server"
|
||||
nameSource: "POM_XML"
|
||||
detected: true
|
||||
elements:
|
||||
com.commafeed.CommaFeedConfiguration.HttpClient.maxResponseSize:
|
||||
description: "If a feed is larger than this, it will be discarded to prevent memory\
|
||||
\ issues while parsing the feed."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.passwordRecoveryEnabled:
|
||||
description: "Enable password recovery via email.\n\nQuarkus mailer will need\
|
||||
\ to be configured."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.imageProxyEnabled:
|
||||
description: "If enabled, images in feed entries will be proxied through the server\
|
||||
\ instead of accessed directly by the browser.\n\nThis is useful if commafeed\
|
||||
\ is accessed through a restricting proxy that blocks some feeds that are followed."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.FeedRefresh.forceRefreshCooldownDuration:
|
||||
description: "Duration after which the \"Fetch all my feeds now\" action is available\
|
||||
\ again after use to avoid spamming feeds."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.Database.queryTimeout:
|
||||
description: "Timeout applied to all database queries.\n\n0 to disable."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.Database.Cleanup.statusesMaxAge:
|
||||
description: "Maximum age of feed entry statuses (read/unread) in the database.\
|
||||
\ Older statuses will be deleted.\n\n0 to disable."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.FeedRefresh.filteringExpressionEvaluationTimeout:
|
||||
description: "Duration after which the evaluation of a filtering expresion to\
|
||||
\ mark an entry as read is considered to have timed out."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.Database.Cleanup.maxFeedCapacity:
|
||||
description: "Maximum number of entries per feed to keep in the database.\n\n\
|
||||
0 to disable."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.FeedRefresh.maxInterval:
|
||||
description: "Maximum amount of time CommaFeed will wait before refreshing a feed.\
|
||||
\ This is used as an upper bound when:\n\n<ul>\n<li>an error occurs while refreshing\
|
||||
\ a feed and we're backing off exponentially</li>\n<li>we receive a Cache-Control\
|
||||
\ header from the feed</li>\n<li>we receive a Retry-After header from the feed</li>\n\
|
||||
</ul>"
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.Database.cleanup:
|
||||
description: "Database cleanup settings"
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.FeedRefresh.databaseThreads:
|
||||
description: "Amount of threads used to insert new entries in the database."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.HttpClient.connectTimeout:
|
||||
description: "Time to wait for a connection to be established."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.Database.Cleanup.batchSize:
|
||||
description: "Rows to delete per query while cleaning up old entries."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.HttpClient.responseTimeout:
|
||||
description: "Time to wait for the full response to be received."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.Users.strictPasswordPolicy:
|
||||
description: "Whether to enable strict password validation (1 uppercase char,\
|
||||
\ 1 lowercase char, 1 digit, 1 special char)."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.Database.Cleanup.maxFeedsPerUser:
|
||||
description: "Limit the number of feeds a user can subscribe to.\n\n0 to disable."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.database:
|
||||
description: "Database settings"
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.HttpClientCache.maximumMemorySize:
|
||||
description: "Maximum amount of memory the cache can use."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.HttpClient.sslHandshakeTimeout:
|
||||
description: "Time to wait for SSL handshake to complete."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.users:
|
||||
description: "Users settings"
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.FeedRefresh.intervalEmpirical:
|
||||
description: "If enabled, CommaFeed will calculate the next refresh time based\
|
||||
\ on the feed's average time between entries and the time since\nthe last entry\
|
||||
\ was published. The interval will be sometimes between the default refresh\
|
||||
\ interval\n(`commafeed.feed-refresh.interval`) and the maximum refresh interval\
|
||||
\ (`commafeed.feed-refresh.max-interval`).\n\nSee {@link FeedRefreshIntervalCalculator}\
|
||||
\ for details."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.feedRefresh:
|
||||
description: "Feed refresh engine settings"
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.googleAuthKey:
|
||||
description: "Google Auth key for fetching Youtube channel favicons."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.HttpClient.socketTimeout:
|
||||
description: "Time to wait between two packets before timeout."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.FeedRefresh.httpThreads:
|
||||
description: "Amount of http threads used to fetch feeds."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.HttpClient.connectionTimeToLive:
|
||||
description: "Time to live for a connection in the pool."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.HttpClient.cache:
|
||||
description: "HTTP client cache configuration"
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.websocket:
|
||||
description: "Websocket settings"
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.googleAnalyticsTrackingCode:
|
||||
description: "Google Analytics tracking code."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.Users.allowRegistrations:
|
||||
description: "Whether to let users create accounts for themselves."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.Websocket.treeReloadInterval:
|
||||
description: "If the websocket connection is disabled or the connection is lost,\
|
||||
\ the client will reload the feed tree at this interval."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.httpClient:
|
||||
description: "HTTP client configuration"
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.FeedRefresh.errors:
|
||||
description: "Feed refresh engine error handling settings"
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration:
|
||||
description: "CommaFeed configuration"
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.HttpClient.blockLocalAddresses:
|
||||
description: "Prevent access to local addresses to mitigate server-side request\
|
||||
\ forgery (SSRF) attacks, which could potentially expose internal\nresources.\n\
|
||||
\nYou may want to disable this if you subscribe to feeds that are only available\
|
||||
\ on your local network and you trust all users of\nyour CommaFeed instance."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.announcement:
|
||||
description: "Message displayed in a notification at the bottom of the page."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.HttpClientCache.expiration:
|
||||
description: "Duration after which an entry is removed from the cache."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.FeedRefreshErrorHandling.backoffInterval:
|
||||
description: "Duration to wait before retrying after an error. Will be multiplied\
|
||||
\ by the number of errors since the last successful fetch."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.Websocket.pingInterval:
|
||||
description: "Interval at which the client will send a ping message on the websocket\
|
||||
\ to keep the connection alive."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.FeedRefresh.interval:
|
||||
description: "Default amount of time CommaFeed will wait before refreshing a feed."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.FeedRefreshErrorHandling.retriesBeforeBackoff:
|
||||
description: "Number of retries before backoff is applied."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.Database.Cleanup.entriesMaxAge:
|
||||
description: "Maximum age of feed entries in the database. Older entries will\
|
||||
\ be deleted.\n\n0 to disable."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.HttpClientCache.enabled:
|
||||
description: "Whether to enable the cache. This cache is used to avoid spamming\
|
||||
\ feeds in short bursts (e.g. when subscribing to a feed for the\nfirst time\
|
||||
\ or when clicking \"fetch all my feeds now\")."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.HttpClient.idleConnectionsEvictionInterval:
|
||||
description: "Time between eviction runs for idle connections."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.FeedRefresh.userInactivityPeriod:
|
||||
description: "Duration after which a user is considered inactive. Feeds for inactive\
|
||||
\ users are not refreshed until they log in again.\n\n0 to disable."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.Users.createDemoAccount:
|
||||
description: "Whether to create a demo account the first time the app starts."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.hideFromWebCrawlers:
|
||||
description: "Whether to expose a robots.txt file that disallows web crawlers\
|
||||
\ and search engine indexers."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.Websocket.enabled:
|
||||
description: "Enable websocket connection so the server can notify web clients\
|
||||
\ that there are new entries for feeds."
|
||||
format: "JAVADOC"
|
||||
com.commafeed.CommaFeedConfiguration.HttpClient.userAgent:
|
||||
description: "User-Agent string that will be used by the http client, leave empty\
|
||||
\ for the default one."
|
||||
format: "JAVADOC"
|
||||
@@ -0,0 +1,538 @@
|
||||
---
|
||||
configRoots:
|
||||
- extension:
|
||||
groupId: "com.commafeed"
|
||||
artifactId: "commafeed-server"
|
||||
name: "CommaFeed Server"
|
||||
nameSource: "POM_XML"
|
||||
detected: true
|
||||
prefix: "commafeed"
|
||||
topLevelPrefix: "commafeed"
|
||||
items:
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration"
|
||||
sourceElementName: "hideFromWebCrawlers"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.hide-from-web-crawlers"
|
||||
environmentVariable: "COMMAFEED_HIDE_FROM_WEB_CRAWLERS"
|
||||
type: "boolean"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "boolean"
|
||||
defaultValue: "true"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration"
|
||||
sourceElementName: "imageProxyEnabled"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.image-proxy-enabled"
|
||||
environmentVariable: "COMMAFEED_IMAGE_PROXY_ENABLED"
|
||||
type: "boolean"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "boolean"
|
||||
defaultValue: "false"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration"
|
||||
sourceElementName: "passwordRecoveryEnabled"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.password-recovery-enabled"
|
||||
environmentVariable: "COMMAFEED_PASSWORD_RECOVERY_ENABLED"
|
||||
type: "boolean"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "boolean"
|
||||
defaultValue: "false"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration"
|
||||
sourceElementName: "announcement"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.announcement"
|
||||
environmentVariable: "COMMAFEED_ANNOUNCEMENT"
|
||||
type: "java.lang.String"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "string"
|
||||
optional: true
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration"
|
||||
sourceElementName: "googleAnalyticsTrackingCode"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.google-analytics-tracking-code"
|
||||
environmentVariable: "COMMAFEED_GOOGLE_ANALYTICS_TRACKING_CODE"
|
||||
type: "java.lang.String"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "string"
|
||||
optional: true
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration"
|
||||
sourceElementName: "googleAuthKey"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.google-auth-key"
|
||||
environmentVariable: "COMMAFEED_GOOGLE_AUTH_KEY"
|
||||
type: "java.lang.String"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "string"
|
||||
optional: true
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigSection>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration"
|
||||
sourceElementName: "httpClient"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigSection$SectionPath>
|
||||
property: "commafeed.http-client"
|
||||
type: "com.commafeed.CommaFeedConfiguration.HttpClient"
|
||||
items:
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.HttpClient"
|
||||
sourceElementName: "userAgent"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.http-client.user-agent"
|
||||
environmentVariable: "COMMAFEED_HTTP_CLIENT_USER_AGENT"
|
||||
type: "java.lang.String"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "string"
|
||||
optional: true
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.HttpClient"
|
||||
sourceElementName: "connectTimeout"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.http-client.connect-timeout"
|
||||
environmentVariable: "COMMAFEED_HTTP_CLIENT_CONNECT_TIMEOUT"
|
||||
type: "java.time.Duration"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "Duration"
|
||||
defaultValue: "5S"
|
||||
javadocSiteLink: "https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.HttpClient"
|
||||
sourceElementName: "sslHandshakeTimeout"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.http-client.ssl-handshake-timeout"
|
||||
environmentVariable: "COMMAFEED_HTTP_CLIENT_SSL_HANDSHAKE_TIMEOUT"
|
||||
type: "java.time.Duration"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "Duration"
|
||||
defaultValue: "5S"
|
||||
javadocSiteLink: "https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.HttpClient"
|
||||
sourceElementName: "socketTimeout"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.http-client.socket-timeout"
|
||||
environmentVariable: "COMMAFEED_HTTP_CLIENT_SOCKET_TIMEOUT"
|
||||
type: "java.time.Duration"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "Duration"
|
||||
defaultValue: "10S"
|
||||
javadocSiteLink: "https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.HttpClient"
|
||||
sourceElementName: "responseTimeout"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.http-client.response-timeout"
|
||||
environmentVariable: "COMMAFEED_HTTP_CLIENT_RESPONSE_TIMEOUT"
|
||||
type: "java.time.Duration"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "Duration"
|
||||
defaultValue: "10S"
|
||||
javadocSiteLink: "https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.HttpClient"
|
||||
sourceElementName: "connectionTimeToLive"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.http-client.connection-time-to-live"
|
||||
environmentVariable: "COMMAFEED_HTTP_CLIENT_CONNECTION_TIME_TO_LIVE"
|
||||
type: "java.time.Duration"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "Duration"
|
||||
defaultValue: "30S"
|
||||
javadocSiteLink: "https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.HttpClient"
|
||||
sourceElementName: "idleConnectionsEvictionInterval"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.http-client.idle-connections-eviction-interval"
|
||||
environmentVariable: "COMMAFEED_HTTP_CLIENT_IDLE_CONNECTIONS_EVICTION_INTERVAL"
|
||||
type: "java.time.Duration"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "Duration"
|
||||
defaultValue: "1M"
|
||||
javadocSiteLink: "https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.HttpClient"
|
||||
sourceElementName: "maxResponseSize"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.http-client.max-response-size"
|
||||
environmentVariable: "COMMAFEED_HTTP_CLIENT_MAX_RESPONSE_SIZE"
|
||||
type: "io.quarkus.runtime.configuration.MemorySize"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "MemorySize"
|
||||
defaultValue: "5M"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.HttpClient"
|
||||
sourceElementName: "blockLocalAddresses"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.http-client.block-local-addresses"
|
||||
environmentVariable: "COMMAFEED_HTTP_CLIENT_BLOCK_LOCAL_ADDRESSES"
|
||||
type: "boolean"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "boolean"
|
||||
defaultValue: "true"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigSection>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.HttpClient"
|
||||
sourceElementName: "cache"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigSection$SectionPath>
|
||||
property: "commafeed.http-client.cache"
|
||||
type: "com.commafeed.CommaFeedConfiguration.HttpClientCache"
|
||||
items:
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.HttpClientCache"
|
||||
sourceElementName: "enabled"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.http-client.cache.enabled"
|
||||
environmentVariable: "COMMAFEED_HTTP_CLIENT_CACHE_ENABLED"
|
||||
type: "boolean"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "boolean"
|
||||
defaultValue: "true"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.HttpClientCache"
|
||||
sourceElementName: "maximumMemorySize"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.http-client.cache.maximum-memory-size"
|
||||
environmentVariable: "COMMAFEED_HTTP_CLIENT_CACHE_MAXIMUM_MEMORY_SIZE"
|
||||
type: "io.quarkus.runtime.configuration.MemorySize"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "MemorySize"
|
||||
defaultValue: "10M"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.HttpClientCache"
|
||||
sourceElementName: "expiration"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.http-client.cache.expiration"
|
||||
environmentVariable: "COMMAFEED_HTTP_CLIENT_CACHE_EXPIRATION"
|
||||
type: "java.time.Duration"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "Duration"
|
||||
defaultValue: "1M"
|
||||
javadocSiteLink: "https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html"
|
||||
level: 1
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigSection>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration"
|
||||
sourceElementName: "feedRefresh"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigSection$SectionPath>
|
||||
property: "commafeed.feed-refresh"
|
||||
type: "com.commafeed.CommaFeedConfiguration.FeedRefresh"
|
||||
items:
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.FeedRefresh"
|
||||
sourceElementName: "interval"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.feed-refresh.interval"
|
||||
environmentVariable: "COMMAFEED_FEED_REFRESH_INTERVAL"
|
||||
type: "java.time.Duration"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "Duration"
|
||||
defaultValue: "5M"
|
||||
javadocSiteLink: "https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.FeedRefresh"
|
||||
sourceElementName: "maxInterval"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.feed-refresh.max-interval"
|
||||
environmentVariable: "COMMAFEED_FEED_REFRESH_MAX_INTERVAL"
|
||||
type: "java.time.Duration"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "Duration"
|
||||
defaultValue: "4H"
|
||||
javadocSiteLink: "https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.FeedRefresh"
|
||||
sourceElementName: "intervalEmpirical"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.feed-refresh.interval-empirical"
|
||||
environmentVariable: "COMMAFEED_FEED_REFRESH_INTERVAL_EMPIRICAL"
|
||||
type: "boolean"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "boolean"
|
||||
defaultValue: "true"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigSection>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.FeedRefresh"
|
||||
sourceElementName: "errors"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigSection$SectionPath>
|
||||
property: "commafeed.feed-refresh.errors"
|
||||
type: "com.commafeed.CommaFeedConfiguration.FeedRefreshErrorHandling"
|
||||
items:
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.FeedRefreshErrorHandling"
|
||||
sourceElementName: "retriesBeforeBackoff"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.feed-refresh.errors.retries-before-backoff"
|
||||
environmentVariable: "COMMAFEED_FEED_REFRESH_ERRORS_RETRIES_BEFORE_BACKOFF"
|
||||
type: "int"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "int"
|
||||
defaultValue: "3"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.FeedRefreshErrorHandling"
|
||||
sourceElementName: "backoffInterval"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.feed-refresh.errors.backoff-interval"
|
||||
environmentVariable: "COMMAFEED_FEED_REFRESH_ERRORS_BACKOFF_INTERVAL"
|
||||
type: "java.time.Duration"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "Duration"
|
||||
defaultValue: "1H"
|
||||
javadocSiteLink: "https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html"
|
||||
level: 1
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.FeedRefresh"
|
||||
sourceElementName: "httpThreads"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.feed-refresh.http-threads"
|
||||
environmentVariable: "COMMAFEED_FEED_REFRESH_HTTP_THREADS"
|
||||
type: "int"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "int"
|
||||
defaultValue: "3"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.FeedRefresh"
|
||||
sourceElementName: "databaseThreads"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.feed-refresh.database-threads"
|
||||
environmentVariable: "COMMAFEED_FEED_REFRESH_DATABASE_THREADS"
|
||||
type: "int"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "int"
|
||||
defaultValue: "1"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.FeedRefresh"
|
||||
sourceElementName: "userInactivityPeriod"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.feed-refresh.user-inactivity-period"
|
||||
environmentVariable: "COMMAFEED_FEED_REFRESH_USER_INACTIVITY_PERIOD"
|
||||
type: "java.time.Duration"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "Duration"
|
||||
defaultValue: "0S"
|
||||
javadocSiteLink: "https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.FeedRefresh"
|
||||
sourceElementName: "filteringExpressionEvaluationTimeout"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.feed-refresh.filtering-expression-evaluation-timeout"
|
||||
environmentVariable: "COMMAFEED_FEED_REFRESH_FILTERING_EXPRESSION_EVALUATION_TIMEOUT"
|
||||
type: "java.time.Duration"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "Duration"
|
||||
defaultValue: "500MS"
|
||||
javadocSiteLink: "https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.FeedRefresh"
|
||||
sourceElementName: "forceRefreshCooldownDuration"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.feed-refresh.force-refresh-cooldown-duration"
|
||||
environmentVariable: "COMMAFEED_FEED_REFRESH_FORCE_REFRESH_COOLDOWN_DURATION"
|
||||
type: "java.time.Duration"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "Duration"
|
||||
defaultValue: "0S"
|
||||
javadocSiteLink: "https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigSection>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration"
|
||||
sourceElementName: "database"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigSection$SectionPath>
|
||||
property: "commafeed.database"
|
||||
type: "com.commafeed.CommaFeedConfiguration.Database"
|
||||
items:
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.Database"
|
||||
sourceElementName: "queryTimeout"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.database.query-timeout"
|
||||
environmentVariable: "COMMAFEED_DATABASE_QUERY_TIMEOUT"
|
||||
type: "java.time.Duration"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "Duration"
|
||||
defaultValue: "0S"
|
||||
javadocSiteLink: "https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigSection>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.Database"
|
||||
sourceElementName: "cleanup"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigSection$SectionPath>
|
||||
property: "commafeed.database.cleanup"
|
||||
type: "com.commafeed.CommaFeedConfiguration.Database.Cleanup"
|
||||
items:
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.Database.Cleanup"
|
||||
sourceElementName: "entriesMaxAge"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.database.cleanup.entries-max-age"
|
||||
environmentVariable: "COMMAFEED_DATABASE_CLEANUP_ENTRIES_MAX_AGE"
|
||||
type: "java.time.Duration"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "Duration"
|
||||
defaultValue: "365D"
|
||||
javadocSiteLink: "https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.Database.Cleanup"
|
||||
sourceElementName: "statusesMaxAge"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.database.cleanup.statuses-max-age"
|
||||
environmentVariable: "COMMAFEED_DATABASE_CLEANUP_STATUSES_MAX_AGE"
|
||||
type: "java.time.Duration"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "Duration"
|
||||
defaultValue: "0S"
|
||||
javadocSiteLink: "https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.Database.Cleanup"
|
||||
sourceElementName: "maxFeedCapacity"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.database.cleanup.max-feed-capacity"
|
||||
environmentVariable: "COMMAFEED_DATABASE_CLEANUP_MAX_FEED_CAPACITY"
|
||||
type: "int"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "int"
|
||||
defaultValue: "500"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.Database.Cleanup"
|
||||
sourceElementName: "maxFeedsPerUser"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.database.cleanup.max-feeds-per-user"
|
||||
environmentVariable: "COMMAFEED_DATABASE_CLEANUP_MAX_FEEDS_PER_USER"
|
||||
type: "int"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "int"
|
||||
defaultValue: "0"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.Database.Cleanup"
|
||||
sourceElementName: "batchSize"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.database.cleanup.batch-size"
|
||||
environmentVariable: "COMMAFEED_DATABASE_CLEANUP_BATCH_SIZE"
|
||||
type: "int"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "int"
|
||||
defaultValue: "100"
|
||||
level: 1
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigSection>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration"
|
||||
sourceElementName: "users"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigSection$SectionPath>
|
||||
property: "commafeed.users"
|
||||
type: "com.commafeed.CommaFeedConfiguration.Users"
|
||||
items:
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.Users"
|
||||
sourceElementName: "allowRegistrations"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.users.allow-registrations"
|
||||
environmentVariable: "COMMAFEED_USERS_ALLOW_REGISTRATIONS"
|
||||
type: "boolean"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "boolean"
|
||||
defaultValue: "false"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.Users"
|
||||
sourceElementName: "strictPasswordPolicy"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.users.strict-password-policy"
|
||||
environmentVariable: "COMMAFEED_USERS_STRICT_PASSWORD_POLICY"
|
||||
type: "boolean"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "boolean"
|
||||
defaultValue: "true"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.Users"
|
||||
sourceElementName: "createDemoAccount"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.users.create-demo-account"
|
||||
environmentVariable: "COMMAFEED_USERS_CREATE_DEMO_ACCOUNT"
|
||||
type: "boolean"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "boolean"
|
||||
defaultValue: "false"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigSection>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration"
|
||||
sourceElementName: "websocket"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigSection$SectionPath>
|
||||
property: "commafeed.websocket"
|
||||
type: "com.commafeed.CommaFeedConfiguration.Websocket"
|
||||
items:
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.Websocket"
|
||||
sourceElementName: "enabled"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.websocket.enabled"
|
||||
environmentVariable: "COMMAFEED_WEBSOCKET_ENABLED"
|
||||
type: "boolean"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "boolean"
|
||||
defaultValue: "true"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.Websocket"
|
||||
sourceElementName: "pingInterval"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.websocket.ping-interval"
|
||||
environmentVariable: "COMMAFEED_WEBSOCKET_PING_INTERVAL"
|
||||
type: "java.time.Duration"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "Duration"
|
||||
defaultValue: "15M"
|
||||
javadocSiteLink: "https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html"
|
||||
- !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty>
|
||||
sourceType: "com.commafeed.CommaFeedConfiguration.Websocket"
|
||||
sourceElementName: "treeReloadInterval"
|
||||
sourceElementType: "METHOD"
|
||||
path: !<io.quarkus.annotation.processor.documentation.config.model.ConfigProperty$PropertyPath>
|
||||
property: "commafeed.websocket.tree-reload-interval"
|
||||
environmentVariable: "COMMAFEED_WEBSOCKET_TREE_RELOAD_INTERVAL"
|
||||
type: "java.time.Duration"
|
||||
phase: "RUN_TIME"
|
||||
typeDescription: "Duration"
|
||||
defaultValue: "30S"
|
||||
javadocSiteLink: "https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html"
|
||||
qualifiedNames:
|
||||
- "com.commafeed.CommaFeedConfiguration"
|
||||
Reference in New Issue
Block a user