fix formatting

This commit is contained in:
Athou
2022-01-02 20:55:46 +01:00
parent 089be99287
commit 4021389a4d
56 changed files with 563 additions and 562 deletions

View File

@@ -21,36 +21,36 @@ import lombok.Getter;
@Getter @Getter
public class CommaFeedConfiguration extends Configuration { public class CommaFeedConfiguration extends Configuration {
public static enum CacheType { public enum CacheType {
NOOP, REDIS NOOP, REDIS
} }
private ResourceBundle bundle;
public CommaFeedConfiguration() {
bundle = ResourceBundle.getBundle("application");
}
@Valid @Valid
@NotNull @NotNull
@JsonProperty("database") @JsonProperty("database")
private DataSourceFactory dataSourceFactory = new DataSourceFactory(); private final DataSourceFactory dataSourceFactory = new DataSourceFactory();
@Valid @Valid
@NotNull @NotNull
@JsonProperty("redis") @JsonProperty("redis")
private RedisPoolFactory redisPoolFactory = new RedisPoolFactory(); private final RedisPoolFactory redisPoolFactory = new RedisPoolFactory();
@Valid @Valid
@NotNull @NotNull
@JsonProperty("session") @JsonProperty("session")
private SessionHandlerFactory SessionHandlerFactory = new SessionHandlerFactory(); private final SessionHandlerFactory sessionHandlerFactory = new SessionHandlerFactory();
@Valid @Valid
@NotNull @NotNull
@JsonProperty("app") @JsonProperty("app")
private ApplicationSettings applicationSettings; private ApplicationSettings applicationSettings;
private final ResourceBundle bundle;
public CommaFeedConfiguration() {
bundle = ResourceBundle.getBundle("application");
}
public String getVersion() { public String getVersion() {
return bundle.getString("version"); return bundle.getString("version");
} }

View File

@@ -2,16 +2,13 @@ package com.commafeed;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.SessionFactory; import org.hibernate.SessionFactory;
import com.codahale.metrics.MetricFilter;
import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.graphite.Graphite; import com.codahale.metrics.graphite.Graphite;
import com.codahale.metrics.graphite.GraphiteReporter; import com.codahale.metrics.graphite.GraphiteReporter;
import com.codahale.metrics.MetricFilter;
import com.commafeed.CommaFeedConfiguration.ApplicationSettings; import com.commafeed.CommaFeedConfiguration.ApplicationSettings;
import com.commafeed.CommaFeedConfiguration.CacheType; import com.commafeed.CommaFeedConfiguration.CacheType;
import com.commafeed.backend.cache.CacheService; import com.commafeed.backend.cache.CacheService;
@@ -33,6 +30,10 @@ import com.google.inject.AbstractModule;
import com.google.inject.Provides; import com.google.inject.Provides;
import com.google.inject.multibindings.Multibinder; import com.google.inject.multibindings.Multibinder;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j @Slf4j
public class CommaFeedModule extends AbstractModule { public class CommaFeedModule extends AbstractModule {
@@ -76,7 +77,8 @@ public class CommaFeedModule extends AbstractModule {
final int graphitePort = settings.getGraphitePort(); final int graphitePort = settings.getGraphitePort();
final int graphiteInterval = settings.getGraphiteInterval(); final int graphiteInterval = settings.getGraphiteInterval();
log.info("Graphite Metrics will be sent to host={}, port={}, prefix={}, interval={}sec", graphiteHost, graphitePort, graphitePrefix, graphiteInterval); log.info("Graphite Metrics will be sent to host={}, port={}, prefix={}, interval={}sec", graphiteHost, graphitePort,
graphitePrefix, graphiteInterval);
final Graphite graphite = new Graphite(new InetSocketAddress(graphiteHost, graphitePort)); final Graphite graphite = new Graphite(new InetSocketAddress(graphiteHost, graphitePort));
final GraphiteReporter reporter = GraphiteReporter.forRegistry(metrics) final GraphiteReporter reporter = GraphiteReporter.forRegistry(metrics)

View File

@@ -5,12 +5,6 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Pipeline;
import com.commafeed.backend.model.Feed; import com.commafeed.backend.model.Feed;
import com.commafeed.backend.model.FeedSubscription; import com.commafeed.backend.model.FeedSubscription;
import com.commafeed.backend.model.Models; import com.commafeed.backend.model.Models;
@@ -20,11 +14,17 @@ import com.commafeed.frontend.model.UnreadCount;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Pipeline;
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
public class RedisCacheService extends CacheService { public class RedisCacheService extends CacheService {
private static ObjectMapper MAPPER = new ObjectMapper(); private static final ObjectMapper MAPPER = new ObjectMapper();
private final JedisPool pool; private final JedisPool pool;

View File

@@ -1,22 +1,21 @@
package com.commafeed.backend.cache; package com.commafeed.backend.cache;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import lombok.Getter;
import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Protocol; import redis.clients.jedis.Protocol;
@Getter @Getter
public class RedisPoolFactory { public class RedisPoolFactory {
private String host = "localhost"; private final String host = "localhost";
private int port = Protocol.DEFAULT_PORT; private final int port = Protocol.DEFAULT_PORT;
private String password = null; private String password;
private int timeout = Protocol.DEFAULT_TIMEOUT; private final int timeout = Protocol.DEFAULT_TIMEOUT;
private int database = Protocol.DEFAULT_DATABASE; private final int database = Protocol.DEFAULT_DATABASE;
private int maxTotal = 500; private final int maxTotal = 500;
public JedisPool build() { public JedisPool build() {
JedisPoolConfig config = new JedisPoolConfig(); JedisPoolConfig config = new JedisPoolConfig();

View File

@@ -38,6 +38,18 @@ import com.querydsl.jpa.impl.JPAQuery;
@Singleton @Singleton
public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> { public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
private static final Comparator<FeedEntryStatus> STATUS_COMPARATOR_DESC = new Comparator<FeedEntryStatus>() {
@Override
public int compare(FeedEntryStatus o1, FeedEntryStatus o2) {
CompareToBuilder builder = new CompareToBuilder();
builder.append(o2.getEntryUpdated(), o1.getEntryUpdated());
builder.append(o2.getId(), o1.getId());
return builder.toComparison();
}
};
private static final Comparator<FeedEntryStatus> STATUS_COMPARATOR_ASC = Ordering.from(STATUS_COMPARATOR_DESC).reverse();
private final FeedEntryDAO feedEntryDAO; private final FeedEntryDAO feedEntryDAO;
private final FeedEntryTagDAO feedEntryTagDAO; private final FeedEntryTagDAO feedEntryTagDAO;
private final CommaFeedConfiguration config; private final CommaFeedConfiguration config;
@@ -56,18 +68,6 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
this.config = config; this.config = config;
} }
private static final Comparator<FeedEntryStatus> STATUS_COMPARATOR_DESC = new Comparator<FeedEntryStatus>() {
@Override
public int compare(FeedEntryStatus o1, FeedEntryStatus o2) {
CompareToBuilder builder = new CompareToBuilder();
builder.append(o2.getEntryUpdated(), o1.getEntryUpdated());
builder.append(o2.getId(), o1.getId());
return builder.toComparison();
}
};
private static final Comparator<FeedEntryStatus> STATUS_COMPARATOR_ASC = Ordering.from(STATUS_COMPARATOR_DESC).reverse();
public FeedEntryStatus getStatus(User user, FeedSubscription sub, FeedEntry entry) { public FeedEntryStatus getStatus(User user, FeedSubscription sub, FeedEntry entry) {
List<FeedEntryStatus> statuses = query().selectFrom(status).where(status.entry.eq(entry), status.subscription.eq(sub)).fetch(); List<FeedEntryStatus> statuses = query().selectFrom(status).where(status.entry.eq(entry), status.subscription.eq(sub)).fetch();
FeedEntryStatus status = Iterables.getFirst(statuses, null); FeedEntryStatus status = Iterables.getFirst(statuses, null);

View File

@@ -7,16 +7,6 @@ import org.hibernate.context.internal.ManagedSessionContext;
public class UnitOfWork { public class UnitOfWork {
@FunctionalInterface
public static interface SessionRunner {
public void runInSession();
}
@FunctionalInterface
public static interface SessionRunnerReturningValue<T> {
public T runInSession();
}
public static void run(SessionFactory sessionFactory, SessionRunner sessionRunner) { public static void run(SessionFactory sessionFactory, SessionRunner sessionRunner) {
call(sessionFactory, () -> { call(sessionFactory, () -> {
sessionRunner.runInSession(); sessionRunner.runInSession();
@@ -66,4 +56,14 @@ public class UnitOfWork {
throw (E) e; throw (E) e;
} }
@FunctionalInterface
public interface SessionRunner {
void runInSession();
}
@FunctionalInterface
public interface SessionRunnerReturningValue<T> {
T runInSession();
}
} }

View File

@@ -3,22 +3,22 @@ package com.commafeed.backend.favicon;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import com.commafeed.backend.model.Feed; import com.commafeed.backend.model.Feed;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
public abstract class AbstractFaviconFetcher { public abstract class AbstractFaviconFetcher {
private static List<String> ICON_MIMETYPE_BLACKLIST = Arrays.asList("application/xml", "text/html"); protected static final int TIMEOUT = 4000;
private static long MIN_ICON_LENGTH = 100;
private static long MAX_ICON_LENGTH = 100000;
protected static int TIMEOUT = 4000; private static final List<String> ICON_MIMETYPE_BLACKLIST = Arrays.asList("application/xml", "text/html");
private static final long MIN_ICON_LENGTH = 100;
private static final long MAX_ICON_LENGTH = 100000;
public abstract Favicon fetch(Feed feed); public abstract Favicon fetch(Feed feed);

View File

@@ -3,9 +3,6 @@ package com.commafeed.backend.favicon;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
@@ -16,6 +13,9 @@ import com.commafeed.backend.HttpGetter.HttpResult;
import com.commafeed.backend.feed.FeedUtils; import com.commafeed.backend.feed.FeedUtils;
import com.commafeed.backend.model.Feed; import com.commafeed.backend.model.Feed;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
/** /**
* Inspired/Ported from https://github.com/potatolondon/getfavicon * Inspired/Ported from https://github.com/potatolondon/getfavicon
* *

View File

@@ -8,9 +8,6 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.NameValuePair; import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.client.utils.URLEncodedUtils;
@@ -18,6 +15,9 @@ import com.commafeed.backend.HttpGetter;
import com.commafeed.backend.HttpGetter.HttpResult; import com.commafeed.backend.HttpGetter.HttpResult;
import com.commafeed.backend.model.Feed; import com.commafeed.backend.model.Feed;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
@RequiredArgsConstructor(onConstructor = @__({ @Inject })) @RequiredArgsConstructor(onConstructor = @__({ @Inject }))
@Singleton @Singleton

View File

@@ -28,7 +28,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
@RequiredArgsConstructor(onConstructor = @__({ @Inject }) ) @RequiredArgsConstructor(onConstructor = @__({ @Inject }))
@Singleton @Singleton
public class YoutubeFaviconFetcher extends AbstractFaviconFetcher { public class YoutubeFaviconFetcher extends AbstractFaviconFetcher {

View File

@@ -3,11 +3,11 @@ package com.commafeed.backend.feed;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.commons.lang3.StringUtils;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
/** /**
* A keyword used in a search query * A keyword used in a search query
*/ */
@@ -15,7 +15,7 @@ import org.apache.commons.lang3.StringUtils;
@RequiredArgsConstructor @RequiredArgsConstructor
public class FeedEntryKeyword { public class FeedEntryKeyword {
public static enum Mode { public enum Mode {
INCLUDE, EXCLUDE; INCLUDE, EXCLUDE;
} }

View File

@@ -86,9 +86,10 @@ public class FeedFetcher {
private static String extractFeedUrl(Set<FeedURLProvider> urlProviders, String url, String urlContent) { private static String extractFeedUrl(Set<FeedURLProvider> urlProviders, String url, String urlContent) {
for (FeedURLProvider urlProvider : urlProviders) { for (FeedURLProvider urlProvider : urlProviders) {
String feedUrl = urlProvider.get(url, urlContent); String feedUrl = urlProvider.get(url, urlContent);
if (feedUrl != null) if (feedUrl != null) {
return feedUrl; return feedUrl;
} }
}
return null; return null;
} }

View File

@@ -48,7 +48,7 @@ public class FeedParser {
private static final Namespace ATOM_10_NS = Namespace.getNamespace(ATOM_10_URI); private static final Namespace ATOM_10_NS = Namespace.getNamespace(ATOM_10_URI);
private static final Date START = new Date(86400000); private static final Date START = new Date(86400000);
private static final Date END = new Date(1000l * Integer.MAX_VALUE - 86400000); private static final Date END = new Date(1000L * Integer.MAX_VALUE - 86400000);
public FetchedFeed parse(String feedUrl, byte[] xml) throws FeedException { public FetchedFeed parse(String feedUrl, byte[] xml) throws FeedException {
FetchedFeed fetchedFeed = new FetchedFeed(); FetchedFeed fetchedFeed = new FetchedFeed();

View File

@@ -2,12 +2,12 @@ package com.commafeed.backend.feed;
import java.util.List; import java.util.List;
import lombok.Getter;
import lombok.Setter;
import com.commafeed.backend.model.Feed; import com.commafeed.backend.model.Feed;
import com.commafeed.backend.model.FeedEntry; import com.commafeed.backend.model.FeedEntry;
import lombok.Getter;
import lombok.Setter;
@Getter @Getter
@Setter @Setter
public class FeedRefreshContext { public class FeedRefreshContext {

View File

@@ -81,10 +81,6 @@ public class FeedRefreshExecutor {
pool.execute(task); pool.execute(task);
} }
public static interface Task extends Runnable {
boolean isUrgent();
}
public void shutdown() { public void shutdown() {
pool.shutdownNow(); pool.shutdownNow();
while (!pool.isTerminated()) { while (!pool.isTerminated()) {
@@ -95,4 +91,9 @@ public class FeedRefreshExecutor {
} }
} }
} }
public interface Task extends Runnable {
boolean isUrgent();
}
} }

View File

@@ -1,20 +1,19 @@
package com.commafeed.backend.feed; package com.commafeed.backend.feed;
import io.dropwizard.lifecycle.Managed;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import com.codahale.metrics.Meter; import com.codahale.metrics.Meter;
import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.MetricRegistry;
import com.commafeed.CommaFeedConfiguration; import com.commafeed.CommaFeedConfiguration;
import com.commafeed.backend.dao.FeedDAO; import com.commafeed.backend.dao.FeedDAO;
import io.dropwizard.lifecycle.Managed;
import lombok.extern.slf4j.Slf4j;
/** /**
* Infinite loop fetching feeds from @FeedQueues and queuing them to the {@link FeedRefreshWorker} pool. * Infinite loop fetching feeds from @FeedQueues and queuing them to the {@link FeedRefreshWorker} pool.
* *
@@ -26,10 +25,10 @@ public class FeedRefreshTaskGiver implements Managed {
private final FeedQueues queues; private final FeedQueues queues;
private final FeedRefreshWorker worker; private final FeedRefreshWorker worker;
private ExecutorService executor; private final ExecutorService executor;
private Meter feedRefreshed; private final Meter feedRefreshed;
private Meter threadWaited; private final Meter threadWaited;
@Inject @Inject
public FeedRefreshTaskGiver(FeedQueues queues, FeedDAO feedDAO, FeedRefreshWorker worker, CommaFeedConfiguration config, public FeedRefreshTaskGiver(FeedQueues queues, FeedDAO feedDAO, FeedRefreshWorker worker, CommaFeedConfiguration config,

View File

@@ -49,13 +49,13 @@ public class FeedRefreshUpdater implements Managed {
private final FeedSubscriptionDAO feedSubscriptionDAO; private final FeedSubscriptionDAO feedSubscriptionDAO;
private final CacheService cache; private final CacheService cache;
private FeedRefreshExecutor pool; private final FeedRefreshExecutor pool;
private Striped<Lock> locks; private final Striped<Lock> locks;
private Meter entryCacheMiss; private final Meter entryCacheMiss;
private Meter entryCacheHit; private final Meter entryCacheHit;
private Meter feedUpdated; private final Meter feedUpdated;
private Meter entryInserted; private final Meter entryInserted;
@Inject @Inject
public FeedRefreshUpdater(SessionFactory sessionFactory, FeedUpdateService feedUpdateService, PubSubService pubSubService, public FeedRefreshUpdater(SessionFactory sessionFactory, FeedUpdateService feedUpdateService, PubSubService pubSubService,
@@ -94,70 +94,6 @@ public class FeedRefreshUpdater implements Managed {
pool.execute(new EntryTask(context)); pool.execute(new EntryTask(context));
} }
private class EntryTask implements Task {
private FeedRefreshContext context;
public EntryTask(FeedRefreshContext context) {
this.context = context;
}
@Override
public void run() {
boolean ok = true;
final Feed feed = context.getFeed();
List<FeedEntry> entries = context.getEntries();
if (entries.isEmpty()) {
feed.setMessage("Feed has no entries");
} else {
List<String> lastEntries = cache.getLastEntries(feed);
List<String> currentEntries = new ArrayList<>();
List<FeedSubscription> subscriptions = null;
for (FeedEntry entry : entries) {
String cacheKey = cache.buildUniqueEntryKey(feed, entry);
if (!lastEntries.contains(cacheKey)) {
log.debug("cache miss for {}", entry.getUrl());
if (subscriptions == null) {
subscriptions = UnitOfWork.call(sessionFactory, () -> feedSubscriptionDAO.findByFeed(feed));
}
ok &= addEntry(feed, entry, subscriptions);
entryCacheMiss.mark();
} else {
log.debug("cache hit for {}", entry.getUrl());
entryCacheHit.mark();
}
currentEntries.add(cacheKey);
}
cache.setLastEntries(feed, currentEntries);
if (subscriptions == null) {
feed.setMessage("No new entries found");
} else if (!subscriptions.isEmpty()) {
List<User> users = subscriptions.stream().map(s -> s.getUser()).collect(Collectors.toList());
cache.invalidateUnreadCount(subscriptions.toArray(new FeedSubscription[0]));
cache.invalidateUserRootCategory(users.toArray(new User[0]));
}
}
if (config.getApplicationSettings().getPubsubhubbub()) {
handlePubSub(feed);
}
if (!ok) {
// requeue asap
feed.setDisabledUntil(new Date(0));
}
feedUpdated.mark();
queues.giveBack(feed);
}
@Override
public boolean isUrgent() {
return context.isUrgent();
}
}
private boolean addEntry(final Feed feed, final FeedEntry entry, final List<FeedSubscription> subscriptions) { private boolean addEntry(final Feed feed, final FeedEntry entry, final List<FeedSubscription> subscriptions) {
boolean success = false; boolean success = false;
@@ -223,4 +159,68 @@ public class FeedRefreshUpdater implements Managed {
} }
} }
private class EntryTask implements Task {
private final FeedRefreshContext context;
public EntryTask(FeedRefreshContext context) {
this.context = context;
}
@Override
public void run() {
boolean ok = true;
final Feed feed = context.getFeed();
List<FeedEntry> entries = context.getEntries();
if (entries.isEmpty()) {
feed.setMessage("Feed has no entries");
} else {
List<String> lastEntries = cache.getLastEntries(feed);
List<String> currentEntries = new ArrayList<>();
List<FeedSubscription> subscriptions = null;
for (FeedEntry entry : entries) {
String cacheKey = cache.buildUniqueEntryKey(feed, entry);
if (!lastEntries.contains(cacheKey)) {
log.debug("cache miss for {}", entry.getUrl());
if (subscriptions == null) {
subscriptions = UnitOfWork.call(sessionFactory, () -> feedSubscriptionDAO.findByFeed(feed));
}
ok &= addEntry(feed, entry, subscriptions);
entryCacheMiss.mark();
} else {
log.debug("cache hit for {}", entry.getUrl());
entryCacheHit.mark();
}
currentEntries.add(cacheKey);
}
cache.setLastEntries(feed, currentEntries);
if (subscriptions == null) {
feed.setMessage("No new entries found");
} else if (!subscriptions.isEmpty()) {
List<User> users = subscriptions.stream().map(FeedSubscription::getUser).collect(Collectors.toList());
cache.invalidateUnreadCount(subscriptions.toArray(new FeedSubscription[0]));
cache.invalidateUserRootCategory(users.toArray(new User[0]));
}
}
if (config.getApplicationSettings().getPubsubhubbub()) {
handlePubSub(feed);
}
if (!ok) {
// requeue asap
feed.setDisabledUntil(new Date(0));
}
feedUpdated.mark();
queues.giveBack(feed);
}
@Override
public boolean isUrgent() {
return context.isUrgent();
}
}
} }

View File

@@ -1,7 +1,5 @@
package com.commafeed.backend.feed; package com.commafeed.backend.feed;
import io.dropwizard.lifecycle.Managed;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@@ -10,8 +8,6 @@ import java.util.stream.Collectors;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.DateUtils;
@@ -23,6 +19,9 @@ import com.commafeed.backend.feed.FeedRefreshExecutor.Task;
import com.commafeed.backend.model.Feed; import com.commafeed.backend.model.Feed;
import com.commafeed.backend.model.FeedEntry; import com.commafeed.backend.model.FeedEntry;
import io.dropwizard.lifecycle.Managed;
import lombok.extern.slf4j.Slf4j;
/** /**
* Calls {@link FeedFetcher} and handles its outcome * Calls {@link FeedFetcher} and handles its outcome
* *
@@ -61,25 +60,6 @@ public class FeedRefreshWorker implements Managed {
pool.execute(new FeedTask(context)); pool.execute(new FeedTask(context));
} }
private class FeedTask implements Task {
private FeedRefreshContext context;
public FeedTask(FeedRefreshContext context) {
this.context = context;
}
@Override
public void run() {
update(context);
}
@Override
public boolean isUrgent() {
return context.isUrgent();
}
}
private void update(FeedRefreshContext context) { private void update(FeedRefreshContext context) {
Feed feed = context.getFeed(); Feed feed = context.getFeed();
int refreshInterval = config.getApplicationSettings().getRefreshIntervalMinutes(); int refreshInterval = config.getApplicationSettings().getRefreshIntervalMinutes();
@@ -97,8 +77,8 @@ public class FeedRefreshWorker implements Managed {
} }
if (config.getApplicationSettings().getHeavyLoad()) { if (config.getApplicationSettings().getHeavyLoad()) {
disabledUntil = FeedUtils.buildDisabledUntil(fetchedFeed.getFeed().getLastEntryDate(), fetchedFeed.getFeed() disabledUntil = FeedUtils.buildDisabledUntil(fetchedFeed.getFeed().getLastEntryDate(),
.getAverageEntryInterval(), disabledUntil); fetchedFeed.getFeed().getAverageEntryInterval(), disabledUntil);
} }
String urlAfterRedirect = fetchedFeed.getUrlAfterRedirect(); String urlAfterRedirect = fetchedFeed.getUrlAfterRedirect();
if (StringUtils.equals(url, urlAfterRedirect)) { if (StringUtils.equals(url, urlAfterRedirect)) {
@@ -156,7 +136,7 @@ public class FeedRefreshWorker implements Managed {
topic = "http://" + topic; topic = "http://" + topic;
} else if (topic.startsWith("feed://")) { } else if (topic.startsWith("feed://")) {
topic = "http://" + topic.substring(7); topic = "http://" + topic.substring(7);
} else if (topic.startsWith("http") == false) { } else if (!topic.startsWith("http")) {
topic = "http://" + topic; topic = "http://" + topic;
} }
log.debug("feed {} has pubsub info: {}", feed.getUrl(), topic); log.debug("feed {} has pubsub info: {}", feed.getUrl(), topic);
@@ -165,4 +145,23 @@ public class FeedRefreshWorker implements Managed {
feed.setPushTopicHash(DigestUtils.sha1Hex(topic)); feed.setPushTopicHash(DigestUtils.sha1Hex(topic));
} }
} }
private class FeedTask implements Task {
private final FeedRefreshContext context;
public FeedTask(FeedRefreshContext context) {
this.context = context;
}
@Override
public void run() {
update(context);
}
@Override
public boolean isUrgent() {
return context.isUrgent();
}
}
} }

View File

@@ -110,7 +110,7 @@ public class FeedUtils {
public static Charset guessEncoding(byte[] bytes) { public static Charset guessEncoding(byte[] bytes) {
String extracted = extractDeclaredEncoding(bytes); String extracted = extractDeclaredEncoding(bytes);
if (StringUtils.startsWithIgnoreCase(extracted, "iso-8859-")) { if (StringUtils.startsWithIgnoreCase(extracted, "iso-8859-")) {
if (StringUtils.endsWith(extracted, "1") == false) { if (!StringUtils.endsWith(extracted, "1")) {
return Charset.forName(extracted); return Charset.forName(extracted);
} }
} else if (StringUtils.startsWithIgnoreCase(extracted, "windows-")) { } else if (StringUtils.startsWithIgnoreCase(extracted, "windows-")) {

View File

@@ -3,12 +3,12 @@ package com.commafeed.backend.feed;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import lombok.Getter;
import lombok.Setter;
import com.commafeed.backend.model.Feed; import com.commafeed.backend.model.Feed;
import com.commafeed.backend.model.FeedEntry; import com.commafeed.backend.model.FeedEntry;
import lombok.Getter;
import lombok.Setter;
@Getter @Getter
@Setter @Setter
public class FetchedFeed { public class FetchedFeed {

View File

@@ -8,11 +8,11 @@ import javax.persistence.Table;
import javax.persistence.Temporal; import javax.persistence.Temporal;
import javax.persistence.TemporalType; import javax.persistence.TemporalType;
import org.apache.commons.lang3.time.DateUtils;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.apache.commons.lang3.time.DateUtils;
@Entity @Entity
@Table(name = "USERS") @Table(name = "USERS")
@SuppressWarnings("serial") @SuppressWarnings("serial")
@@ -55,7 +55,7 @@ public class User extends AbstractModel {
private Date lastFullRefresh; private Date lastFullRefresh;
public boolean shouldRefreshFeedsAt(Date when) { public boolean shouldRefreshFeedsAt(Date when) {
return (lastFullRefresh == null || lastFullRefreshMoreThan30MinutesBefore(when)); return lastFullRefresh == null || lastFullRefreshMoreThan30MinutesBefore(when);
} }
private boolean lastFullRefreshMoreThan30MinutesBefore(Date when) { private boolean lastFullRefreshMoreThan30MinutesBefore(Date when) {

View File

@@ -19,7 +19,7 @@ import lombok.Setter;
@Setter @Setter
public class UserRole extends AbstractModel { public class UserRole extends AbstractModel {
public static enum Role { public enum Role {
USER, ADMIN USER, ADMIN
} }

View File

@@ -6,9 +6,6 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@@ -23,6 +20,9 @@ import com.rometools.opml.feed.opml.Opml;
import com.rometools.opml.feed.opml.Outline; import com.rometools.opml.feed.opml.Outline;
import com.rometools.rome.io.WireFeedInput; import com.rometools.rome.io.WireFeedInput;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
@RequiredArgsConstructor(onConstructor = @__({ @Inject })) @RequiredArgsConstructor(onConstructor = @__({ @Inject }))
@Singleton @Singleton

View File

@@ -24,7 +24,7 @@ import lombok.extern.slf4j.Slf4j;
* *
*/ */
@Slf4j @Slf4j
@RequiredArgsConstructor(onConstructor = @__({ @Inject }) ) @RequiredArgsConstructor(onConstructor = @__({ @Inject }))
@Singleton @Singleton
public class DatabaseCleaningService { public class DatabaseCleaningService {

View File

@@ -12,8 +12,6 @@ import java.util.concurrent.TimeoutException;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.RequiredArgsConstructor;
import org.apache.commons.jexl2.JexlContext; import org.apache.commons.jexl2.JexlContext;
import org.apache.commons.jexl2.JexlEngine; import org.apache.commons.jexl2.JexlEngine;
import org.apache.commons.jexl2.JexlException; import org.apache.commons.jexl2.JexlException;
@@ -30,12 +28,16 @@ import org.jsoup.Jsoup;
import com.commafeed.backend.model.FeedEntry; import com.commafeed.backend.model.FeedEntry;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor(onConstructor = @__({ @Inject })) @RequiredArgsConstructor(onConstructor = @__({ @Inject }))
@Singleton @Singleton
public class FeedEntryFilteringService { public class FeedEntryFilteringService {
private static final JexlEngine ENGINE = initEngine(); private static final JexlEngine ENGINE = initEngine();
private final ExecutorService executor = Executors.newCachedThreadPool();
private static JexlEngine initEngine() { private static JexlEngine initEngine() {
// classloader that prevents object creation // classloader that prevents object creation
ClassLoader cl = new ClassLoader() { ClassLoader cl = new ClassLoader() {
@@ -70,8 +72,6 @@ public class FeedEntryFilteringService {
return engine; return engine;
} }
private ExecutorService executor = Executors.newCachedThreadPool();
public boolean filterMatchesEntry(String filter, FeedEntry entry) throws FeedEntryFilterException { public boolean filterMatchesEntry(String filter, FeedEntry entry) throws FeedEntryFilterException {
if (StringUtils.isBlank(filter)) { if (StringUtils.isBlank(filter)) {
return true; return true;
@@ -87,8 +87,8 @@ public class FeedEntryFilteringService {
JexlContext context = new MapContext(); JexlContext context = new MapContext();
context.set("title", entry.getContent().getTitle() == null ? "" : Jsoup.parse(entry.getContent().getTitle()).text().toLowerCase()); context.set("title", entry.getContent().getTitle() == null ? "" : Jsoup.parse(entry.getContent().getTitle()).text().toLowerCase());
context.set("author", entry.getContent().getAuthor() == null ? "" : entry.getContent().getAuthor().toLowerCase()); context.set("author", entry.getContent().getAuthor() == null ? "" : entry.getContent().getAuthor().toLowerCase());
context.set("content", entry.getContent().getContent() == null ? "" : Jsoup.parse(entry.getContent().getContent()).text() context.set("content",
.toLowerCase()); entry.getContent().getContent() == null ? "" : Jsoup.parse(entry.getContent().getContent()).text().toLowerCase());
context.set("url", entry.getUrl() == null ? "" : entry.getUrl().toLowerCase()); context.set("url", entry.getUrl() == null ? "" : entry.getUrl().toLowerCase());
context.set("categories", entry.getContent().getCategories() == null ? "" : entry.getContent().getCategories().toLowerCase()); context.set("categories", entry.getContent().getCategories() == null ? "" : entry.getContent().getCategories().toLowerCase());

View File

@@ -7,8 +7,6 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.RequiredArgsConstructor;
import com.commafeed.backend.cache.CacheService; import com.commafeed.backend.cache.CacheService;
import com.commafeed.backend.dao.FeedEntryDAO; import com.commafeed.backend.dao.FeedEntryDAO;
import com.commafeed.backend.dao.FeedEntryStatusDAO; import com.commafeed.backend.dao.FeedEntryStatusDAO;
@@ -19,6 +17,8 @@ import com.commafeed.backend.model.FeedEntryStatus;
import com.commafeed.backend.model.FeedSubscription; import com.commafeed.backend.model.FeedSubscription;
import com.commafeed.backend.model.User; import com.commafeed.backend.model.User;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor(onConstructor = @__({ @Inject })) @RequiredArgsConstructor(onConstructor = @__({ @Inject }))
@Singleton @Singleton
public class FeedEntryService { public class FeedEntryService {

View File

@@ -7,14 +7,14 @@ import java.util.stream.Collectors;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.RequiredArgsConstructor;
import com.commafeed.backend.dao.FeedEntryDAO; import com.commafeed.backend.dao.FeedEntryDAO;
import com.commafeed.backend.dao.FeedEntryTagDAO; import com.commafeed.backend.dao.FeedEntryTagDAO;
import com.commafeed.backend.model.FeedEntry; import com.commafeed.backend.model.FeedEntry;
import com.commafeed.backend.model.FeedEntryTag; import com.commafeed.backend.model.FeedEntryTag;
import com.commafeed.backend.model.User; import com.commafeed.backend.model.User;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor(onConstructor = @__({ @Inject })) @RequiredArgsConstructor(onConstructor = @__({ @Inject }))
@Singleton @Singleton
public class FeedEntryTagService { public class FeedEntryTagService {
@@ -29,10 +29,12 @@ public class FeedEntryTagService {
} }
List<FeedEntryTag> existingTags = feedEntryTagDAO.findByEntry(user, entry); List<FeedEntryTag> existingTags = feedEntryTagDAO.findByEntry(user, entry);
Set<String> existingTagNames = existingTags.stream().map(t -> t.getName()).collect(Collectors.toSet()); Set<String> existingTagNames = existingTags.stream().map(FeedEntryTag::getName).collect(Collectors.toSet());
List<FeedEntryTag> addList = tagNames.stream().filter(name -> !existingTagNames.contains(name)) List<FeedEntryTag> addList = tagNames.stream()
.map(name -> new FeedEntryTag(user, entry, name)).collect(Collectors.toList()); .filter(name -> !existingTagNames.contains(name))
.map(name -> new FeedEntryTag(user, entry, name))
.collect(Collectors.toList());
List<FeedEntryTag> removeList = existingTags.stream().filter(tag -> !tagNames.contains(tag.getName())).collect(Collectors.toList()); List<FeedEntryTag> removeList = existingTags.stream().filter(tag -> !tagNames.contains(tag.getName())).collect(Collectors.toList());
feedEntryTagDAO.saveOrUpdate(addList); feedEntryTagDAO.saveOrUpdate(addList);

View File

@@ -7,9 +7,6 @@ import java.util.stream.Collectors;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import com.commafeed.CommaFeedConfiguration; import com.commafeed.CommaFeedConfiguration;
@@ -26,18 +23,14 @@ import com.commafeed.backend.model.Models;
import com.commafeed.backend.model.User; import com.commafeed.backend.model.User;
import com.commafeed.frontend.model.UnreadCount; import com.commafeed.frontend.model.UnreadCount;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
@RequiredArgsConstructor(onConstructor = @__({ @Inject })) @RequiredArgsConstructor(onConstructor = @__({ @Inject }))
@Singleton @Singleton
public class FeedSubscriptionService { public class FeedSubscriptionService {
@SuppressWarnings("serial")
public static class FeedSubscriptionException extends RuntimeException {
private FeedSubscriptionException(String msg) {
super(msg);
}
}
private final FeedDAO feedDAO; private final FeedDAO feedDAO;
private final FeedEntryStatusDAO feedEntryStatusDAO; private final FeedEntryStatusDAO feedEntryStatusDAO;
private final FeedSubscriptionDAO feedSubscriptionDAO; private final FeedSubscriptionDAO feedSubscriptionDAO;
@@ -108,7 +101,7 @@ public class FeedSubscriptionService {
} }
public Map<Long, UnreadCount> getUnreadCount(User user) { public Map<Long, UnreadCount> getUnreadCount(User user) {
return feedSubscriptionDAO.findAll(user).stream().collect(Collectors.toMap(s -> s.getId(), s -> getUnreadCount(user, s))); return feedSubscriptionDAO.findAll(user).stream().collect(Collectors.toMap(FeedSubscription::getId, s -> getUnreadCount(user, s)));
} }
private UnreadCount getUnreadCount(User user, FeedSubscription sub) { private UnreadCount getUnreadCount(User user, FeedSubscription sub) {
@@ -121,4 +114,11 @@ public class FeedSubscriptionService {
return count; return count;
} }
@SuppressWarnings("serial")
public static class FeedSubscriptionException extends RuntimeException {
private FeedSubscriptionException(String msg) {
super(msg);
}
}
} }

View File

@@ -6,9 +6,6 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.DigestUtils;
import com.commafeed.backend.dao.FeedEntryDAO; import com.commafeed.backend.dao.FeedEntryDAO;
@@ -20,6 +17,9 @@ import com.commafeed.backend.model.FeedEntryStatus;
import com.commafeed.backend.model.FeedSubscription; import com.commafeed.backend.model.FeedSubscription;
import com.commafeed.backend.service.FeedEntryFilteringService.FeedEntryFilterException; import com.commafeed.backend.service.FeedEntryFilteringService.FeedEntryFilterException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
@RequiredArgsConstructor(onConstructor = @__({ @Inject })) @RequiredArgsConstructor(onConstructor = @__({ @Inject }))
@Singleton @Singleton

View File

@@ -13,12 +13,12 @@ import javax.mail.Transport;
import javax.mail.internet.InternetAddress; import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMessage;
import lombok.RequiredArgsConstructor;
import com.commafeed.CommaFeedConfiguration; import com.commafeed.CommaFeedConfiguration;
import com.commafeed.CommaFeedConfiguration.ApplicationSettings; import com.commafeed.CommaFeedConfiguration.ApplicationSettings;
import com.commafeed.backend.model.User; import com.commafeed.backend.model.User;
import lombok.RequiredArgsConstructor;
/** /**
* Mailing service * Mailing service
* *

View File

@@ -12,11 +12,11 @@ import javax.crypto.spec.PBEKeySpec;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.apache.commons.lang3.StringUtils;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
// taken from http://www.javacodegeeks.com/2012/05/secure-password-storage-donts-dos-and.html // taken from http://www.javacodegeeks.com/2012/05/secure-password-storage-donts-dos-and.html
@SuppressWarnings("serial") @SuppressWarnings("serial")
@Slf4j @Slf4j

View File

@@ -7,9 +7,6 @@ import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHeaders; import org.apache.http.HttpHeaders;
@@ -28,6 +25,9 @@ import com.commafeed.backend.feed.FeedUtils;
import com.commafeed.backend.model.Feed; import com.commafeed.backend.model.Feed;
import com.commafeed.frontend.resource.PubSubHubbubCallbackREST; import com.commafeed.frontend.resource.PubSubHubbubCallbackREST;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
/** /**
* Sends push subscription requests. Callback is handled by {@link PubSubHubbubCallbackREST} * Sends push subscription requests. Callback is handled by {@link PubSubHubbubCallbackREST}
* *
@@ -76,8 +76,8 @@ public class PubSubService {
queues.giveBack(feed); queues.giveBack(feed);
log.debug("handled pushpress subfeed {} : {}", topic, feed.getPushTopic()); log.debug("handled pushpress subfeed {} : {}", topic, feed.getPushTopic());
} else { } else {
throw new Exception("Unexpected response code: " + code + " " + response.getStatusLine().getReasonPhrase() + " - " throw new Exception(
+ message); "Unexpected response code: " + code + " " + response.getStatusLine().getReasonPhrase() + " - " + message);
} }
} }
log.debug("subscribed to {} for {}", hub, topic); log.debug("subscribed to {} for {}", hub, topic);

View File

@@ -9,8 +9,6 @@ import java.util.UUID;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.RequiredArgsConstructor;
import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@@ -26,6 +24,8 @@ import com.commafeed.backend.model.UserRole.Role;
import com.commafeed.backend.service.internal.PostLoginActivities; import com.commafeed.backend.service.internal.PostLoginActivities;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor(onConstructor = @__({ @Inject })) @RequiredArgsConstructor(onConstructor = @__({ @Inject }))
@Singleton @Singleton
public class UserService { public class UserService {
@@ -102,8 +102,8 @@ public class UserService {
Preconditions.checkNotNull(email); Preconditions.checkNotNull(email);
Preconditions.checkArgument(StringUtils.length(name) >= 3, "Name too short (3 characters minimum)"); Preconditions.checkArgument(StringUtils.length(name) >= 3, "Name too short (3 characters minimum)");
Preconditions Preconditions.checkArgument(forceRegistration || StringUtils.length(password) >= 6,
.checkArgument(forceRegistration || StringUtils.length(password) >= 6, "Password too short (6 characters maximum)"); "Password too short (6 characters maximum)");
Preconditions.checkArgument(StringUtils.contains(email, "@"), "Invalid email address"); Preconditions.checkArgument(StringUtils.contains(email, "@"), "Invalid email address");
} }

View File

@@ -5,8 +5,6 @@ import java.util.Date;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.DateUtils;
import com.commafeed.CommaFeedConfiguration; import com.commafeed.CommaFeedConfiguration;
@@ -14,6 +12,8 @@ import com.commafeed.backend.dao.UserDAO;
import com.commafeed.backend.model.User; import com.commafeed.backend.model.User;
import com.commafeed.backend.service.FeedSubscriptionService; import com.commafeed.backend.service.FeedSubscriptionService;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor(onConstructor = @__({ @Inject })) @RequiredArgsConstructor(onConstructor = @__({ @Inject }))
@Singleton @Singleton
public class PostLoginActivities { public class PostLoginActivities {

View File

@@ -5,11 +5,11 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.RequiredArgsConstructor;
import com.commafeed.CommaFeedConfiguration; import com.commafeed.CommaFeedConfiguration;
import com.commafeed.backend.service.DatabaseCleaningService; import com.commafeed.backend.service.DatabaseCleaningService;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor(onConstructor = @__({ @Inject })) @RequiredArgsConstructor(onConstructor = @__({ @Inject }))
@Singleton @Singleton
public class OldEntriesCleanupTask extends ScheduledTask { public class OldEntriesCleanupTask extends ScheduledTask {

View File

@@ -6,11 +6,11 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.RequiredArgsConstructor;
import com.commafeed.CommaFeedConfiguration; import com.commafeed.CommaFeedConfiguration;
import com.commafeed.backend.service.DatabaseCleaningService; import com.commafeed.backend.service.DatabaseCleaningService;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor(onConstructor = @__({ @Inject })) @RequiredArgsConstructor(onConstructor = @__({ @Inject }))
@Singleton @Singleton
public class OldStatusesCleanupTask extends ScheduledTask { public class OldStatusesCleanupTask extends ScheduledTask {

View File

@@ -5,10 +5,10 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.RequiredArgsConstructor;
import com.commafeed.backend.service.DatabaseCleaningService; import com.commafeed.backend.service.DatabaseCleaningService;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor(onConstructor = @__({ @Inject })) @RequiredArgsConstructor(onConstructor = @__({ @Inject }))
@Singleton @Singleton
public class OrphanedContentsCleanupTask extends ScheduledTask { public class OrphanedContentsCleanupTask extends ScheduledTask {

View File

@@ -5,10 +5,10 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.RequiredArgsConstructor;
import com.commafeed.backend.service.DatabaseCleaningService; import com.commafeed.backend.service.DatabaseCleaningService;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor(onConstructor = @__({ @Inject })) @RequiredArgsConstructor(onConstructor = @__({ @Inject }))
@Singleton @Singleton
public class OrphanedFeedsCleanupTask extends ScheduledTask { public class OrphanedFeedsCleanupTask extends ScheduledTask {

View File

@@ -11,8 +11,6 @@ import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import lombok.RequiredArgsConstructor;
import org.eclipse.jetty.util.B64Code; import org.eclipse.jetty.util.B64Code;
import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.StringUtil;
import org.glassfish.jersey.server.internal.inject.AbstractContainerRequestValueFactory; import org.glassfish.jersey.server.internal.inject.AbstractContainerRequestValueFactory;
@@ -22,6 +20,8 @@ import com.commafeed.backend.model.UserRole.Role;
import com.commafeed.backend.service.UserService; import com.commafeed.backend.service.UserService;
import com.commafeed.frontend.session.SessionHelper; import com.commafeed.frontend.session.SessionHelper;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor @RequiredArgsConstructor
public class SecurityCheckFactory extends AbstractContainerRequestValueFactory<User> { public class SecurityCheckFactory extends AbstractContainerRequestValueFactory<User> {
@@ -52,11 +52,15 @@ public class SecurityCheckFactory extends AbstractContainerRequestValueFactory<U
return user.get(); return user.get();
} else { } else {
throw new WebApplicationException(Response.status(Response.Status.FORBIDDEN) throw new WebApplicationException(Response.status(Response.Status.FORBIDDEN)
.entity("You don't have the required role to access this resource.").type(MediaType.TEXT_PLAIN_TYPE).build()); .entity("You don't have the required role to access this resource.")
.type(MediaType.TEXT_PLAIN_TYPE)
.build());
} }
} else { } else {
throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED) throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED)
.entity("Credentials are required to access this resource.").type(MediaType.TEXT_PLAIN_TYPE).build()); .entity("Credentials are required to access this resource.")
.type(MediaType.TEXT_PLAIN_TYPE)
.build());
} }
} }

View File

@@ -3,8 +3,6 @@ package com.commafeed.frontend.auth;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.RequiredArgsConstructor;
import org.glassfish.hk2.api.Factory; import org.glassfish.hk2.api.Factory;
import org.glassfish.hk2.api.InjectionResolver; import org.glassfish.hk2.api.InjectionResolver;
import org.glassfish.hk2.api.ServiceLocator; import org.glassfish.hk2.api.ServiceLocator;
@@ -19,6 +17,8 @@ import org.glassfish.jersey.server.spi.internal.ValueFactoryProvider;
import com.commafeed.backend.model.User; import com.commafeed.backend.model.User;
import com.commafeed.backend.service.UserService; import com.commafeed.backend.service.UserService;
import lombok.RequiredArgsConstructor;
@Singleton @Singleton
public class SecurityCheckFactoryProvider extends AbstractValueFactoryProvider { public class SecurityCheckFactoryProvider extends AbstractValueFactoryProvider {
@@ -32,8 +32,9 @@ public class SecurityCheckFactoryProvider extends AbstractValueFactoryProvider {
final Class<?> classType = parameter.getRawType(); final Class<?> classType = parameter.getRawType();
SecurityCheck securityCheck = parameter.getAnnotation(SecurityCheck.class); SecurityCheck securityCheck = parameter.getAnnotation(SecurityCheck.class);
if (securityCheck == null) if (securityCheck == null) {
return null; return null;
}
if (classType.isAssignableFrom(User.class)) { if (classType.isAssignableFrom(User.class)) {
return new SecurityCheckFactory(securityCheck.value(), securityCheck.apiKeyAllowed()); return new SecurityCheckFactory(securityCheck.value(), securityCheck.apiKeyAllowed());

View File

@@ -30,74 +30,6 @@ import lombok.Data;
@Data @Data
public class Entry implements Serializable { public class Entry implements Serializable {
public static Entry build(FeedEntryStatus status, String publicUrl, boolean proxyImages) {
Entry entry = new Entry();
FeedEntry feedEntry = status.getEntry();
FeedSubscription sub = status.getSubscription();
FeedEntryContent content = feedEntry.getContent();
entry.setId(String.valueOf(feedEntry.getId()));
entry.setGuid(feedEntry.getGuid());
entry.setRead(status.isRead());
entry.setStarred(status.isStarred());
entry.setMarkable(status.isMarkable());
entry.setDate(feedEntry.getUpdated());
entry.setInsertedDate(feedEntry.getInserted());
entry.setUrl(feedEntry.getUrl());
entry.setFeedName(sub.getTitle());
entry.setFeedId(String.valueOf(sub.getId()));
entry.setFeedUrl(sub.getFeed().getUrl());
entry.setFeedLink(sub.getFeed().getLink());
entry.setIconUrl(FeedUtils.getFaviconUrl(sub, publicUrl));
entry.setTags(status.getTags().stream().map(FeedEntryTag::getName).collect(Collectors.toList()));
if (content != null) {
entry.setRtl(FeedUtils.isRTL(feedEntry));
entry.setTitle(content.getTitle());
entry.setContent(proxyImages ? FeedUtils.proxyImages(content.getContent(), publicUrl) : content.getContent());
entry.setAuthor(content.getAuthor());
entry.setEnclosureType(content.getEnclosureType());
entry.setEnclosureUrl(proxyImages && StringUtils.contains(content.getEnclosureType(), "image")
? FeedUtils.proxyImage(content.getEnclosureUrl(), publicUrl)
: content.getEnclosureUrl());
entry.setMediaDescription(content.getMediaDescription());
entry.setMediaThumbnailUrl(
proxyImages ? FeedUtils.proxyImage(content.getMediaThumbnailUrl(), publicUrl) : content.getMediaThumbnailUrl());
entry.setMediaThumbnailWidth(content.getMediaThumbnailWidth());
entry.setMediaThumbnailHeight(content.getMediaThumbnailHeight());
entry.setCategories(content.getCategories());
}
return entry;
}
public SyndEntry asRss() {
SyndEntry entry = new SyndEntryImpl();
entry.setUri(getGuid());
entry.setTitle(getTitle());
entry.setAuthor(getAuthor());
SyndContentImpl content = new SyndContentImpl();
content.setValue(getContent());
entry.setContents(Arrays.<SyndContent> asList(content));
if (getEnclosureUrl() != null) {
SyndEnclosureImpl enclosure = new SyndEnclosureImpl();
enclosure.setType(getEnclosureType());
enclosure.setUrl(getEnclosureUrl());
entry.setEnclosures(Arrays.<SyndEnclosure> asList(enclosure));
}
entry.setLink(getUrl());
entry.setPublishedDate(getDate());
return entry;
}
@ApiModelProperty(value = "entry id", required = true) @ApiModelProperty(value = "entry id", required = true)
private String id; private String id;
@@ -172,4 +104,72 @@ public class Entry implements Serializable {
@ApiModelProperty(value = "tags", required = true) @ApiModelProperty(value = "tags", required = true)
private List<String> tags; private List<String> tags;
public static Entry build(FeedEntryStatus status, String publicUrl, boolean proxyImages) {
Entry entry = new Entry();
FeedEntry feedEntry = status.getEntry();
FeedSubscription sub = status.getSubscription();
FeedEntryContent content = feedEntry.getContent();
entry.setId(String.valueOf(feedEntry.getId()));
entry.setGuid(feedEntry.getGuid());
entry.setRead(status.isRead());
entry.setStarred(status.isStarred());
entry.setMarkable(status.isMarkable());
entry.setDate(feedEntry.getUpdated());
entry.setInsertedDate(feedEntry.getInserted());
entry.setUrl(feedEntry.getUrl());
entry.setFeedName(sub.getTitle());
entry.setFeedId(String.valueOf(sub.getId()));
entry.setFeedUrl(sub.getFeed().getUrl());
entry.setFeedLink(sub.getFeed().getLink());
entry.setIconUrl(FeedUtils.getFaviconUrl(sub, publicUrl));
entry.setTags(status.getTags().stream().map(FeedEntryTag::getName).collect(Collectors.toList()));
if (content != null) {
entry.setRtl(FeedUtils.isRTL(feedEntry));
entry.setTitle(content.getTitle());
entry.setContent(proxyImages ? FeedUtils.proxyImages(content.getContent(), publicUrl) : content.getContent());
entry.setAuthor(content.getAuthor());
entry.setEnclosureType(content.getEnclosureType());
entry.setEnclosureUrl(proxyImages && StringUtils.contains(content.getEnclosureType(), "image")
? FeedUtils.proxyImage(content.getEnclosureUrl(), publicUrl)
: content.getEnclosureUrl());
entry.setMediaDescription(content.getMediaDescription());
entry.setMediaThumbnailUrl(
proxyImages ? FeedUtils.proxyImage(content.getMediaThumbnailUrl(), publicUrl) : content.getMediaThumbnailUrl());
entry.setMediaThumbnailWidth(content.getMediaThumbnailWidth());
entry.setMediaThumbnailHeight(content.getMediaThumbnailHeight());
entry.setCategories(content.getCategories());
}
return entry;
}
public SyndEntry asRss() {
SyndEntry entry = new SyndEntryImpl();
entry.setUri(getGuid());
entry.setTitle(getTitle());
entry.setAuthor(getAuthor());
SyndContentImpl content = new SyndContentImpl();
content.setValue(getContent());
entry.setContents(Arrays.<SyndContent> asList(content));
if (getEnclosureUrl() != null) {
SyndEnclosureImpl enclosure = new SyndEnclosureImpl();
enclosure.setType(getEnclosureType());
enclosure.setUrl(getEnclosureUrl());
entry.setEnclosures(Arrays.<SyndEnclosure> asList(enclosure));
}
entry.setLink(getUrl());
entry.setPublishedDate(getDate());
return entry;
}
} }

View File

@@ -17,28 +17,6 @@ import lombok.Data;
@Data @Data
public class Subscription implements Serializable { public class Subscription implements Serializable {
public static Subscription build(FeedSubscription subscription, String publicUrl, UnreadCount unreadCount) {
Date now = new Date();
FeedCategory category = subscription.getCategory();
Feed feed = subscription.getFeed();
Subscription sub = new Subscription();
sub.setId(subscription.getId());
sub.setName(subscription.getTitle());
sub.setPosition(subscription.getPosition());
sub.setMessage(feed.getMessage());
sub.setErrorCount(feed.getErrorCount());
sub.setFeedUrl(feed.getUrl());
sub.setFeedLink(feed.getLink());
sub.setIconUrl(FeedUtils.getFaviconUrl(subscription, publicUrl));
sub.setLastRefresh(feed.getLastUpdated());
sub.setNextRefresh((feed.getDisabledUntil() != null && feed.getDisabledUntil().before(now)) ? null : feed.getDisabledUntil());
sub.setUnread(unreadCount.getUnreadCount());
sub.setNewestItemTime(unreadCount.getNewestItemTime());
sub.setCategoryId(category == null ? null : String.valueOf(category.getId()));
sub.setFilter(subscription.getFilter());
return sub;
}
@ApiModelProperty(value = "subscription id", required = true) @ApiModelProperty(value = "subscription id", required = true)
private Long id; private Long id;
@@ -84,4 +62,26 @@ public class Subscription implements Serializable {
@ApiModelProperty(value = "JEXL string evaluated on new entries to mark them as read if they do not match") @ApiModelProperty(value = "JEXL string evaluated on new entries to mark them as read if they do not match")
private String filter; private String filter;
public static Subscription build(FeedSubscription subscription, String publicUrl, UnreadCount unreadCount) {
Date now = new Date();
FeedCategory category = subscription.getCategory();
Feed feed = subscription.getFeed();
Subscription sub = new Subscription();
sub.setId(subscription.getId());
sub.setName(subscription.getTitle());
sub.setPosition(subscription.getPosition());
sub.setMessage(feed.getMessage());
sub.setErrorCount(feed.getErrorCount());
sub.setFeedUrl(feed.getUrl());
sub.setFeedLink(feed.getLink());
sub.setIconUrl(FeedUtils.getFaviconUrl(subscription, publicUrl));
sub.setLastRefresh(feed.getLastUpdated());
sub.setNextRefresh((feed.getDisabledUntil() != null && feed.getDisabledUntil().before(now)) ? null : feed.getDisabledUntil());
sub.setUnread(unreadCount.getUnreadCount());
sub.setNewestItemTime(unreadCount.getNewestItemTime());
sub.setCategoryId(category == null ? null : String.valueOf(category.getId()));
sub.setFilter(subscription.getFilter());
return sub;
}
} }

View File

@@ -100,18 +100,6 @@ public class FeedREST {
private static final FeedEntry TEST_ENTRY = initTestEntry(); private static final FeedEntry TEST_ENTRY = initTestEntry();
private static FeedEntry initTestEntry() {
FeedEntry entry = new FeedEntry();
entry.setUrl("https://github.com/Athou/commafeed");
FeedEntryContent content = new FeedEntryContent();
content.setAuthor("Athou");
content.setTitle("Merge pull request #662 from Athou/dw8");
content.setContent("Merge pull request #662 from Athou/dw8");
entry.setContent(content);
return entry;
}
private final FeedSubscriptionDAO feedSubscriptionDAO; private final FeedSubscriptionDAO feedSubscriptionDAO;
private final FeedCategoryDAO feedCategoryDAO; private final FeedCategoryDAO feedCategoryDAO;
private final FeedEntryStatusDAO feedEntryStatusDAO; private final FeedEntryStatusDAO feedEntryStatusDAO;
@@ -126,6 +114,18 @@ public class FeedREST {
private final CacheService cache; private final CacheService cache;
private final CommaFeedConfiguration config; private final CommaFeedConfiguration config;
private static FeedEntry initTestEntry() {
FeedEntry entry = new FeedEntry();
entry.setUrl("https://github.com/Athou/commafeed");
FeedEntryContent content = new FeedEntryContent();
content.setAuthor("Athou");
content.setTitle("Merge pull request #662 from Athou/dw8");
content.setContent("Merge pull request #662 from Athou/dw8");
entry.setContent(content);
return entry;
}
@Path("/entries") @Path("/entries")
@GET @GET
@UnitOfWork @UnitOfWork
@@ -176,7 +176,8 @@ public class FeedREST {
entryKeywords, newerThanDate, offset, limit + 1, order, true, onlyIds, null); entryKeywords, newerThanDate, offset, limit + 1, order, true, onlyIds, null);
for (FeedEntryStatus status : list) { for (FeedEntryStatus status : list) {
entries.getEntries().add(Entry.build(status, config.getApplicationSettings().getPublicUrl(), entries.getEntries()
.add(Entry.build(status, config.getApplicationSettings().getPublicUrl(),
config.getApplicationSettings().getImageProxyEnabled())); config.getApplicationSettings().getImageProxyEnabled()));
} }
@@ -226,7 +227,7 @@ public class FeedREST {
feed.setTitle("CommaFeed - " + entries.getName()); feed.setTitle("CommaFeed - " + entries.getName());
feed.setDescription("CommaFeed - " + entries.getName()); feed.setDescription("CommaFeed - " + entries.getName());
feed.setLink(config.getApplicationSettings().getPublicUrl()); feed.setLink(config.getApplicationSettings().getPublicUrl());
feed.setEntries(entries.getEntries().stream().map(e -> e.asRss()).collect(Collectors.toList())); feed.setEntries(entries.getEntries().stream().map(Entry::asRss).collect(Collectors.toList()));
SyndFeedOutput output = new SyndFeedOutput(); SyndFeedOutput output = new SyndFeedOutput();
StringWriter writer = new StringWriter(); StringWriter writer = new StringWriter();
@@ -270,8 +271,10 @@ public class FeedREST {
try { try {
info = fetchFeedInternal(req.getUrl()); info = fetchFeedInternal(req.getUrl());
} catch (Exception e) { } catch (Exception e) {
return Response.status(Status.INTERNAL_SERVER_ERROR).entity(Throwables.getStackTraceAsString(Throwables.getRootCause(e))) return Response.status(Status.INTERNAL_SERVER_ERROR)
.type(MediaType.TEXT_PLAIN).build(); .entity(Throwables.getStackTraceAsString(Throwables.getRootCause(e)))
.type(MediaType.TEXT_PLAIN)
.build();
} }
return Response.ok(info).build(); return Response.ok(info).build();
} }

View File

@@ -37,7 +37,7 @@ import lombok.extern.slf4j.Slf4j;
@Path("/push") @Path("/push")
@Slf4j @Slf4j
@RequiredArgsConstructor(onConstructor = @__({ @Inject }) ) @RequiredArgsConstructor(onConstructor = @__({ @Inject }))
@Singleton @Singleton
public class PubSubHubbubCallbackREST { public class PubSubHubbubCallbackREST {
@@ -69,7 +69,7 @@ public class PubSubHubbubCallbackREST {
List<Feed> feeds = feedDAO.findByTopic(topic); List<Feed> feeds = feedDAO.findByTopic(topic);
if (feeds.isEmpty() == false) { if (!feeds.isEmpty()) {
for (Feed feed : feeds) { for (Feed feed : feeds) {
log.debug("activated push notifications for {}", feed.getPushTopic()); log.debug("activated push notifications for {}", feed.getPushTopic());
feed.setPushLastPing(new Date()); feed.setPushLastPing(new Date());

View File

@@ -21,7 +21,7 @@ import com.commafeed.frontend.session.SessionHelper;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@SuppressWarnings("serial") @SuppressWarnings("serial")
@RequiredArgsConstructor(onConstructor = @__({ @Inject }) ) @RequiredArgsConstructor(onConstructor = @__({ @Inject }))
@Singleton @Singleton
public class CustomCssServlet extends HttpServlet { public class CustomCssServlet extends HttpServlet {

View File

@@ -9,10 +9,10 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import com.commafeed.CommaFeedConfiguration; import com.commafeed.CommaFeedConfiguration;
import lombok.RequiredArgsConstructor;
@SuppressWarnings("serial") @SuppressWarnings("serial")
@RequiredArgsConstructor(onConstructor = @__({ @Inject })) @RequiredArgsConstructor(onConstructor = @__({ @Inject }))
@Singleton @Singleton

View File

@@ -5,10 +5,10 @@ import java.util.Optional;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import com.commafeed.backend.model.User; import com.commafeed.backend.model.User;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor() @RequiredArgsConstructor()
public class SessionHelper { public class SessionHelper {

View File

@@ -28,8 +28,9 @@ public class SessionHelperFactoryProvider extends AbstractValueFactoryProvider {
final Class<?> classType = parameter.getRawType(); final Class<?> classType = parameter.getRawType();
Context context = parameter.getAnnotation(Context.class); Context context = parameter.getAnnotation(Context.class);
if (context == null) if (context == null) {
return null; return null;
}
if (classType.isAssignableFrom(SessionHelper.class)) { if (classType.isAssignableFrom(SessionHelper.class)) {
return new SessionHelperFactory(); return new SessionHelperFactory();

View File

@@ -9,17 +9,18 @@ import org.junit.Test;
public class FixedSizeSortedSetTest { public class FixedSizeSortedSetTest {
private FixedSizeSortedSet<String> set; private static final Comparator<String> COMP = new Comparator<String>() {
private static Comparator<String> COMP = new Comparator<String>() {
@Override @Override
public int compare(String o1, String o2) { public int compare(String o1, String o2) {
return ObjectUtils.compare(o1, o2); return ObjectUtils.compare(o1, o2);
} }
}; };
private FixedSizeSortedSet<String> set;
@Before @Before
public void init() { public void init() {
set = new FixedSizeSortedSet<String>(3, COMP); set = new FixedSizeSortedSet<>(3, COMP);
} }
@Test @Test

View File

@@ -87,7 +87,7 @@ public class FeedUtilsTest {
} }
@Test @Test
public void testRemoveTrailingSlash_lastSlashOnly() { public void testRemoveTrailingSlashLastSlashOnly() {
final String url = "http://localhost//"; final String url = "http://localhost//";
final String result = FeedUtils.removeTrailingSlash(url); final String result = FeedUtils.removeTrailingSlash(url);
Assert.assertEquals("http://localhost/", result); Assert.assertEquals("http://localhost/", result);

View File

@@ -1,16 +1,14 @@
package com.commafeed.backend.opml; package com.commafeed.backend.opml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import com.commafeed.backend.dao.FeedCategoryDAO; import com.commafeed.backend.dao.FeedCategoryDAO;
@@ -29,31 +27,31 @@ public class OPMLExporterTest {
@Mock @Mock
private FeedSubscriptionDAO feedSubscriptionDAO; private FeedSubscriptionDAO feedSubscriptionDAO;
private User user = new User(); private final User user = new User();
private FeedCategory cat1 = new FeedCategory(); private final FeedCategory cat1 = new FeedCategory();
private FeedCategory cat2 = new FeedCategory(); private final FeedCategory cat2 = new FeedCategory();
private FeedSubscription rootFeed = newFeedSubscription("rootFeed", "rootFeed.com"); private final FeedSubscription rootFeed = newFeedSubscription("rootFeed", "rootFeed.com");
private FeedSubscription cat1Feed = newFeedSubscription("cat1Feed", "cat1Feed.com"); private final FeedSubscription cat1Feed = newFeedSubscription("cat1Feed", "cat1Feed.com");
private FeedSubscription cat2Feed = newFeedSubscription("cat2Feed", "cat2Feed.com"); private final FeedSubscription cat2Feed = newFeedSubscription("cat2Feed", "cat2Feed.com");
private List<FeedCategory> categories = new ArrayList<>(); private final List<FeedCategory> categories = new ArrayList<>();
private List<FeedSubscription> subscriptions = new ArrayList<>(); private final List<FeedSubscription> subscriptions = new ArrayList<>();
@Before @Before
public void before_each_test() { public void init() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
user.setName("John Doe"); user.setName("John Doe");
cat1.setId(1l); cat1.setId(1L);
cat1.setName("cat1"); cat1.setName("cat1");
cat1.setParent(null); cat1.setParent(null);
cat1.setChildren(new HashSet<FeedCategory>()); cat1.setChildren(new HashSet<FeedCategory>());
cat1.setSubscriptions(new HashSet<FeedSubscription>()); cat1.setSubscriptions(new HashSet<FeedSubscription>());
cat2.setId(2l); cat2.setId(2L);
cat2.setName("cat2"); cat2.setName("cat2");
cat2.setParent(cat1); cat2.setParent(cat1);
cat2.setChildren(new HashSet<FeedCategory>()); cat2.setChildren(new HashSet<FeedCategory>());
@@ -90,51 +88,59 @@ public class OPMLExporterTest {
} }
@Test @Test
public void generates_OPML_correctly() { public void generatesOpmlCorrectly() {
when(feedCategoryDAO.findAll(user)).thenReturn(categories); Mockito.when(feedCategoryDAO.findAll(user)).thenReturn(categories);
when(feedSubscriptionDAO.findAll(user)).thenReturn(subscriptions); Mockito.when(feedSubscriptionDAO.findAll(user)).thenReturn(subscriptions);
Opml opml = new OPMLExporter(feedCategoryDAO, feedSubscriptionDAO).export(user); Opml opml = new OPMLExporter(feedCategoryDAO, feedSubscriptionDAO).export(user);
List<Outline> rootOutlines = opml.getOutlines(); List<Outline> rootOutlines = opml.getOutlines();
assertEquals(2, rootOutlines.size()); Assert.assertEquals(2, rootOutlines.size());
assertTrue(containsCategory(rootOutlines, "cat1")); Assert.assertTrue(containsCategory(rootOutlines, "cat1"));
assertTrue(containsFeed(rootOutlines, "rootFeed", "rootFeed.com")); Assert.assertTrue(containsFeed(rootOutlines, "rootFeed", "rootFeed.com"));
Outline cat1Outline = getCategoryOutline(rootOutlines, "cat1"); Outline cat1Outline = getCategoryOutline(rootOutlines, "cat1");
List<Outline> cat1Children = cat1Outline.getChildren(); List<Outline> cat1Children = cat1Outline.getChildren();
assertEquals(2, cat1Children.size()); Assert.assertEquals(2, cat1Children.size());
assertTrue(containsCategory(cat1Children, "cat2")); Assert.assertTrue(containsCategory(cat1Children, "cat2"));
assertTrue(containsFeed(cat1Children, "cat1Feed", "cat1Feed.com")); Assert.assertTrue(containsFeed(cat1Children, "cat1Feed", "cat1Feed.com"));
Outline cat2Outline = getCategoryOutline(cat1Children, "cat2"); Outline cat2Outline = getCategoryOutline(cat1Children, "cat2");
List<Outline> cat2Children = cat2Outline.getChildren(); List<Outline> cat2Children = cat2Outline.getChildren();
assertEquals(1, cat2Children.size()); Assert.assertEquals(1, cat2Children.size());
assertTrue(containsFeed(cat2Children, "cat2Feed", "cat2Feed.com")); Assert.assertTrue(containsFeed(cat2Children, "cat2Feed", "cat2Feed.com"));
} }
private boolean containsCategory(List<Outline> outlines, String category) { private boolean containsCategory(List<Outline> outlines, String category) {
for (Outline o : outlines) for (Outline o : outlines) {
if (!"rss".equals(o.getType())) if (!"rss".equals(o.getType())) {
if (category.equals(o.getTitle())) if (category.equals(o.getTitle())) {
return true; return true;
}
}
}
return false; return false;
} }
private boolean containsFeed(List<Outline> outlines, String title, String url) { private boolean containsFeed(List<Outline> outlines, String title, String url) {
for (Outline o : outlines) for (Outline o : outlines) {
if ("rss".equals(o.getType())) if ("rss".equals(o.getType())) {
if (title.equals(o.getTitle()) && o.getAttributeValue("xmlUrl").equals(url)) if (title.equals(o.getTitle()) && o.getAttributeValue("xmlUrl").equals(url)) {
return true; return true;
}
}
}
return false; return false;
} }
private Outline getCategoryOutline(List<Outline> outlines, String title) { private Outline getCategoryOutline(List<Outline> outlines, String title) {
for (Outline o : outlines) for (Outline o : outlines) {
if (o.getTitle().equals(title)) if (o.getTitle().equals(title)) {
return o; return o;
}
}
return null; return null;
} }

View File

@@ -1,14 +1,5 @@
package com.commafeed.backend.service; package com.commafeed.backend.service;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import static org.mockserver.model.HttpRequest.request;
import static org.mockserver.model.HttpResponse.response;
import org.apache.http.HttpHeaders; import org.apache.http.HttpHeaders;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
@@ -16,9 +7,12 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Answers; import org.mockito.Answers;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
import org.mockserver.client.MockServerClient; import org.mockserver.client.MockServerClient;
import org.mockserver.junit.MockServerRule; import org.mockserver.junit.MockServerRule;
import org.mockserver.model.HttpRequest;
import org.mockserver.model.HttpResponse;
import org.mockserver.model.MediaType; import org.mockserver.model.MediaType;
import com.commafeed.CommaFeedConfiguration; import com.commafeed.CommaFeedConfiguration;
@@ -28,76 +22,78 @@ import com.commafeed.backend.model.Feed;
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class PubSubServiceTest { public class PubSubServiceTest {
PubSubService underTest; private PubSubService underTest;
@Rule @Rule
public MockServerRule mockServerRule = new MockServerRule(this, 22441); private final MockServerRule mockServerRule = new MockServerRule(this, 22441);
public MockServerClient mockServerClient;
private MockServerClient mockServerClient;
@Mock(answer = Answers.RETURNS_DEEP_STUBS) @Mock(answer = Answers.RETURNS_DEEP_STUBS)
CommaFeedConfiguration config; private CommaFeedConfiguration config;
@Mock @Mock
FeedQueues queues; private FeedQueues queues;
@Mock @Mock
Feed feed; private Feed feed;
@Before @Before
public void init() { public void init() {
underTest = new PubSubService(config, queues); underTest = new PubSubService(config, queues);
// setup feed // setup feed
feed = mock(Feed.class); feed = Mockito.mock(Feed.class);
when(feed.getPushHub()).thenReturn("http://localhost:22441/hub"); Mockito.when(feed.getPushHub()).thenReturn("http://localhost:22441/hub");
when(feed.getPushTopic()).thenReturn("foo"); Mockito.when(feed.getPushTopic()).thenReturn("foo");
// setup config // setup config
when(config.getApplicationSettings().getPublicUrl()).thenReturn("http://localhost:22441/hub"); Mockito.when(config.getApplicationSettings().getPublicUrl()).thenReturn("http://localhost:22441/hub");
} }
@Test @Test
public void subscribe_200() { public void subscribe200() {
// Arrange // Arrange
mockServerClient.when(request().withMethod("POST")).respond(response().withStatusCode(200)); mockServerClient.when(HttpRequest.request().withMethod("POST")).respond(HttpResponse.response().withStatusCode(200));
// Act // Act
underTest.subscribe(feed); underTest.subscribe(feed);
// Assert // Assert
mockServerClient.verify(request().withContentType(MediaType.APPLICATION_FORM_URLENCODED) mockServerClient.verify(HttpRequest.request()
.withContentType(MediaType.APPLICATION_FORM_URLENCODED)
.withHeader(HttpHeaders.USER_AGENT, "CommaFeed") .withHeader(HttpHeaders.USER_AGENT, "CommaFeed")
.withMethod("POST") .withMethod("POST")
.withPath("/hub")); .withPath("/hub"));
verify(feed, never()).setPushTopic(anyString()); Mockito.verify(feed, Mockito.never()).setPushTopic(Mockito.anyString());
verifyZeroInteractions(queues); Mockito.verifyZeroInteractions(queues);
} }
@Test @Test
public void subscribe_400_withPushpressError() { public void subscribe400WithPushpressError() {
// Arrange // Arrange
mockServerClient.when(request().withMethod("POST")) mockServerClient.when(HttpRequest.request().withMethod("POST"))
.respond(response().withStatusCode(400).withBody(" is value is not allowed. You may only subscribe to")); .respond(HttpResponse.response().withStatusCode(400).withBody(" is value is not allowed. You may only subscribe to"));
// Act // Act
underTest.subscribe(feed); underTest.subscribe(feed);
// Assert // Assert
verify(feed).setPushTopic(anyString()); Mockito.verify(feed).setPushTopic(Mockito.anyString());
verify(queues).giveBack(feed); Mockito.verify(queues).giveBack(feed);
} }
@Test @Test
public void subscribe_400_withoutPushpressError() { public void subscribe400WithoutPushpressError() {
// Arrange // Arrange
mockServerClient.when(request().withMethod("POST")).respond(response().withStatusCode(400)); mockServerClient.when(HttpRequest.request().withMethod("POST")).respond(HttpResponse.response().withStatusCode(400));
// Act // Act
underTest.subscribe(feed); underTest.subscribe(feed);
// Assert // Assert
verify(feed, never()).setPushTopic(anyString()); Mockito.verify(feed, Mockito.never()).setPushTopic(Mockito.anyString());
verifyZeroInteractions(queues); Mockito.verifyZeroInteractions(queues);
} }
} }

View File

@@ -1,19 +1,12 @@
package com.commafeed.backend.service; package com.commafeed.backend.service;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Optional; import java.util.Optional;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import com.commafeed.CommaFeedConfiguration; import com.commafeed.CommaFeedConfiguration;
@@ -53,7 +46,7 @@ public class UserServiceTest {
private UserService userService; private UserService userService;
@Before @Before
public void before_each_test() { public void init() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
userService = new UserService(feedCategoryDAO, feedSubscriptionDAO, userDAO, userRoleDAO, userSettingsDAO, userService = new UserService(feedCategoryDAO, feedSubscriptionDAO, userDAO, userRoleDAO, userSettingsDAO,
@@ -69,129 +62,133 @@ public class UserServiceTest {
} }
@Test @Test
public void calling_login_should_not_return_user_object_when_given_null_nameOrEmail() { public void callingLoginShouldNotReturnUserObjectWhenGivenNullNameOrEmail() {
Optional<User> user = userService.login(null, "password"); Optional<User> user = userService.login(null, "password");
assertFalse(user.isPresent()); Assert.assertFalse(user.isPresent());
} }
@Test @Test
public void calling_login_should_not_return_user_object_when_given_null_password() { public void callingLoginShouldNotReturnUserObjectWhenGivenNullPassword() {
Optional<User> user = userService.login("testusername", null); Optional<User> user = userService.login("testusername", null);
assertFalse(user.isPresent()); Assert.assertFalse(user.isPresent());
} }
@Test @Test
public void calling_login_should_lookup_user_by_name() { public void callingLoginShouldLookupUserByName() {
userService.login("test", "password"); userService.login("test", "password");
verify(userDAO).findByName("test"); Mockito.verify(userDAO).findByName("test");
} }
@Test @Test
public void calling_login_should_lookup_user_by_email_if_lookup_by_name_failed() { public void callingLoginShouldLookupUserByEmailIfLookupByNameFailed() {
when(userDAO.findByName("test@test.com")).thenReturn(null); Mockito.when(userDAO.findByName("test@test.com")).thenReturn(null);
userService.login("test@test.com", "password"); userService.login("test@test.com", "password");
verify(userDAO).findByEmail("test@test.com"); Mockito.verify(userDAO).findByEmail("test@test.com");
} }
@Test @Test
public void calling_login_should_not_return_user_object_if_could_not_find_user_by_name_or_email() { public void callingLoginShouldNotReturnUserObjectIfCouldNotFindUserByNameOrEmail() {
when(userDAO.findByName("test@test.com")).thenReturn(null); Mockito.when(userDAO.findByName("test@test.com")).thenReturn(null);
when(userDAO.findByEmail("test@test.com")).thenReturn(null); Mockito.when(userDAO.findByEmail("test@test.com")).thenReturn(null);
Optional<User> user = userService.login("test@test.com", "password"); Optional<User> user = userService.login("test@test.com", "password");
assertFalse(user.isPresent()); Assert.assertFalse(user.isPresent());
} }
@Test @Test
public void calling_login_should_not_return_user_object_if_user_is_disabled() { public void callingLoginShouldNotReturnUserObjectIfUserIsDisabled() {
when(userDAO.findByName("test")).thenReturn(disabledUser); Mockito.when(userDAO.findByName("test")).thenReturn(disabledUser);
Optional<User> user = userService.login("test", "password"); Optional<User> user = userService.login("test", "password");
assertFalse(user.isPresent()); Assert.assertFalse(user.isPresent());
} }
@Test @Test
public void calling_login_should_try_to_authenticate_user_who_is_not_disabled() { public void callingLoginShouldTryToAuthenticateUserWhoIsNotDisabled() {
when(userDAO.findByName("test")).thenReturn(normalUser); Mockito.when(userDAO.findByName("test")).thenReturn(normalUser);
when(passwordEncryptionService.authenticate(anyString(), any(byte[].class), any(byte[].class))).thenReturn(false); Mockito.when(passwordEncryptionService.authenticate(Mockito.anyString(), Mockito.any(byte[].class), Mockito.any(byte[].class)))
.thenReturn(false);
userService.login("test", "password"); userService.login("test", "password");
verify(passwordEncryptionService).authenticate("password", ENCRYPTED_PASSWORD, SALT); Mockito.verify(passwordEncryptionService).authenticate("password", ENCRYPTED_PASSWORD, SALT);
} }
@Test @Test
public void calling_login_should_not_return_user_object_on_unsuccessful_authentication() { public void callingLoginShouldNotReturnUserObjectOnUnsuccessfulAuthentication() {
when(userDAO.findByName("test")).thenReturn(normalUser); Mockito.when(userDAO.findByName("test")).thenReturn(normalUser);
when(passwordEncryptionService.authenticate(anyString(), any(byte[].class), any(byte[].class))).thenReturn(false); Mockito.when(passwordEncryptionService.authenticate(Mockito.anyString(), Mockito.any(byte[].class), Mockito.any(byte[].class)))
.thenReturn(false);
Optional<User> authenticatedUser = userService.login("test", "password"); Optional<User> authenticatedUser = userService.login("test", "password");
assertFalse(authenticatedUser.isPresent()); Assert.assertFalse(authenticatedUser.isPresent());
} }
@Test @Test
public void calling_login_should_execute_post_login_activities_for_user_on_successful_authentication() { public void callingLoginShouldExecutePostLoginActivitiesForUserOnSuccessfulAuthentication() {
when(userDAO.findByName("test")).thenReturn(normalUser); Mockito.when(userDAO.findByName("test")).thenReturn(normalUser);
when(passwordEncryptionService.authenticate(anyString(), any(byte[].class), any(byte[].class))).thenReturn(true); Mockito.when(passwordEncryptionService.authenticate(Mockito.anyString(), Mockito.any(byte[].class), Mockito.any(byte[].class)))
doNothing().when(postLoginActivities).executeFor(any(User.class)); .thenReturn(true);
Mockito.doNothing().when(postLoginActivities).executeFor(Mockito.any(User.class));
userService.login("test", "password"); userService.login("test", "password");
verify(postLoginActivities).executeFor(normalUser); Mockito.verify(postLoginActivities).executeFor(normalUser);
} }
@Test @Test
public void calling_login_should_return_user_object_on_successful_authentication() { public void callingLoginShouldReturnUserObjectOnSuccessfulAuthentication() {
when(userDAO.findByName("test")).thenReturn(normalUser); Mockito.when(userDAO.findByName("test")).thenReturn(normalUser);
when(passwordEncryptionService.authenticate(anyString(), any(byte[].class), any(byte[].class))).thenReturn(true); Mockito.when(passwordEncryptionService.authenticate(Mockito.anyString(), Mockito.any(byte[].class), Mockito.any(byte[].class)))
doNothing().when(postLoginActivities).executeFor(any(User.class)); .thenReturn(true);
Mockito.doNothing().when(postLoginActivities).executeFor(Mockito.any(User.class));
Optional<User> authenticatedUser = userService.login("test", "password"); Optional<User> authenticatedUser = userService.login("test", "password");
assertTrue(authenticatedUser.isPresent()); Assert.assertTrue(authenticatedUser.isPresent());
assertEquals(normalUser, authenticatedUser.get()); Assert.assertEquals(normalUser, authenticatedUser.get());
} }
@Test @Test
public void api_login_should_not_return_user_if_apikey_null() { public void apiLoginShouldNotReturnUserIfApikeyNull() {
Optional<User> user = userService.login(null); Optional<User> user = userService.login(null);
assertFalse(user.isPresent()); Assert.assertFalse(user.isPresent());
} }
@Test @Test
public void api_login_should_lookup_user_by_apikey() { public void apiLoginShouldLookupUserByApikey() {
when(userDAO.findByApiKey("apikey")).thenReturn(null); Mockito.when(userDAO.findByApiKey("apikey")).thenReturn(null);
userService.login("apikey"); userService.login("apikey");
verify(userDAO).findByApiKey("apikey"); Mockito.verify(userDAO).findByApiKey("apikey");
} }
@Test @Test
public void api_login_should_not_return_user_if_user_not_found_from_lookup_by_apikey() { public void apiLoginShouldNotReturnUserIfUserNotFoundFromLookupByApikey() {
when(userDAO.findByApiKey("apikey")).thenReturn(null); Mockito.when(userDAO.findByApiKey("apikey")).thenReturn(null);
Optional<User> user = userService.login("apikey"); Optional<User> user = userService.login("apikey");
assertFalse(user.isPresent()); Assert.assertFalse(user.isPresent());
} }
@Test @Test
public void api_login_should_not_return_user_if_user_found_from_apikey_lookup_is_disabled() { public void apiLoginShouldNotReturnUserIfUserFoundFromApikeyLookupIsDisabled() {
when(userDAO.findByApiKey("apikey")).thenReturn(disabledUser); Mockito.when(userDAO.findByApiKey("apikey")).thenReturn(disabledUser);
Optional<User> user = userService.login("apikey"); Optional<User> user = userService.login("apikey");
assertFalse(user.isPresent()); Assert.assertFalse(user.isPresent());
} }
@Test @Test
public void api_login_should_perform_post_login_activities_if_user_found_from_apikey_lookup_not_disabled() { public void apiLoginShouldPerformPostLoginActivitiesIfUserFoundFromApikeyLookupNotDisabled() {
when(userDAO.findByApiKey("apikey")).thenReturn(normalUser); Mockito.when(userDAO.findByApiKey("apikey")).thenReturn(normalUser);
userService.login("apikey"); userService.login("apikey");
verify(postLoginActivities).executeFor(normalUser); Mockito.verify(postLoginActivities).executeFor(normalUser);
} }
@Test @Test
public void api_login_should_return_user_if_user_found_from_apikey_lookup_not_disabled() { public void apiLoginShouldReturnUserIfUserFoundFromApikeyLookupNotDisabled() {
when(userDAO.findByApiKey("apikey")).thenReturn(normalUser); Mockito.when(userDAO.findByApiKey("apikey")).thenReturn(normalUser);
Optional<User> returnedUser = userService.login("apikey"); Optional<User> returnedUser = userService.login("apikey");
assertEquals(normalUser, returnedUser.get()); Assert.assertEquals(normalUser, returnedUser.get());
} }
} }

View File

@@ -1,12 +1,9 @@
package com.commafeed.frontend.auth; package com.commafeed.frontend.auth;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Optional; import java.util.Optional;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito;
import com.commafeed.backend.model.User; import com.commafeed.backend.model.User;
import com.commafeed.backend.service.UserService; import com.commafeed.backend.service.UserService;
@@ -16,13 +13,13 @@ import com.commafeed.frontend.session.SessionHelper;
public class SecurityCheckFactoryTest { public class SecurityCheckFactoryTest {
@Test @Test
public void cookie_login_should_perform_post_login_activities_if_user_is_logged_in() { public void cookieLoginShouldPerformPostLoginActivities() {
User userInSession = new User(); User userInSession = new User();
SessionHelper sessionHelper = mock(SessionHelper.class); SessionHelper sessionHelper = Mockito.mock(SessionHelper.class);
when(sessionHelper.getLoggedInUser()).thenReturn(Optional.of(userInSession)); Mockito.when(sessionHelper.getLoggedInUser()).thenReturn(Optional.of(userInSession));
PostLoginActivities postLoginActivities = mock(PostLoginActivities.class); PostLoginActivities postLoginActivities = Mockito.mock(PostLoginActivities.class);
UserService service = new UserService(null, null, null, null, null, null, null, postLoginActivities); UserService service = new UserService(null, null, null, null, null, null, null, postLoginActivities);
@@ -30,7 +27,7 @@ public class SecurityCheckFactoryTest {
factory.userService = service; factory.userService = service;
factory.cookieSessionLogin(sessionHelper); factory.cookieSessionLogin(sessionHelper);
verify(postLoginActivities).executeFor(userInSession); Mockito.verify(postLoginActivities).executeFor(userInSession);
} }
} }

View File

@@ -1,18 +1,12 @@
package com.commafeed.frontend.resource; package com.commafeed.frontend.resource;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Arrays; import java.util.Arrays;
import java.util.Optional; import java.util.Optional;
import org.junit.Test; import org.junit.Test;
import org.mockito.ArgumentMatchers;
import org.mockito.InOrder; import org.mockito.InOrder;
import org.mockito.Matchers; import org.mockito.Mockito;
import com.commafeed.backend.model.User; import com.commafeed.backend.model.User;
import com.commafeed.backend.model.UserRole.Role; import com.commafeed.backend.model.UserRole.Role;
@@ -24,16 +18,16 @@ import com.commafeed.frontend.session.SessionHelper;
public class UserRestTest { public class UserRestTest {
@Test @Test
public void login_should_not_populate_http_session_if_unsuccessfull() { public void loginShouldNotPopulateHttpSessionIfUnsuccessfull() {
// Absent user // Absent user
Optional<User> absentUser = Optional.empty(); Optional<User> absentUser = Optional.empty();
// Create UserService partial mock // Create UserService partial mock
UserService service = mock(UserService.class); UserService service = Mockito.mock(UserService.class);
when(service.login("user", "password")).thenReturn(absentUser); Mockito.when(service.login("user", "password")).thenReturn(absentUser);
UserREST userREST = new UserREST(null, null, null, service, null, null, null); UserREST userREST = new UserREST(null, null, null, service, null, null, null);
SessionHelper sessionHelper = mock(SessionHelper.class); SessionHelper sessionHelper = Mockito.mock(SessionHelper.class);
LoginRequest req = new LoginRequest(); LoginRequest req = new LoginRequest();
req.setName("user"); req.setName("user");
@@ -41,43 +35,43 @@ public class UserRestTest {
userREST.login(req, sessionHelper); userREST.login(req, sessionHelper);
verify(sessionHelper, never()).setLoggedInUser(any(User.class)); Mockito.verify(sessionHelper, Mockito.never()).setLoggedInUser(Mockito.any(User.class));
} }
@Test @Test
public void login_should_populate_http_session_if_successfull() { public void loginShouldPopulateHttpSessionIfSuccessfull() {
// Create a user // Create a user
User user = new User(); User user = new User();
// Create UserService mock // Create UserService mock
UserService service = mock(UserService.class); UserService service = Mockito.mock(UserService.class);
when(service.login("user", "password")).thenReturn(Optional.of(user)); Mockito.when(service.login("user", "password")).thenReturn(Optional.of(user));
LoginRequest req = new LoginRequest(); LoginRequest req = new LoginRequest();
req.setName("user"); req.setName("user");
req.setPassword("password"); req.setPassword("password");
UserREST userREST = new UserREST(null, null, null, service, null, null, null); UserREST userREST = new UserREST(null, null, null, service, null, null, null);
SessionHelper sessionHelper = mock(SessionHelper.class); SessionHelper sessionHelper = Mockito.mock(SessionHelper.class);
userREST.login(req, sessionHelper); userREST.login(req, sessionHelper);
verify(sessionHelper).setLoggedInUser(user); Mockito.verify(sessionHelper).setLoggedInUser(user);
} }
@Test @Test
public void register_should_register_and_then_login() { public void registerShouldRegisterAndThenLogin() {
// Create UserService mock // Create UserService mock
UserService service = mock(UserService.class); UserService service = Mockito.mock(UserService.class);
RegistrationRequest req = new RegistrationRequest(); RegistrationRequest req = new RegistrationRequest();
req.setName("user"); req.setName("user");
req.setPassword("password"); req.setPassword("password");
req.setEmail("test@test.com"); req.setEmail("test@test.com");
InOrder inOrder = inOrder(service); InOrder inOrder = Mockito.inOrder(service);
SessionHelper sessionHelper = mock(SessionHelper.class); SessionHelper sessionHelper = Mockito.mock(SessionHelper.class);
UserREST userREST = new UserREST(null, null, null, service, null, null, null); UserREST userREST = new UserREST(null, null, null, service, null, null, null);
userREST.registerUser(req, sessionHelper); userREST.registerUser(req, sessionHelper);
@@ -87,26 +81,27 @@ public class UserRestTest {
} }
@Test @Test
public void register_should_populate_http_session() { public void registerShouldPopulateHttpSession() {
// Create a user // Create a user
User user = new User(); User user = new User();
// Create UserService mock // Create UserService mock
UserService service = mock(UserService.class); UserService service = Mockito.mock(UserService.class);
when(service.register(any(String.class), any(String.class), any(String.class), Matchers.anyListOf(Role.class))).thenReturn(user); Mockito.when(service.register(Mockito.any(String.class), Mockito.any(String.class), Mockito.any(String.class),
when(service.login(any(String.class), any(String.class))).thenReturn(Optional.of(user)); ArgumentMatchers.anyList())).thenReturn(user);
Mockito.when(service.login(Mockito.any(String.class), Mockito.any(String.class))).thenReturn(Optional.of(user));
RegistrationRequest req = new RegistrationRequest(); RegistrationRequest req = new RegistrationRequest();
req.setName("user"); req.setName("user");
req.setPassword("password"); req.setPassword("password");
req.setEmail("test@test.com"); req.setEmail("test@test.com");
SessionHelper sessionHelper = mock(SessionHelper.class); SessionHelper sessionHelper = Mockito.mock(SessionHelper.class);
UserREST userREST = new UserREST(null, null, null, service, null, null, null); UserREST userREST = new UserREST(null, null, null, service, null, null, null);
userREST.registerUser(req, sessionHelper); userREST.registerUser(req, sessionHelper);
verify(sessionHelper).setLoggedInUser(user); Mockito.verify(sessionHelper).setLoggedInUser(user);
} }
} }

View File

@@ -1,9 +1,5 @@
package com.commafeed.frontend.session; package com.commafeed.frontend.session;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Optional; import java.util.Optional;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -11,27 +7,28 @@ import javax.servlet.http.HttpSession;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito;
import com.commafeed.backend.model.User; import com.commafeed.backend.model.User;
public class SessionHelperTest { public class SessionHelperTest {
private static String SESSION_KEY_USER = "user"; private static final String SESSION_KEY_USER = "user";
@Test @Test
public void getting_user_does_not_create_a_session_if_not_present() { public void gettingUserDoesNotCreateSession() {
HttpServletRequest request = mock(HttpServletRequest.class); HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
SessionHelper sessionHelper = new SessionHelper(request); SessionHelper sessionHelper = new SessionHelper(request);
sessionHelper.getLoggedInUser(); sessionHelper.getLoggedInUser();
verify(request).getSession(false); Mockito.verify(request).getSession(false);
} }
@Test @Test
public void getting_user_should_not_return_user_if_there_is_no_preexisting_http_session() { public void gettingUserShouldNotReturnUserIfThereIsNoPreexistingHttpSession() {
HttpServletRequest request = mock(HttpServletRequest.class); HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
when(request.getSession(false)).thenReturn(null); Mockito.when(request.getSession(false)).thenReturn(null);
SessionHelper sessionHelper = new SessionHelper(request); SessionHelper sessionHelper = new SessionHelper(request);
Optional<User> user = sessionHelper.getLoggedInUser(); Optional<User> user = sessionHelper.getLoggedInUser();
@@ -40,12 +37,12 @@ public class SessionHelperTest {
} }
@Test @Test
public void getting_user_should_not_return_user_if_user_not_present_in_http_session() { public void gettingUserShouldNotReturnUserIfUserNotPresentInHttpSession() {
HttpSession session = mock(HttpSession.class); HttpSession session = Mockito.mock(HttpSession.class);
when(session.getAttribute(SESSION_KEY_USER)).thenReturn(null); Mockito.when(session.getAttribute(SESSION_KEY_USER)).thenReturn(null);
HttpServletRequest request = mock(HttpServletRequest.class); HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
when(request.getSession(false)).thenReturn(session); Mockito.when(request.getSession(false)).thenReturn(session);
SessionHelper sessionHelper = new SessionHelper(request); SessionHelper sessionHelper = new SessionHelper(request);
Optional<User> user = sessionHelper.getLoggedInUser(); Optional<User> user = sessionHelper.getLoggedInUser();
@@ -54,14 +51,14 @@ public class SessionHelperTest {
} }
@Test @Test
public void getting_user_should_return_user_if_user_present_in_http_session() { public void gettingUserShouldReturnUserIfUserPresentInHttpSession() {
User userInSession = new User(); User userInSession = new User();
HttpSession session = mock(HttpSession.class); HttpSession session = Mockito.mock(HttpSession.class);
when(session.getAttribute(SESSION_KEY_USER)).thenReturn(userInSession); Mockito.when(session.getAttribute(SESSION_KEY_USER)).thenReturn(userInSession);
HttpServletRequest request = mock(HttpServletRequest.class); HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
when(request.getSession(false)).thenReturn(session); Mockito.when(request.getSession(false)).thenReturn(session);
SessionHelper sessionHelper = new SessionHelper(request); SessionHelper sessionHelper = new SessionHelper(request);
Optional<User> user = sessionHelper.getLoggedInUser(); Optional<User> user = sessionHelper.getLoggedInUser();