aboutsummaryrefslogtreecommitdiff
path: root/src/test/java/com/juick/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/java/com/juick/server')
-rw-r--r--src/test/java/com/juick/server/configuration/TestActivityConfiguration.java19
-rw-r--r--src/test/java/com/juick/server/tests/ServerTests.java439
2 files changed, 315 insertions, 143 deletions
diff --git a/src/test/java/com/juick/server/configuration/TestActivityConfiguration.java b/src/test/java/com/juick/server/configuration/TestActivityConfiguration.java
new file mode 100644
index 00000000..5daf4900
--- /dev/null
+++ b/src/test/java/com/juick/server/configuration/TestActivityConfiguration.java
@@ -0,0 +1,19 @@
+package com.juick.server.configuration;
+
+import com.juick.server.KeystoreManager;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.Resource;
+
+import java.io.IOException;
+
+@Configuration
+public class TestActivityConfiguration {
+ @Value("classpath:test.p12")
+ Resource keystoreFile;
+ @Bean
+ public KeystoreManager testKeystoreManager() throws IOException {
+ return new KeystoreManager(keystoreFile.getFile().getAbsolutePath(), "secret");
+ }
+}
diff --git a/src/test/java/com/juick/server/tests/ServerTests.java b/src/test/java/com/juick/server/tests/ServerTests.java
index deef6f30..7f46968f 100644
--- a/src/test/java/com/juick/server/tests/ServerTests.java
+++ b/src/test/java/com/juick/server/tests/ServerTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2017, Juick
+ * Copyright (C) 2008-2019, Juick
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -19,6 +19,7 @@ package com.juick.server.tests;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gargoylesoftware.htmlunit.CookieManager;
import com.gargoylesoftware.htmlunit.WebClient;
@@ -33,27 +34,22 @@ import com.juick.model.PrivateChats;
import com.juick.model.TagStats;
import com.juick.server.*;
import com.juick.server.api.activity.model.Context;
-import com.juick.server.api.activity.model.activities.Create;
-import com.juick.server.api.activity.model.activities.Delete;
-import com.juick.server.api.activity.model.activities.Follow;
-import com.juick.server.api.activity.model.activities.Like;
-import com.juick.server.api.activity.model.activities.Undo;
+import com.juick.server.api.activity.model.activities.*;
import com.juick.server.api.activity.model.objects.Note;
import com.juick.server.api.activity.model.objects.Person;
import com.juick.server.api.webfinger.model.Account;
import com.juick.server.api.xnodeinfo2.model.NodeInfo;
import com.juick.server.util.HttpUtils;
import com.juick.server.util.ImageUtils;
-import com.juick.server.xmpp.helpers.XMPPStatus;
-import com.juick.server.xmpp.s2s.ConnectionIn;
+import com.juick.server.www.WebApp;
import com.juick.service.*;
import com.juick.service.component.MessageEvent;
+import com.juick.test.util.MockUtils;
import com.juick.util.DateFormattersHolder;
import com.juick.util.MessageUtils;
import com.mitchellbosecke.pebble.PebbleEngine;
import com.mitchellbosecke.pebble.error.PebbleException;
import com.mitchellbosecke.pebble.template.PebbleTemplate;
-import org.apache.commons.codec.CharEncoding;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.IteratorUtils;
import org.apache.commons.io.IOUtils;
@@ -70,16 +66,22 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMock
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
import org.springframework.http.*;
+import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.client.MockRestServiceServer;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.util.DigestUtils;
import org.springframework.util.FileSystemUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.ResourceAccessException;
+import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import org.w3c.dom.Document;
@@ -91,9 +93,6 @@ import rocks.xmpp.addr.Jid;
import rocks.xmpp.core.session.Extension;
import rocks.xmpp.core.session.XmppSession;
import rocks.xmpp.core.session.XmppSessionConfiguration;
-import rocks.xmpp.core.stanza.model.StanzaError;
-import rocks.xmpp.core.stanza.model.client.ClientMessage;
-import rocks.xmpp.core.stanza.model.errors.Condition;
import javax.inject.Inject;
import javax.servlet.http.Cookie;
@@ -105,7 +104,6 @@ import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
-import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
@@ -117,17 +115,20 @@ import java.sql.Timestamp;
import java.time.Instant;
import java.util.*;
import java.util.function.BiFunction;
-import java.util.function.Function;
-import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.StreamSupport;
+import static com.juick.server.api.activity.model.Context.ACTIVITY_MEDIA_TYPE;
import static junit.framework.TestCase.assertTrue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic;
+import static org.springframework.test.web.client.ExpectedCount.times;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
+import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
+import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@@ -140,9 +141,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@TestPropertySource(properties = {
"broken_ssl_hosts=localhost,serverstorageisfull.tld",
"ios_app_id=12345678.com.juick.ExampleApp",
- "xmppbot_jid=juick@localhost/Juick",
- "hostname=localhost",
- "componentname=localhost",
"spring.jackson.default-property-inclusion=non_default"
})
@AutoConfigureMockMvc
@@ -163,12 +161,8 @@ public class ServerTests {
@Inject
private ObjectMapper jsonMapper;
@Inject
- private XMPPServer server;
- @Inject
private CommandsManager commandsManager;
@Inject
- private XMPPConnection router;
- @Inject
private SubscriptionService subscriptionService;
@Inject
private PrivacyQueriesService privacyQueriesService;
@@ -188,10 +182,6 @@ public class ServerTests {
private ServerManager serverManager;
@Inject
private KeystoreManager keystoreManager;
- @Value("${hostname:localhost}")
- private Jid jid;
- @Value("${xmppbot_jid:juick@localhost}")
- private Jid botJid;
@Value("${upload_tmp_dir:#{systemEnvironment['TEMP'] ?: '/tmp'}}")
private String tmpDir;
@Value("${img_path:#{systemEnvironment['TEMP'] ?: '/tmp'}}")
@@ -204,6 +194,32 @@ public class ServerTests {
private SignatureManager signatureManager;
@Inject
private ActivityPubManager activityPubManager;
+ @Inject
+ private WebApp webApp;
+ @Inject
+ private RestTemplate apClient;
+
+ @Value("classpath:mocks/activity/testuser.json")
+ private Resource testuserResponse;
+ @Value("classpath:mocks/activity/testfollow.json")
+ private Resource testfollowRequest;
+ @Value("classpath:static/av-96.png")
+ private Resource defaultAvatar;
+ @Value("classpath:cmyk.jpg")
+ private Resource cmykJpeg;
+ @Value("classpath:nojfif.jpg")
+ private Resource nojfif;
+ @Value("classpath:hubzilla_activity.json")
+ private Resource hubzillaActivity;
+ @Value("classpath:hubzilla_follow.json")
+ private Resource hubzillaFollow;
+ @Value("classpath:announce.json")
+ private Resource noteWithDocument;
+ @Value("classpath:2936611-57.jpg")
+ private Resource jpegNoJfifTiff;
+
+ @Inject
+ private KeystoreManager testKeystoreManager;
private static User ugnich, freefd, juick;
static String ugnichName, ugnichPassword, freefdName, freefdPassword, juickName, juickPassword;
@@ -217,10 +233,16 @@ public class ServerTests {
FileSystemUtils.deleteRecursively(Paths.get(imgDir, "photos-1024"));
FileSystemUtils.deleteRecursively(Paths.get(imgDir, "photos-512"));
FileSystemUtils.deleteRecursively(Paths.get(imgDir, "ps"));
+ FileSystemUtils.deleteRecursively(Paths.get(imgDir, "a"));
+ FileSystemUtils.deleteRecursively(Paths.get(imgDir, "ao"));
+ FileSystemUtils.deleteRecursively(Paths.get(imgDir, "as"));
Files.createDirectory(Paths.get(imgDir, "p"));
Files.createDirectory(Paths.get(imgDir, "photos-1024"));
Files.createDirectory(Paths.get(imgDir, "photos-512"));
Files.createDirectory(Paths.get(imgDir, "ps"));
+ Files.createDirectory(Paths.get(imgDir, "a"));
+ Files.createDirectory(Paths.get(imgDir, "ao"));
+ Files.createDirectory(Paths.get(imgDir, "as"));
if (!isSetUp) {
ugnichName = "ugnich";
ugnichPassword = "secret";
@@ -339,7 +361,7 @@ public class ServerTests {
Message msg3 = messagesService.getMessage(mid2).get();
assertEquals(2, msg3.getReplies());
- assertEquals("weather", msg3.getTags().get(0).getName());
+ assertEquals("weather", msg3.getTags().stream().findFirst().get().getName());
assertEquals(ugnich.getUid(), userService.checkPassword(ugnich.getName(), "x"));
assertEquals(-1, userService.checkPassword(ugnich.getName(), "xy"));
@@ -411,7 +433,7 @@ public class ServerTests {
Timestamp.class, mid).toInstant();
assertThat(rts, greaterThan(ts));
Message msg = messagesService.getReply(mid, rid);
- assertThat(rts, equalTo(msg.getTimestamp()));
+ assertThat(rts, equalTo(msg.getCreated()));
messagesService.deleteMessage(ugnich_id, mid);
}
@@ -436,11 +458,10 @@ public class ServerTests {
@Test
public void homeTestWithMessages() throws Exception {
String msgText = "Привет, я - Угнич";
- CommandResult result = commandsManager.processCommand(ugnich, msgText, URI.create("http://static.juick.com/settings/facebook.png"));
+ CommandResult result = commandsManager.processCommand(ugnich, msgText, URI.create("https://static.juick.com/settings/facebook.png"));
int mid = result.getNewMessage().get().getMid();
Message msg = messagesService.getMessage(mid).get();
tagService.createTag("тест");
- ClassPathResource defaultAvatar = new ClassPathResource("static/av-96.png");
String hash = DigestUtils.md5DigestAsHex(IOUtils.toByteArray(defaultAvatar.getInputStream()));
mockMvc.perform(
get("/api/home")
@@ -449,7 +470,7 @@ public class ServerTests {
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$[0].mid", is(msg.getMid())))
.andExpect(jsonPath("$[0].timestamp",
- is(DateFormattersHolder.getMessageFormatterInstance().format(msg.getTimestamp()))))
+ is(DateFormattersHolder.getMessageFormatterInstance().format(msg.getCreated()))))
.andExpect(jsonPath("$[0].body", is(msg.getText())))
.andExpect(jsonPath("$[0].attachment.url",
is(String.format("https://i.juick.com/p/%d.png", msg.getMid()))))
@@ -481,6 +502,11 @@ public class ServerTests {
.header("Origin", "http://api.example.net"))
.andExpect(status().isOk())
.andExpect(header().string("Access-Control-Allow-Origin", "*"));
+ mockMvc.perform(
+ get("/u/ugnich")
+ .header("Origin", "http://api.example.net"))
+ .andExpect(status().isOk())
+ .andExpect(header().string("Access-Control-Allow-Origin", "*"));
}
@Test
@@ -675,63 +701,6 @@ public class ServerTests {
.andExpect(xpath("/rss/channel/description").string("The latest messages at Juick"));
}
@Test
- public void statusPageIsUp() throws Exception {
- mockMvc.perform(get("/api/status").with(httpBasic(ugnichName, ugnichPassword))).andExpect(status().isOk());
- assertThat(server.getJid(), equalTo(jid));
- }
- @Test
- public void botIsUpAndProcessingResourceConstraints() throws Exception {
- jdbcTemplate.execute("DELETE FROM users WHERE nick='renha'");
- int renhaId = userService.createUser("renha", "umnnbt");
- Jid from = Jid.of("renha@serverstorageisfull.tld");
- jdbcTemplate.update("INSERT INTO jids(user_id,jid,active) VALUES(?,?,?)",
- renhaId, from.toEscapedString(), 1);
- rocks.xmpp.core.stanza.model.Message xmppMessage = new rocks.xmpp.core.stanza.model.Message();
- xmppMessage.setType(rocks.xmpp.core.stanza.model.Message.Type.ERROR);
- xmppMessage.setFrom(from);
- xmppMessage.setTo(botJid);
- StanzaError err = new StanzaError(StanzaError.Type.CANCEL, Condition.RESOURCE_CONSTRAINT);
- xmppMessage.setError(err);
- Function<Integer, Boolean> isActive = f -> jdbcTemplate.queryForObject("SELECT active FROM jids WHERE user_id=?", Integer.class, f) == 1;
- assertThat(isActive.apply(renhaId), equalTo(true));
- ClientMessage result = router.incomingMessage(xmppMessage);
- assertNull(result);
- assertThat(isActive.apply(renhaId), equalTo(false));
- xmppMessage.setError(null);
- xmppMessage.setType(rocks.xmpp.core.stanza.model.Message.Type.CHAT);
- xmppMessage.setBody("On");
- result = router.incomingMessage(xmppMessage);
- assertThat(result.getBody(), equalTo("XMPP notifications are activated"));
- assertTrue(isActive.apply(renhaId));
- xmppMessage.setBody("*test test");
- result = router.incomingMessage(xmppMessage);
- assertThat(result.getBody(), startsWith("New message posted"));
- xmppMessage.setFrom(from);
- xmppMessage.setBody("PING");
- result = router.incomingMessage(xmppMessage);
- assertThat(result.getBody(), equalTo("PONG"));
- int secretlySadId = userService.createUser("secretlysad", "bbk");
- xmppMessage.setTo(botJid.withLocal("secretlysad"));
- xmppMessage.setBody("What's up?");
- result = router.incomingMessage(xmppMessage);
- assertThat(result, is(nullValue()));
- xmppMessage.setTo(botJid);
- xmppMessage.setBody("@secretlysad Hey!");
- result = router.incomingMessage(xmppMessage);
- assertThat(result.getBody(), is("Private message sent"));
- assertThat(pmQueriesService.getPMMessages(renhaId, secretlySadId).size(), is(2));
- String xml = "<message xmlns=\"jabber:server\" from=\"" + botJid + "\" to=\"renha@serverstorageisfull.tld\" type=\"chat\"><body>@yo:\n" +
- "343432434\n" +
- "\n" +
- "#2 http://juick.com/2</body><thread>juick-2</thread><juick xmlns=\"http://juick.com/message\" mid=\"2\" privacy=\"1\" quote=\"\" replyto=\"0\" rid=\"0\" ts=\"2018-04-10 06:58:23\"><body>343432434</body><updated></updated><user xmlns=\"http://juick.com/user\" uname=\"yo\" uid=\"2\"></user></juick><nick xmlns=\"http://jabber.org/protocol/nick\">@yo</nick></message>";
- result = router.incomingMessage((rocks.xmpp.core.stanza.model.Message)server.parse(xml));
- String active = "<message xmlns=\"jabber:server\" from=\"renha@serverstorageisfull.tld/work\" to=\""
- + botJid.asBareJid().toEscapedString() + "\" type=\"chat\" id=\"purple553384c6\"><active xmlns=\"http://jabber.org/protocol/chatstates\"></active></message>";
- result = router.incomingMessage((rocks.xmpp.core.stanza.model.Message)server.parse(active));
- xmppMessage.setFrom(botJid);
- // TODO: assert events
- }
- @Test
public void botCommandsTests() throws Exception {
assertThat(commandsManager.processCommand(AnonymousUser.INSTANCE, "PING", emptyUri).getText(), is("PONG"));
// subscription commands have two lines, others have 1
@@ -743,21 +712,21 @@ public class ServerTests {
int uid = userService.createUser("me", "secret");
User user = userService.getUserByUID(uid).orElse(AnonymousUser.INSTANCE);
Tag yo = tagService.getTag("yo", true);
- Message msg = commandsManager.processCommand(user, "*yo yoyo", URI.create("http://static.juick.com/settings/facebook.png")).getNewMessage().get();
+ Message msg = commandsManager.processCommand(user, "*yo yoyo", URI.create("https://static.juick.com/settings/facebook.png")).getNewMessage().get();
assertThat(msg.getAttachmentType(), is("png"));
- Message msgreply = commandsManager.processCommand(user, "#" + msg.getMid() + " yyy", HttpUtils.downloadImage(URI.create("http://static.juick.com/settings/xmpp.png").toURL(), tmpDir)).getNewMessage().get();
+ Message msgreply = commandsManager.processCommand(user, "#" + msg.getMid() + " yyy", HttpUtils.downloadImage(URI.create("https://static.juick.com/settings/xmpp.png").toURL(), tmpDir)).getNewMessage().get();
assertThat(msgreply.getAttachmentType(), equalTo("png"));
assertEquals("text should match", "yoyo",
messagesService.getMessage(msg.getMid()).get().getText());
assertEquals("tag should match", "yo",
tagService.getMessageTags(msg.getMid()).get(0).getTag().getName());
- CommandResult yoyoMsg = commandsManager.processCommand(user, "*yo", URI.create("http://static.juick.com/settings/facebook.png"));
+ CommandResult yoyoMsg = commandsManager.processCommand(user, "*yo", URI.create("https://static.juick.com/settings/facebook.png"));
assertTrue(yoyoMsg.getNewMessage().isPresent());
- assertThat(yoyoMsg.getNewMessage().get().getTags().get(0), is(yo));
+ assertThat(yoyoMsg.getNewMessage().get().getTags().stream().findFirst().get(), is(yo));
Message msg2 = yoyoMsg.getNewMessage().get();
int mid = msg2.getMid();
Timestamp last = jdbcTemplate.queryForObject("SELECT lastmessage FROM users WHERE id=?", Timestamp.class, user.getUid());
- assertThat(last.toInstant(), equalTo(yoyoMsg.getNewMessage().get().getTimestamp()));
+ assertThat(last.toInstant(), equalTo(yoyoMsg.getNewMessage().get().getCreated()));
assertEquals("should be message", true,
commandsManager.processCommand(user, String.format("#%d", mid), emptyUri).getText().startsWith("@me"));
int readerUid = userService.createUser("dummyReader", "dummySecret");
@@ -795,14 +764,14 @@ public class ServerTests {
String expectedThirdReply = "Reply posted.\n#" + mid + "/3 "
+ "https://juick.com/m/" + mid + "#3";
assertEquals("should be second reply", expectedSecondReply,
- commandsManager.processCommand(user, "#" + mid + " yoyo", URI.create("http://static.juick.com/settings/facebook.png")).getText());
+ commandsManager.processCommand(user, "#" + mid + " yoyo", URI.create("https://static.juick.com/settings/facebook.png")).getText());
assertEquals("should be third reply", expectedThirdReply,
commandsManager.processCommand(user, " \t\n #" + mid + "/2 ",
- URI.create("http://static.juick.com/settings/facebook.png")).getText());
+ URI.create("https://static.juick.com/settings/facebook.png")).getText());
Message reply = messagesService.getReplies(user, mid).stream().filter(m -> m.getRid() == 3).findFirst()
.orElse(new Message());
Timestamp lastreply = jdbcTemplate.queryForObject("SELECT lastmessage FROM users WHERE id=?", Timestamp.class, user.getUid());
- assertThat(lastreply.toInstant(), equalTo(reply.getTimestamp()));
+ assertThat(lastreply.toInstant(), equalTo(reply.getCreated()));
assertEquals("should be reply to second comment", 2, reply.getReplyto());
assertThat(commandsManager.processCommand(readerUser, "#" + mid + " *yo *there", emptyUri)
.getText(), startsWith("Reply posted"));
@@ -857,11 +826,11 @@ public class ServerTests {
"> }";
String codeAndTags = "*code\n" + expectedCodeMessage;
Message codeAndTagsMessage = commandsManager.processCommand(user, codeAndTags, emptyUri).getNewMessage().get();
- List<Tag> codeAndTagsTags = codeAndTagsMessage.getTags();
+ Set<Tag> codeAndTagsTags = codeAndTagsMessage.getTags();
assertEquals("expected single tag", 1,
codeAndTagsTags.size());
assertEquals("the single tag should be the 'code'", "code",
- codeAndTagsTags.get(0).getName());
+ codeAndTagsTags.stream().findFirst().get().getName());
assertEquals("and the message should be with a C-code and without tags", expectedCodeMessage,
codeAndTagsMessage.getText());
CommandResult result = commandsManager.processCommand(user, "*one *two *three *four *five *six test", emptyUri);
@@ -885,7 +854,7 @@ public class ServerTests {
data = "* \u043c\u0443\u0441\u043e\u0440\\n\u0423 \u043c\u0435\u043d\u044f \u043a\u0430\u0436\u0434\u0443\u044e \u043d\u0435\u0434\u0435\u043b\u044e \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043f\u043e 4-5 \u0431\u0443\u0442\u044b\u043b\u043e\u043a 1,5\u043b \u041f\u0415\u0422. \u041c\u043d\u0435 \u0433\u0435\u043c\u043e\u0440\u043d\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u043f\u043e \u043a\u0438\u043b\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0438\u043b\u0438 \u043f\u043e 5\u043a\u0433 \u044d\u0442\u043e\u0433\u043e \u043c\u0443\u0441\u043e\u0440\u0430, \u0447\u0442\u043e\u0431\u044b \u0432\u0435\u0437\u0442\u0438 \u0435\u0433\u043e \u0435\u0449\u0435 \u043a\u0443\u0434\u0430-\u0442\u043e.\\n\u041d\u0435, \u043d\u0443 \u0435\u0441\u0442\u044c \u043b\u044e\u0434\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u044e\u0442 \u0432\u0442\u043e\u0440\u0441\u044b\u0440\u044c\u0435 \u043f\u043e \u043c\u0443\u0441\u043e\u0440\u043a\u0430\u043c, \u0441\u0432\u0430\u043b\u043a\u0430\u043c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0434\u0435\u043d\u044c\u0433\u0438 \u043d\u0443\u0436\u043d\u044b. \u0418 \u0431\u044b\u0432\u0430\u044e\u0442 \u0441\u0442\u043e\u044f\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b-\u043a\u043b\u0435\u0442\u043a\u0438 \u0434\u043b\u044f \u043f\u043b\u0430\u0441\u0442\u0438\u043a\u0430, \u043d\u043e \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u0443\u0441\u043e\u0440 \u0432\u044b\u0432\u043e\u0437\u044f\u0442 \u043d\u0435 \u0447\u0430\u0441\u0442\u043e \u0438\u043b\u0438 \u043b\u044e\u0434\u0438 \u0432\u043d\u0435\u0437\u0430\u043f\u043d\u043e \u0432\u044b\u043a\u0438\u0434\u044b\u0432\u0430\u044e\u0442 \u043c\u043d\u043e\u0433\u043e \u043c\u0443\u0441\u043e\u0440\u0430, \u0442\u043e \u0432 \u0442\u043e\u0439 \u043a\u043b\u0435\u0442\u043a\u0435 \u0442\u043e\u0442 \u043c\u0443\u0441\u043e\u0440, \u0447\u0442\u043e \u043d\u0435 \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043b\u0441\u044f \u0432 \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u0445.";
result = commandsManager.processCommand(user, String.format("%s %s", tags, data), emptyUri);
assertThat(result.getNewMessage().get().getTags().size(), equalTo(2));
- assertThat(result.getNewMessage().get().getTags().get(0).getName(), equalTo("Киев"));
+ assertThat(result.getNewMessage().get().getTags().stream().findFirst().get().getName(), equalTo("Киев"));
assertThat(result.getNewMessage().get().getText(), equalTo(data));
result = commandsManager.processCommand(user, "S @unknown-user", emptyUri);
assertThat(result.getNewMessage(), is(Optional.empty()));
@@ -933,7 +902,7 @@ public class ServerTests {
mockMvc.perform(get("/api/thread?mid=" + mid + "&hash=" + freefdHash))
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].recommendations.length()", is(1)))
- .andExpect(jsonPath("$[0].recommendations[0]", is(freefdName)));
+ .andExpect(jsonPath("$[0].recommendations[0].uname", is(freefdName)));
mockMvc.perform(post("/api/like?mid=" + freefdMid + "&hash=" + freefdHash))
.andExpect(status().isForbidden());
}
@@ -1029,8 +998,8 @@ public class ServerTests {
tagService.updateTags(newMid, Collections.singletonList(banned));
assertThat(messagesService.getMessage(newMid).get().getTags().size(), is(0));
privacyQueriesService.blacklistUser(freefd, userService.getUserByUID(newUid).orElse(AnonymousUser.INSTANCE));
- assertTrue(messagesService.getMessages(AnonymousUser.INSTANCE, messagesService.getMyFeed(freefd.getUid(), 0, true))
- .stream().noneMatch(m -> m.getMid() == newMid));
+ assertTrue(messagesService.getMyFeed(freefd.getUid(), 0, true)
+ .stream().noneMatch(m -> m == newMid));
}
@Test
public void tagsShouldBeDeserializedFromXml() throws JAXBException {
@@ -1055,18 +1024,21 @@ public class ServerTests {
Tag xmlTag = (Tag) unmarshaller.unmarshal(new StringReader(tag));
assertThat(xmlTag.getName(), equalTo("yo"));
Message juickMessage = xmppMessage.getExtension(Message.class);
- assertThat(juickMessage.getTags().get(0).getName(), equalTo("yo"));
+ List<Tag> tags = new ArrayList<>(juickMessage.getTags());
+ assertThat(tags.get(0).getName(), equalTo("yo"));
}
@Test
public void messageParserSerializer() throws ParserConfigurationException,
IOException, SAXException, JAXBException {
+ Set<Tag> tags = MessageUtils.parseTags("test test" + (char) 0xA0 + "2 test3");
+ List<Tag> tagList = new ArrayList<>(tags);
+ assertEquals("First tag must be", "test", tagList.get(0).getName());
+ assertEquals("Third tag must be", "test3", tagList.get(2).getName());
+ assertEquals("Count of tags must be", 3, tagList.size());
Message msg = new Message();
- msg.setTags(MessageUtils.parseTags("test test" + (char) 0xA0 + "2 test3"));
- assertEquals("First tag must be", "test", msg.getTags().get(0).getName());
- assertEquals("Third tag must be", "test3", msg.getTags().get(2).getName());
- assertEquals("Count of tags must be", 3, msg.getTags().size());
+ msg.setTags(tags);
Instant currentDate = Instant.now();
- msg.setTimestamp(currentDate);
+ msg.setCreated(currentDate);
String jsonMessage = jsonMapper.writeValueAsString(msg);
assertEquals("date should be in timestamp field", DateFormattersHolder.getMessageFormatterInstance().format(currentDate),
JsonPath.read(jsonMessage, "$.timestamp"));
@@ -1081,7 +1053,7 @@ public class ServerTests {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
- Document doc = db.parse(new ByteArrayInputStream(sw.toString().getBytes(CharEncoding.UTF_8)));
+ Document doc = db.parse(new ByteArrayInputStream(sw.toString().getBytes(StandardCharsets.UTF_8)));
Node juickNode = doc.getDocumentElement();
NamedNodeMap attrs = juickNode.getAttributes();
assertEquals("date should be in ts field", DateFormattersHolder.getMessageFormatterInstance().format(currentDate),
@@ -1168,7 +1140,7 @@ public class ServerTests {
}
@Test
public void cmykJpegShouldBeProcessedCorrectly() throws Exception {
- CommandResult postJpgCmyk = commandsManager.processCommand(ugnich, "YO", new ClassPathResource("cmyk.jpg").getURI());
+ CommandResult postJpgCmyk = commandsManager.processCommand(ugnich, "YO", cmykJpeg.getURI());
assertThat(postJpgCmyk.getNewMessage().isPresent(), is(true));
int mid = postJpgCmyk.getNewMessage().get().getMid();
File originalFile = Paths.get(imgDir, "p", String.format("%d.jpg", mid)).toFile();
@@ -1182,7 +1154,7 @@ public class ServerTests {
}
@Test
public void JpegWithoutJfifShouldBeProcessedCorrectly() throws Exception {
- CommandResult postJpgCmyk = commandsManager.processCommand(ugnich, "YO", new ClassPathResource("nojfif.jpg").getURI());
+ CommandResult postJpgCmyk = commandsManager.processCommand(ugnich, "YO", nojfif.getURI());
assertThat(postJpgCmyk.getNewMessage().isPresent(), is(true));
int mid = postJpgCmyk.getNewMessage().get().getMid();
File originalFile = Paths.get(imgDir, "p", String.format("%d.jpg", mid)).toFile();
@@ -1210,12 +1182,19 @@ public class ServerTests {
assertThat(postJpgiPhone.getNewMessage().get().getAttachment().getHeight(), is(1280));
assertThat(postJpgiPhone.getNewMessage().get().getAttachment().getMedium().getHeight(), is(1024));
assertThat(postJpgiPhone.getNewMessage().get().getAttachment().getSmall().getHeight(), is(512));
+ CommandResult postNojfifTiff = commandsManager.processCommand(ugnich, "YO2", jpegNoJfifTiff.getURI());
+ assertThat(postNojfifTiff.getNewMessage().isPresent(), is(true));
+ int mid2 = postNojfifTiff.getNewMessage().get().getMid();
+ File originalFile2 = Paths.get(imgDir, "p", String.format("%d.jpg", mid2)).toFile();
+ assertThat(originalFile2.exists(), is(true));
+ File mediumFile2 = Paths.get(imgDir, "photos-1024", String.format("%d.jpg", mid2)).toFile();
+ assertThat(mediumFile2.exists(), is(true));
}
@Test
public void changeExtensionWhenReceiveFileWithWrongContentType() throws Exception {
Path pngOutput = Paths.get(tmpDir, "cmyk.png");
Files.deleteIfExists(pngOutput);
- Files.copy(Paths.get(new ClassPathResource("cmyk.jpg").getURI()), pngOutput);
+ Files.copy(Paths.get(cmykJpeg.getURI()), pngOutput);
assertThat(pngOutput.toFile().exists(), is(true));
CommandResult postJpgCmyk = commandsManager.processCommand(ugnich, "YO", pngOutput.toUri());
assertThat(postJpgCmyk.getNewMessage().isPresent(), is(true));
@@ -1231,7 +1210,7 @@ public class ServerTests {
Message original = jsonMapper.readValue(result.getResponse().getContentAsString(), CommandResult.class)
.getNewMessage().get();
assertThat(original.getText(), equalTo("YO"));
- assertThat(original.getUpdatedAt(), equalTo(original.getTimestamp()));
+ assertThat(original.getUpdatedAt(), equalTo(original.getCreated()));
// to have updated_at greater than ts
Thread.sleep(1000);
result = mockMvc.perform(post("/api/update").with(httpBasic(ugnichName, ugnichPassword))
@@ -1240,7 +1219,7 @@ public class ServerTests {
Message edited = jsonMapper.readValue(result.getResponse().getContentAsString(), CommandResult.class)
.getNewMessage().get();
assertThat(edited.getText(), equalTo("PEOPLE"));
- assertThat(edited.getUpdatedAt(), greaterThan(edited.getTimestamp()));
+ assertThat(edited.getUpdatedAt(), greaterThan(edited.getCreated()));
mockMvc.perform(post("/api/update").with(httpBasic(freefdName, freefdPassword))
.param("mid", String.valueOf(original.getMid()))
.param("body", "PEOPLE")).andExpect(status().is(403));
@@ -1249,7 +1228,7 @@ public class ServerTests {
.param("body", "HEY")).andExpect(status().is2xxSuccessful()).andReturn();
CommandResult comment = jsonMapper.readValue(result.getResponse().getContentAsString(), CommandResult.class);
assertThat(comment.getNewMessage().get().getText(), is("HEY"));
- assertThat(comment.getNewMessage().get().getUpdatedAt(), is(comment.getNewMessage().get().getTimestamp()));
+ assertThat(comment.getNewMessage().get().getUpdatedAt(), is(comment.getNewMessage().get().getCreated()));
// to have updated_at greater than ts
Thread.sleep(1000);
result = mockMvc.perform(post("/api/update").with(httpBasic(freefdName, freefdPassword))
@@ -1259,7 +1238,7 @@ public class ServerTests {
Message editedComment = jsonMapper.readValue(result.getResponse().getContentAsString(), CommandResult.class)
.getNewMessage().get();
assertThat(editedComment.getText(), is("HEY, JOE"));
- assertThat(editedComment.getUpdatedAt(), greaterThan(editedComment.getTimestamp()));
+ assertThat(editedComment.getUpdatedAt(), greaterThan(editedComment.getCreated()));
messagesService.deleteMessage(ugnich.getUid(), original.getMid());
}
@Test
@@ -1316,25 +1295,6 @@ public class ServerTests {
assertThat(subscriptionService.getUsersSubscribedToComments(msg, reply).size(), is(0));
}
@Test
- public void xmppStatusApi() throws Exception {
- Supplier<XMPPStatus> getStatus = () -> {
- try {
- MvcResult result = mockMvc.perform(get("/api/xmpp-status").with(httpBasic(ugnichName, ugnichPassword)))
- .andExpect(status().isOk()).andReturn();
- return jsonMapper.readValue(result.getResponse().getContentAsString(), XMPPStatus.class);
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- };
- assertThat(getStatus.get().getInbound(), is(nullValue()));
- ConnectionIn test = new ConnectionIn(server, new Socket("localhost", server.getServerPort()));
- test.from.add(Jid.of("test"));
- server.getInConnections().clear();
- server.addConnectionIn(test);
- assertThat(getStatus.get().getInbound().size(), is(1));
- }
- @Test
public void credentialsShouldNeverBeSerialized() throws Exception {
int uid = userService.createUser("yyy", "xxxx");
User yyy = userService.getUserByUID(uid).get();
@@ -1405,11 +1365,18 @@ public class ServerTests {
assertThat(messagesService.recommendMessage(mid, ermineId), is(MessagesService.RecommendStatus.Added));
assertThat(messagesService.recommendMessage(mid, fmapId), is(MessagesService.RecommendStatus.Added));
assertThat(messagesService.recommendMessage(mid, pogoId), is(MessagesService.RecommendStatus.Added));
- assertThat(messagesService.getMessage(mid).get().getLikes(), is(3));
- assertThat(CollectionUtils.isEqualCollection(messagesService.getMessageRecommendations(mid), Arrays.asList("fmap", "ermine", "pogo")), is(true));
- privacyQueriesService.blacklistUser(userService.getUserByName("monstreek"), userService.getUserByName("pogo"));
- assertThat(messagesService.getMessage(mid).get().getLikes(), is(3));
- assertThat(CollectionUtils.isEqualCollection(messagesService.getMessageRecommendations(mid), Arrays.asList("fmap", "ermine")), is(true));
+ jdbcTemplate.update("INSERT INTO favorites(user_id, user_uri, message_id, like_id, ts) " +
+ "values (0, 'http://example.com/u/test', ?, 1, now())", mid);
+ assertThat(messagesService.getMessage(mid).get().getLikes(), is(4));
+ assertThat(CollectionUtils.isEqualCollection(messagesService.getMessageRecommendations(mid)
+ .stream().map(User::getName).collect(Collectors.toList()),
+ Arrays.asList("fmap", "ermine", "pogo", "Anonymous")), is(true));
+ privacyQueriesService.blacklistUser(userService.getUserByName("monstreek"),
+ userService.getUserByName("pogo"));
+ assertThat(messagesService.getMessage(mid).get().getLikes(), is(4));
+ assertThat(CollectionUtils.isEqualCollection(messagesService.getMessageRecommendations(mid)
+ .stream().map(User::getName).collect(Collectors.toList()),
+ Arrays.asList("fmap", "ermine", "Anonymous")), is(true));
}
@Test
public void bannedUserShouldNotBeVisibleToOthers() {
@@ -1696,9 +1663,10 @@ public class ServerTests {
CommandResult result = commandsManager.processCommand(ugnich, "*test1 *test2 *test1 test3", emptyUri);
assertThat(result.getNewMessage().isPresent(), is(true));
Message msg = result.getNewMessage().get();
- assertThat(msg.getTags().size(), is (2));
- assertThat(msg.getTags().get(0).getName(), is("test1"));
- assertThat(msg.getTags().get(1).getName(), is("test2"));
+ List<Tag> tags = new ArrayList<>(msg.getTags());
+ assertThat(tags.size(), is (2));
+ assertThat(tags.get(0).getName(), is("test1"));
+ assertThat(tags.get(1).getName(), is("test2"));
assertThat(msg.getText(), is("test3"));
}
@Test
@@ -1759,6 +1727,7 @@ public class ServerTests {
replyNote.setTo(Collections.singletonList(activityPubManager.personUri(ugnich)));
replyNote.setContent("HI");
Create create = new Create();
+ create.setId(replyNote.getId());
create.setActor("http://localhost:8080/u/freefd");
create.setObject(replyNote);
signatureManager.post((Person) signatureManager.getContext(URI.create("http://localhost:8080/u/freefd")).get(),
@@ -1776,6 +1745,55 @@ public class ServerTests {
signatureManager.post(from, to, follow);
}
@Test
+ public void serviceSignatureAuth() throws Exception {
+ String meUri = "/api/me";
+ String testHost = "localhost:8080";
+ Person ugnichPerson = (Person) signatureManager.discoverPerson("ugnich@localhost:8080").get();
+ Instant now = Instant.now();
+ String requestDate = DateFormattersHolder.getHttpDateFormatter().format(now);
+ String signatureString = signatureManager.addSignature(ugnichPerson, testHost, "GET", meUri, requestDate);
+ MvcResult me = mockMvc.perform(get("/api/me")
+ .header("Host", testHost)
+ .header("Date", requestDate)
+ .header("Signature", signatureString))
+ .andExpect(status().isOk())
+ .andReturn();
+ User meUser = jsonMapper.readValue(me.getResponse().getContentAsString(), User.class);
+ assertThat(meUser, is(ugnich));
+ String testuserResponseString = IOUtils.toString(testuserResponse.getInputStream(), StandardCharsets.UTF_8);
+ ClientHttpRequestFactory originalRequestFactory = apClient.getRequestFactory();
+ URI testuserUri = URI.create("https://example.com/u/testuser");
+ URI testuserkeyUri = URI.create("https://example.com/u/testuser#main-key");
+ MockRestServiceServer restServiceServer = MockRestServiceServer.createServer(apClient);
+ restServiceServer.expect(times(3), requestTo(testuserUri))
+ .andRespond(withSuccess(testuserResponseString, MediaType.APPLICATION_JSON_UTF8));
+ restServiceServer.expect(times(3), requestTo(testuserkeyUri))
+ .andRespond(withSuccess(testuserResponseString, MediaType.APPLICATION_JSON_UTF8));
+ Person testuser = (Person)signatureManager.getContext(testuserUri).get();
+ Assert.assertThat(testuser.getPublicKey().getPublicKeyPem(), is(testKeystoreManager.getPublicKeyPem()));
+ Instant now2 = Instant.now();
+ String testRequestDate = DateFormattersHolder.getHttpDateFormatter().format(now2);
+ String inboxUri = "/api/inbox";
+ String testSignatureString =
+ signatureManager.addSignature(testuser, testHost, "POST",
+ inboxUri, testRequestDate, testKeystoreManager);
+ mockMvc.perform(post(inboxUri)
+ .header("Host", testHost)
+ .header("Date", testRequestDate)
+ .header("Signature", testSignatureString)
+ .contentType(Context.LD_JSON_MEDIA_TYPE)
+ .content(IOUtils.toByteArray(testfollowRequest.getInputStream())))
+ .andExpect(status().isAccepted());
+ mockMvc.perform(post(inboxUri)
+ .header("Host", "wronghost")
+ .header("Date", testRequestDate)
+ .header("Signature", testSignatureString)
+ .contentType(Context.LD_JSON_MEDIA_TYPE)
+ .content(IOUtils.toByteArray(testfollowRequest.getInputStream())))
+ .andExpect(status().isUnauthorized());
+ apClient.setRequestFactory(originalRequestFactory);
+ }
+ @Test
public void hostmeta() throws Exception {
MvcResult result = mockMvc.perform(get("/.well-known/host-meta"))
.andExpect(status().isOk()).andReturn();
@@ -1858,4 +1876,139 @@ public class ServerTests {
jdbcTemplate.update("INSERT INTO facebook(user_id, fb_id) VALUES(?, ?)", ugnich.getUid(), "100001866137681");
assertThat(userService.getUserByName("ugnich").isVerified(), is(true));
}
+ @Test
+ public void avatarUploadOverApi() throws Exception {
+ ClassPathResource defaultAvatar = new ClassPathResource("static/av-96.png");
+ String hash = DigestUtils.md5DigestAsHex(IOUtils.toByteArray(defaultAvatar.getInputStream()));
+ assertThat(webApp.getAvatarUrl(userService.getUserByName(freefdName)), is(String.format("http://localhost:8080/av-96-%s.png", hash)));
+
+ ClassPathResource newAvatar = new ClassPathResource("static/durov.png");
+ byte[] newAvatarData = IOUtils.toByteArray(newAvatar.getInputStream());
+ mockMvc.perform(MockMvcRequestBuilders.multipart("/api/me/upload")
+ .file("avatar", newAvatarData)
+ .with(httpBasic(freefdName, freefdPassword))
+ ).andExpect(status().isOk());
+ String newHash = DigestUtils.md5DigestAsHex(newAvatarData);
+ URI newUri = Paths.get(imgDir, "ao", String.format("%d.png", freefd.getUid())).toUri();
+ assertThat(DigestUtils.md5DigestAsHex(IOUtils.toByteArray(newUri)), is(newHash));
+ }
+ @Test
+ public void varyMvcResponse() throws Exception {
+ mockMvc.perform(get("/"))
+ .andExpect(status().isOk())
+ .andExpect(header().string("Vary", "Accept-Language"));
+ mockMvc.perform(get("/rss/ugnich/blog"))
+ .andExpect(status().isOk())
+ .andExpect(header().string("Vary", "Accept-Language"));
+ mockMvc.perform(get("/api/messages"))
+ .andExpect(status().isOk())
+ .andExpect(header().string("Vary", "Accept-Language"));
+ }
+ @Test
+ public void apiInfo() throws Exception {
+ userService.createUser("tst", "tst");
+ MvcResult result = mockMvc.perform(get("/api/info/tst"))
+ .andExpect(status().isOk())
+ .andReturn();
+ User tst = jsonMapper.readValue(result.getResponse().getContentAsString(), User.class);
+ assertThat(tst.getReaders(), is(nullValue()));
+ commandsManager.processCommand(ugnich, "S @tst", emptyUri);
+ result = mockMvc.perform(get("/api/info/tst"))
+ .andExpect(status().isOk())
+ .andReturn();
+ tst = jsonMapper.readValue(result.getResponse().getContentAsString(), User.class);
+ assertThat(tst.getReaders().size(), is(1));
+ }
+ @Test
+ public void federatedUserDeletionFlow() throws Exception {
+ String deleteJsonStr = IOUtils.toString(new ClassPathResource("delete_user.json").getURI(), StandardCharsets.UTF_8);
+ Delete delete = jsonMapper.readValue(deleteJsonStr, Delete.class);
+ ClientHttpRequestFactory originalRequestFactory = apClient.getRequestFactory();
+ MockRestServiceServer restServiceServer = MockRestServiceServer.createServer(apClient);
+ restServiceServer.expect(times(2), requestTo((String) delete.getObject()))
+ .andRespond(withStatus(HttpStatus.GONE));
+ restServiceServer.expect(requestTo((String) delete.getObject()))
+ .andRespond(response -> {
+ throw new ResourceAccessException("Connection reset");
+ });
+ mockMvc.perform(post("/api/inbox")
+ .contentType(ACTIVITY_MEDIA_TYPE)
+ .content(deleteJsonStr))
+ .andExpect(status().isAccepted());
+ mockMvc.perform(post("/api/inbox")
+ .contentType(ACTIVITY_MEDIA_TYPE)
+ .content(deleteJsonStr)
+ .header("Signature", "keyId=\"https://example.com/users/deleted#main-key\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date digest content-type\",signature=\"wHoU91JJBsIYcR1W1/57B0oG98t5Aa/TvGPw1B8KQlAp5KhpePnOzD1MZRgivBx7YKO6eYwDx+AX9dn6tjlAvzRLygv21H6UoDZFihWzeE1HM8pY2Pe4EhUgYBN0YuiKUi7W4TS9bDRAJ5vGNPUWATe+2o5Jcbux5cZYXFKKYbLBLD+/IlqPdHA2IXLZ52HFVVfBkPH5sSklV6XJtD/PHLK9R/I9w/mUpj9moUPQu44rR7KvxiGNuHla3vfDtJbkBqLMdScX91EG8373AulXPUiCCF7R2lJB0fFQedm2nSbcwBoJ32GEyOyOPFgPKG5zd9Fd5TfB1pmA8ZIE0sChfA==\""))
+ .andExpect(status().isAccepted());
+ apClient.setRequestFactory(originalRequestFactory);
+ }
+ @Test
+ public void handleIncorrectCertificates() throws Exception {
+ String deleteJsonStr = IOUtils.toString(new ClassPathResource("delete_user.json").getURI(), StandardCharsets.UTF_8);
+ Delete delete = jsonMapper.readValue(deleteJsonStr, Delete.class);
+ ClientHttpRequestFactory originalRequestFactory = apClient.getRequestFactory();
+ MockRestServiceServer restServiceServer = MockRestServiceServer.createServer(apClient);
+ restServiceServer.expect(requestTo((String) delete.getObject()))
+ .andRespond(response -> {
+ throw new ResourceAccessException("Connection reset");
+ });
+ mockMvc.perform(post("/api/inbox")
+ .contentType(ACTIVITY_MEDIA_TYPE)
+ .content(deleteJsonStr)
+ .header("Signature", "keyId=\"https://example.com/users/deleted#main-key\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date digest content-type\",signature=\"wHoU91JJBsIYcR1W1/57B0oG98t5Aa/TvGPw1B8KQlAp5KhpePnOzD1MZRgivBx7YKO6eYwDx+AX9dn6tjlAvzRLygv21H6UoDZFihWzeE1HM8pY2Pe4EhUgYBN0YuiKUi7W4TS9bDRAJ5vGNPUWATe+2o5Jcbux5cZYXFKKYbLBLD+/IlqPdHA2IXLZ52HFVVfBkPH5sSklV6XJtD/PHLK9R/I9w/mUpj9moUPQu44rR7KvxiGNuHla3vfDtJbkBqLMdScX91EG8373AulXPUiCCF7R2lJB0fFQedm2nSbcwBoJ32GEyOyOPFgPKG5zd9Fd5TfB1pmA8ZIE0sChfA==\""))
+ .andExpect(status().isAccepted());
+ apClient.setRequestFactory(originalRequestFactory);
+ }
+
+ @Test
+ public void legacyAvatarEndpoint() throws Exception {
+ mockMvc.perform(get("/api/avatar")
+ .param("uname", "unknown"))
+ .andExpect(status().isOk())
+ .andExpect(content().bytes(IOUtils.toByteArray(defaultAvatar.getInputStream())));
+ }
+ @Test
+ public void federatedAttachmentsAsLinks() throws Exception {
+ int mid = messagesService.createMessage(ugnich.getUid(), "test", StringUtils.EMPTY, Collections.emptyList());
+ Message testMessage = MockUtils.mockMessage(mid, freefd, "reply");
+ String activity = IOUtils.toString(noteWithDocument.getInputStream(), StandardCharsets.UTF_8);
+ Announce announce = jsonMapper.readValue(activity, Announce.class);
+ }
+ @Test
+ public void hubzillaActor() throws Exception {
+ String activity = IOUtils.toString(hubzillaActivity.getInputStream(), StandardCharsets.UTF_8);
+ Create create = jsonMapper.readValue(activity, Create.class);
+ String followData = IOUtils.toString(hubzillaFollow.getInputStream(), StandardCharsets.UTF_8);
+ Follow follow = jsonMapper.readValue(followData, Follow.class);
+ assertThat(follow.getActor(), is("https://ussr.win/channel/zlax"));
+ }
+ @Test
+ public void nodeinfo() throws Exception {
+ MvcResult nodeinfoXRD = mockMvc.perform(get("/.well-known/nodeinfo")
+ .contentType(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andReturn();
+ JsonNode node = jsonMapper.readTree(nodeinfoXRD.getResponse().getContentAsString());
+ assertThat(node.get("links"), notNullValue());
+ String nodeinfoUrl = node.get("links").get(0).get("href").textValue();
+ MvcResult nodeinfoData = mockMvc.perform(get(nodeinfoUrl)
+ .contentType(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andReturn();
+ JsonNode nodeinfo = jsonMapper.readTree(nodeinfoData.getResponse().getContentAsString());
+ assertThat(nodeinfo.get("software"), notNullValue());
+ assertThat(nodeinfo.get("server"), nullValue());
+ MvcResult xnodeinfoData = mockMvc.perform(get("/.well-known/x-nodeinfo2")
+ .contentType(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andReturn();
+ JsonNode xnodeinfo = jsonMapper.readTree(xnodeinfoData.getResponse().getContentAsString());
+ assertThat(xnodeinfo.get("server"), notNullValue());
+ assertThat(xnodeinfo.get("software"), nullValue());
+ }
+ @Test
+ public void anonymousUserFromZero() {
+ User user = userService.getUserByUID(0).orElse(AnonymousUser.INSTANCE);
+ assertThat(user.isAnonymous(), is(true));
+ }
}