mirror of
https://github.com/MarginaliaSearch/MarginaliaSearch.git
synced 2025-02-23 21:18:58 +00:00
Added rudimentary !bang-support
This commit is contained in:
parent
cfd01c7dbe
commit
275e42197c
@ -233,4 +233,12 @@ public class EdgeSearchE2ETest extends E2ETestBase {
|
|||||||
|
|
||||||
Files.move(driver.getScreenshotAs(OutputType.FILE).toPath(), screenshotFilename("eval"));
|
Files.move(driver.getScreenshotAs(OutputType.FILE).toPath(), screenshotFilename("eval"));
|
||||||
}
|
}
|
||||||
|
@Test
|
||||||
|
public void testBang() throws IOException {
|
||||||
|
var driver = chrome.getWebDriver();
|
||||||
|
|
||||||
|
driver.get("http://proxyNginx/search?query=!g test");
|
||||||
|
|
||||||
|
Files.move(driver.getScreenshotAs(OutputType.FILE).toPath(), screenshotFilename("bang"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ import nu.marginalia.wmsa.edge.index.client.EdgeIndexClient;
|
|||||||
import nu.marginalia.wmsa.edge.search.command.CommandEvaluator;
|
import nu.marginalia.wmsa.edge.search.command.CommandEvaluator;
|
||||||
import nu.marginalia.wmsa.edge.search.command.ResponseType;
|
import nu.marginalia.wmsa.edge.search.command.ResponseType;
|
||||||
import nu.marginalia.wmsa.edge.search.command.SearchParameters;
|
import nu.marginalia.wmsa.edge.search.command.SearchParameters;
|
||||||
|
import nu.marginalia.wmsa.edge.search.exceptions.RedirectException;
|
||||||
import nu.marginalia.wmsa.edge.search.query.model.EdgeUserSearchParameters;
|
import nu.marginalia.wmsa.edge.search.query.model.EdgeUserSearchParameters;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -165,6 +166,9 @@ public class EdgeSearchService extends Service {
|
|||||||
try {
|
try {
|
||||||
return searchCommandEvaulator.eval(ctx, params, humanQuery);
|
return searchCommandEvaulator.eval(ctx, params, humanQuery);
|
||||||
}
|
}
|
||||||
|
catch (RedirectException ex) {
|
||||||
|
response.redirect(ex.newUrl);
|
||||||
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
logger.error("Error", ex);
|
logger.error("Error", ex);
|
||||||
serveError(ctx, response);
|
serveError(ctx, response);
|
||||||
|
@ -2,14 +2,15 @@ package nu.marginalia.wmsa.edge.search.command;
|
|||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import nu.marginalia.wmsa.configuration.server.Context;
|
import nu.marginalia.wmsa.configuration.server.Context;
|
||||||
|
import nu.marginalia.wmsa.edge.search.command.commands.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class CommandEvaluator {
|
public class CommandEvaluator {
|
||||||
|
|
||||||
List<SearchCommandInterface> commands = new ArrayList<>();
|
private final List<SearchCommandInterface> commands = new ArrayList<>();
|
||||||
|
private final SearchCommand search;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public CommandEvaluator(
|
public CommandEvaluator(
|
||||||
@ -17,13 +18,16 @@ public class CommandEvaluator {
|
|||||||
ConvertCommand convert,
|
ConvertCommand convert,
|
||||||
DefinitionCommand define,
|
DefinitionCommand define,
|
||||||
SiteSearchCommand site,
|
SiteSearchCommand site,
|
||||||
|
BangCommand bang,
|
||||||
SearchCommand search
|
SearchCommand search
|
||||||
) {
|
) {
|
||||||
commands.add(browse);
|
commands.add(browse);
|
||||||
commands.add(convert);
|
commands.add(convert);
|
||||||
commands.add(define);
|
commands.add(define);
|
||||||
commands.add(site);
|
commands.add(site);
|
||||||
commands.add(search);
|
commands.add(bang);
|
||||||
|
|
||||||
|
this.search = search;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object eval(Context ctx, SearchParameters parameters, String query) {
|
public Object eval(Context ctx, SearchParameters parameters, String query) {
|
||||||
@ -33,8 +37,10 @@ public class CommandEvaluator {
|
|||||||
return ret.get();
|
return ret.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Search command *should* always evaluate
|
|
||||||
throw new IllegalStateException("Search Command returned Optional.empty()");
|
// Always process the search command last
|
||||||
|
return search.process(ctx, parameters, query)
|
||||||
|
.orElseThrow(() -> new IllegalStateException("Search Command returned Optional.empty()!") /* This Should Not be Possible™ */ );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,73 @@
|
|||||||
|
package nu.marginalia.wmsa.edge.search.command.commands;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import nu.marginalia.wmsa.configuration.server.Context;
|
||||||
|
import nu.marginalia.wmsa.edge.assistant.screenshot.ScreenshotService;
|
||||||
|
import nu.marginalia.wmsa.edge.data.dao.EdgeDataStoreDao;
|
||||||
|
import nu.marginalia.wmsa.edge.data.dao.task.EdgeDomainBlacklist;
|
||||||
|
import nu.marginalia.wmsa.edge.model.EdgeDomain;
|
||||||
|
import nu.marginalia.wmsa.edge.model.EdgeId;
|
||||||
|
import nu.marginalia.wmsa.edge.search.command.SearchCommandInterface;
|
||||||
|
import nu.marginalia.wmsa.edge.search.command.SearchParameters;
|
||||||
|
import nu.marginalia.wmsa.edge.search.exceptions.RedirectException;
|
||||||
|
import nu.marginalia.wmsa.edge.search.model.BrowseResultSet;
|
||||||
|
import nu.marginalia.wmsa.renderer.mustache.MustacheRenderer;
|
||||||
|
import nu.marginalia.wmsa.renderer.mustache.RendererFactory;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class BangCommand implements SearchCommandInterface {
|
||||||
|
private final Map<String, String> bangsToPattern = new HashMap<>();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public BangCommand()
|
||||||
|
{
|
||||||
|
bangsToPattern.put("!g", "https://www.google.com/search?q=%s");
|
||||||
|
bangsToPattern.put("!ddg", "https://duckduckgo.com/search?q=%s");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Object> process(Context ctx, SearchParameters parameters, String query) {
|
||||||
|
|
||||||
|
for (var entry : bangsToPattern.entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
matchBangPattern(query, entry.getKey(), entry.getValue());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void matchBangPattern(String query, String bangKey, String urlPattern) {
|
||||||
|
for (int idx = query.indexOf(bangKey); idx >= 0; idx = query.indexOf(bangKey, idx + 1)) {
|
||||||
|
|
||||||
|
if (idx > 0) { // Don't match "search term!b", require either "!b term" or "search term !b"
|
||||||
|
if (!Character.isSpaceChar(query.charAt(idx-1))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int nextIdx = idx + bangKey.length();
|
||||||
|
|
||||||
|
if (nextIdx >= query.length()) { // allow "search term !b"
|
||||||
|
redirect(urlPattern, query.substring(0, idx));
|
||||||
|
}
|
||||||
|
else if (Character.isSpaceChar(query.charAt(nextIdx))) { // skip matches on pattern "!bsearch term" for !b
|
||||||
|
redirect(urlPattern, query.substring(0, idx).stripTrailing() + " " + query.substring(nextIdx).stripLeading());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void redirect(String pattern, String terms) {
|
||||||
|
var url = String.format(pattern, URLEncoder.encode(terms.trim(), StandardCharsets.UTF_8));
|
||||||
|
throw new RedirectException(url);
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package nu.marginalia.wmsa.edge.search.command;
|
package nu.marginalia.wmsa.edge.search.command.commands;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import nu.marginalia.wmsa.configuration.server.Context;
|
import nu.marginalia.wmsa.configuration.server.Context;
|
||||||
@ -7,6 +7,8 @@ import nu.marginalia.wmsa.edge.data.dao.EdgeDataStoreDao;
|
|||||||
import nu.marginalia.wmsa.edge.data.dao.task.EdgeDomainBlacklist;
|
import nu.marginalia.wmsa.edge.data.dao.task.EdgeDomainBlacklist;
|
||||||
import nu.marginalia.wmsa.edge.model.EdgeDomain;
|
import nu.marginalia.wmsa.edge.model.EdgeDomain;
|
||||||
import nu.marginalia.wmsa.edge.model.EdgeId;
|
import nu.marginalia.wmsa.edge.model.EdgeId;
|
||||||
|
import nu.marginalia.wmsa.edge.search.command.SearchCommandInterface;
|
||||||
|
import nu.marginalia.wmsa.edge.search.command.SearchParameters;
|
||||||
import nu.marginalia.wmsa.edge.search.model.BrowseResultSet;
|
import nu.marginalia.wmsa.edge.search.model.BrowseResultSet;
|
||||||
import nu.marginalia.wmsa.renderer.mustache.MustacheRenderer;
|
import nu.marginalia.wmsa.renderer.mustache.MustacheRenderer;
|
||||||
import nu.marginalia.wmsa.renderer.mustache.RendererFactory;
|
import nu.marginalia.wmsa.renderer.mustache.RendererFactory;
|
@ -1,8 +1,11 @@
|
|||||||
package nu.marginalia.wmsa.edge.search.command;
|
package nu.marginalia.wmsa.edge.search.command.commands;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import nu.marginalia.wmsa.configuration.server.Context;
|
import nu.marginalia.wmsa.configuration.server.Context;
|
||||||
import nu.marginalia.wmsa.edge.search.UnitConversion;
|
import nu.marginalia.wmsa.edge.search.UnitConversion;
|
||||||
|
import nu.marginalia.wmsa.edge.search.command.ResponseType;
|
||||||
|
import nu.marginalia.wmsa.edge.search.command.SearchCommandInterface;
|
||||||
|
import nu.marginalia.wmsa.edge.search.command.SearchParameters;
|
||||||
import nu.marginalia.wmsa.renderer.mustache.MustacheRenderer;
|
import nu.marginalia.wmsa.renderer.mustache.MustacheRenderer;
|
||||||
import nu.marginalia.wmsa.renderer.mustache.RendererFactory;
|
import nu.marginalia.wmsa.renderer.mustache.RendererFactory;
|
||||||
|
|
@ -1,11 +1,14 @@
|
|||||||
|
|
||||||
package nu.marginalia.wmsa.edge.search.command;
|
package nu.marginalia.wmsa.edge.search.command.commands;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import nu.marginalia.wmsa.configuration.server.Context;
|
import nu.marginalia.wmsa.configuration.server.Context;
|
||||||
import nu.marginalia.wmsa.edge.assistant.client.AssistantClient;
|
import nu.marginalia.wmsa.edge.assistant.client.AssistantClient;
|
||||||
import nu.marginalia.wmsa.edge.assistant.dict.DictionaryResponse;
|
import nu.marginalia.wmsa.edge.assistant.dict.DictionaryResponse;
|
||||||
|
import nu.marginalia.wmsa.edge.search.command.ResponseType;
|
||||||
|
import nu.marginalia.wmsa.edge.search.command.SearchCommandInterface;
|
||||||
|
import nu.marginalia.wmsa.edge.search.command.SearchParameters;
|
||||||
import nu.marginalia.wmsa.renderer.mustache.MustacheRenderer;
|
import nu.marginalia.wmsa.renderer.mustache.MustacheRenderer;
|
||||||
import nu.marginalia.wmsa.renderer.mustache.RendererFactory;
|
import nu.marginalia.wmsa.renderer.mustache.RendererFactory;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
@ -1,4 +1,4 @@
|
|||||||
package nu.marginalia.wmsa.edge.search.command;
|
package nu.marginalia.wmsa.edge.search.command.commands;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import nu.marginalia.wmsa.configuration.server.Context;
|
import nu.marginalia.wmsa.configuration.server.Context;
|
||||||
@ -6,6 +6,9 @@ import nu.marginalia.wmsa.edge.data.dao.EdgeDataStoreDao;
|
|||||||
import nu.marginalia.wmsa.edge.data.dao.task.EdgeDomainBlacklist;
|
import nu.marginalia.wmsa.edge.data.dao.task.EdgeDomainBlacklist;
|
||||||
import nu.marginalia.wmsa.edge.search.EdgeSearchOperator;
|
import nu.marginalia.wmsa.edge.search.EdgeSearchOperator;
|
||||||
import nu.marginalia.wmsa.edge.search.UnitConversion;
|
import nu.marginalia.wmsa.edge.search.UnitConversion;
|
||||||
|
import nu.marginalia.wmsa.edge.search.command.ResponseType;
|
||||||
|
import nu.marginalia.wmsa.edge.search.command.SearchCommandInterface;
|
||||||
|
import nu.marginalia.wmsa.edge.search.command.SearchParameters;
|
||||||
import nu.marginalia.wmsa.edge.search.model.DecoratedSearchResults;
|
import nu.marginalia.wmsa.edge.search.model.DecoratedSearchResults;
|
||||||
import nu.marginalia.wmsa.edge.search.query.model.EdgeUserSearchParameters;
|
import nu.marginalia.wmsa.edge.search.query.model.EdgeUserSearchParameters;
|
||||||
import nu.marginalia.wmsa.renderer.mustache.MustacheRenderer;
|
import nu.marginalia.wmsa.renderer.mustache.MustacheRenderer;
|
||||||
@ -17,10 +20,10 @@ import java.util.Optional;
|
|||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
public class SearchCommand implements SearchCommandInterface {
|
public class SearchCommand implements SearchCommandInterface {
|
||||||
private EdgeDomainBlacklist blacklist;
|
private final EdgeDomainBlacklist blacklist;
|
||||||
private EdgeDataStoreDao dataStoreDao;
|
private final EdgeDataStoreDao dataStoreDao;
|
||||||
private EdgeSearchOperator searchOperator;
|
private final EdgeSearchOperator searchOperator;
|
||||||
private UnitConversion unitConversion;
|
private final UnitConversion unitConversion;
|
||||||
private final MustacheRenderer<DecoratedSearchResults> searchResultsRenderer;
|
private final MustacheRenderer<DecoratedSearchResults> searchResultsRenderer;
|
||||||
private final MustacheRenderer<DecoratedSearchResults> searchResultsRendererGmi;
|
private final MustacheRenderer<DecoratedSearchResults> searchResultsRendererGmi;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package nu.marginalia.wmsa.edge.search.command;
|
package nu.marginalia.wmsa.edge.search.command.commands;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import nu.marginalia.wmsa.configuration.server.Context;
|
import nu.marginalia.wmsa.configuration.server.Context;
|
||||||
@ -8,6 +8,9 @@ import nu.marginalia.wmsa.edge.index.model.IndexBlock;
|
|||||||
import nu.marginalia.wmsa.edge.model.crawl.EdgeDomainIndexingState;
|
import nu.marginalia.wmsa.edge.model.crawl.EdgeDomainIndexingState;
|
||||||
import nu.marginalia.wmsa.edge.search.EdgeSearchOperator;
|
import nu.marginalia.wmsa.edge.search.EdgeSearchOperator;
|
||||||
import nu.marginalia.wmsa.edge.search.EdgeSearchProfile;
|
import nu.marginalia.wmsa.edge.search.EdgeSearchProfile;
|
||||||
|
import nu.marginalia.wmsa.edge.search.command.ResponseType;
|
||||||
|
import nu.marginalia.wmsa.edge.search.command.SearchCommandInterface;
|
||||||
|
import nu.marginalia.wmsa.edge.search.command.SearchParameters;
|
||||||
import nu.marginalia.wmsa.edge.search.model.DecoratedSearchResultSet;
|
import nu.marginalia.wmsa.edge.search.model.DecoratedSearchResultSet;
|
||||||
import nu.marginalia.wmsa.edge.search.model.DecoratedSearchResults;
|
import nu.marginalia.wmsa.edge.search.model.DecoratedSearchResults;
|
||||||
import nu.marginalia.wmsa.edge.search.model.DomainInformation;
|
import nu.marginalia.wmsa.edge.search.model.DomainInformation;
|
||||||
@ -27,7 +30,6 @@ import java.util.function.Predicate;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class SiteSearchCommand implements SearchCommandInterface {
|
public class SiteSearchCommand implements SearchCommandInterface {
|
||||||
private EdgeDomainBlacklist blacklist;
|
|
||||||
private final EdgeDataStoreDao dataStoreDao;
|
private final EdgeDataStoreDao dataStoreDao;
|
||||||
private final EdgeSearchOperator searchOperator;
|
private final EdgeSearchOperator searchOperator;
|
||||||
private DomainInformationService domainInformationService;
|
private DomainInformationService domainInformationService;
|
||||||
@ -39,21 +41,18 @@ public class SiteSearchCommand implements SearchCommandInterface {
|
|||||||
private final Predicate<String> queryPatternPredicate = Pattern.compile("^site:[.A-Za-z\\-0-9]+$").asPredicate();
|
private final Predicate<String> queryPatternPredicate = Pattern.compile("^site:[.A-Za-z\\-0-9]+$").asPredicate();
|
||||||
@Inject
|
@Inject
|
||||||
public SiteSearchCommand(
|
public SiteSearchCommand(
|
||||||
EdgeDomainBlacklist blacklist,
|
DomainInformationService domainInformationService,
|
||||||
EdgeDataStoreDao dataStoreDao,
|
EdgeDataStoreDao dataStoreDao,
|
||||||
RendererFactory rendererFactory,
|
RendererFactory rendererFactory,
|
||||||
EdgeSearchOperator searchOperator,
|
EdgeSearchOperator searchOperator)
|
||||||
DomainInformationService domainInformationService)
|
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
this.blacklist = blacklist;
|
|
||||||
this.dataStoreDao = dataStoreDao;
|
this.dataStoreDao = dataStoreDao;
|
||||||
|
this.searchOperator = searchOperator;
|
||||||
|
this.domainInformationService = domainInformationService;
|
||||||
|
|
||||||
siteInfoRenderer = rendererFactory.renderer("edge/site-info");
|
siteInfoRenderer = rendererFactory.renderer("edge/site-info");
|
||||||
siteInfoRendererGmi = rendererFactory.renderer("edge/site-info-gmi");
|
siteInfoRendererGmi = rendererFactory.renderer("edge/site-info-gmi");
|
||||||
|
|
||||||
this.searchOperator = searchOperator;
|
|
||||||
this.domainInformationService = domainInformationService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -63,9 +62,7 @@ public class SiteSearchCommand implements SearchCommandInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var results = siteInfo(ctx, query);
|
var results = siteInfo(ctx, query);
|
||||||
|
|
||||||
var domain = results.getDomain();
|
var domain = results.getDomain();
|
||||||
logger.info("Domain: {}", domain);
|
|
||||||
|
|
||||||
DecoratedSearchResultSet resultSet;
|
DecoratedSearchResultSet resultSet;
|
||||||
Path screenshotPath = null;
|
Path screenshotPath = null;
|
@ -0,0 +1,14 @@
|
|||||||
|
package nu.marginalia.wmsa.edge.search.exceptions;
|
||||||
|
|
||||||
|
public class RedirectException extends RuntimeException {
|
||||||
|
public final String newUrl;
|
||||||
|
|
||||||
|
public RedirectException(String newUrl) {
|
||||||
|
this.newUrl = newUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StackTraceElement[] getStackTrace() {
|
||||||
|
return new StackTraceElement[0];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package nu.marginalia.wmsa.edge.search.command.commands;
|
||||||
|
|
||||||
|
import nu.marginalia.wmsa.edge.search.exceptions.RedirectException;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
|
||||||
|
class BangCommandTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBang() {
|
||||||
|
var bc = new BangCommand();
|
||||||
|
|
||||||
|
expectRedirectUrl("https://www.google.com/search?q=search+terms", () -> bc.process(null, null, "search terms !g"));
|
||||||
|
expectNoRedirect(() -> bc.process(null, null, "search terms!g"));
|
||||||
|
expectNoRedirect(() -> bc.process(null, null, "!gsearch terms"));
|
||||||
|
expectRedirectUrl("https://www.google.com/search?q=search+terms", () -> bc.process(null, null, "!g search terms"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void expectNoRedirect(Runnable op) {
|
||||||
|
try {
|
||||||
|
op.run();
|
||||||
|
}
|
||||||
|
catch (RedirectException ex) {
|
||||||
|
fail("Expected no redirection, but got " + ex.newUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void expectRedirectUrl(String expectedUrl, Runnable op) {
|
||||||
|
try {
|
||||||
|
op.run();
|
||||||
|
fail("Didn't intercept exception");
|
||||||
|
}
|
||||||
|
catch (RedirectException ex) {
|
||||||
|
Assertions.assertEquals(expectedUrl, ex.newUrl, "Unexpected redirect");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user