From 0a47022611e9ade7b4cf04e8d2783e966610e136 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Thu, 22 Feb 2018 10:54:42 +0300 Subject: server and tests now runnable without config --- .../java/com/juick/server/CrosspostManager.java | 4 +- .../java/com/juick/server/TelegramBotManager.java | 2 +- .../src/main/java/com/juick/server/XMPPBot.java | 2 +- .../src/main/java/com/juick/server/XMPPServer.java | 2 +- .../server/configuration/ApiAppConfiguration.java | 4 +- .../juick/server/configuration/ApiInitializer.java | 3 +- .../server/configuration/ApiSecurityConfig.java | 2 - .../java/com/juick/server/tests/MessagesTests.java | 326 -------------- .../test/java/com/juick/server/tests/RSSTests.java | 143 ------- .../java/com/juick/server/tests/ServerTests.java | 471 +++++++++++++++++++++ .../com/juick/server/tests/XMPPServerTests.java | 190 --------- 11 files changed, 479 insertions(+), 670 deletions(-) delete mode 100644 juick-server/src/test/java/com/juick/server/tests/MessagesTests.java delete mode 100644 juick-server/src/test/java/com/juick/server/tests/RSSTests.java create mode 100644 juick-server/src/test/java/com/juick/server/tests/ServerTests.java delete mode 100644 juick-server/src/test/java/com/juick/server/tests/XMPPServerTests.java (limited to 'juick-server') diff --git a/juick-server/src/main/java/com/juick/server/CrosspostManager.java b/juick-server/src/main/java/com/juick/server/CrosspostManager.java index 1752e1ca..631e98ae 100644 --- a/juick-server/src/main/java/com/juick/server/CrosspostManager.java +++ b/juick-server/src/main/java/com/juick/server/CrosspostManager.java @@ -53,9 +53,9 @@ public class CrosspostManager implements ApplicationListener { @Inject private CrosspostService crosspostService; - @Value("${twitter_consumer_key:}") + @Value("${twitter_consumer_key:12345678}") private String twitter_consumer_key; - @Value("${twitter_consumer_secret:}") + @Value("${twitter_consumer_secret:secret}") private String twitter_consumer_secret; @Override diff --git a/juick-server/src/main/java/com/juick/server/TelegramBotManager.java b/juick-server/src/main/java/com/juick/server/TelegramBotManager.java index 5743a15e..0d765b71 100644 --- a/juick-server/src/main/java/com/juick/server/TelegramBotManager.java +++ b/juick-server/src/main/java/com/juick/server/TelegramBotManager.java @@ -70,7 +70,7 @@ public class TelegramBotManager implements ApplicationListener { private TelegramBot bot; - @Value("${telegram_token}") + @Value("${telegram_token:12345678}") private String telegramToken; @Inject private TelegramService telegramService; diff --git a/juick-server/src/main/java/com/juick/server/XMPPBot.java b/juick-server/src/main/java/com/juick/server/XMPPBot.java index 46a83777..1c17a0aa 100644 --- a/juick-server/src/main/java/com/juick/server/XMPPBot.java +++ b/juick-server/src/main/java/com/juick/server/XMPPBot.java @@ -60,7 +60,7 @@ public class XMPPBot implements StanzaListener, AutoCloseable { private XMPPServer xmpp; @Inject private XMPPConnection router; - @Value("${xmppbot_jid}") + @Value("${xmppbot_jid:juick@localhost}") private Jid jid; private PrettyTime pt; diff --git a/juick-server/src/main/java/com/juick/server/XMPPServer.java b/juick-server/src/main/java/com/juick/server/XMPPServer.java index 7562d265..358860f7 100644 --- a/juick-server/src/main/java/com/juick/server/XMPPServer.java +++ b/juick-server/src/main/java/com/juick/server/XMPPServer.java @@ -63,7 +63,7 @@ public class XMPPServer implements ConnectionListener, AutoCloseable { @Inject public ExecutorService service; - @Value("${hostname}") + @Value("${hostname:localhost}") private Jid jid; @Value("${s2s_port:5269}") private int s2sPort; diff --git a/juick-server/src/main/java/com/juick/server/configuration/ApiAppConfiguration.java b/juick-server/src/main/java/com/juick/server/configuration/ApiAppConfiguration.java index db9dab17..146e277c 100644 --- a/juick-server/src/main/java/com/juick/server/configuration/ApiAppConfiguration.java +++ b/juick-server/src/main/java/com/juick/server/configuration/ApiAppConfiguration.java @@ -68,7 +68,7 @@ import java.util.concurrent.Executors; @EnableSwagger2 @EnableScheduling @EnableWebSocket -@PropertySource("classpath:juick.conf") +@PropertySource(value = "classpath:juick.conf", ignoreResourceNotFound = true) @ComponentScan(basePackages = "com.juick.server") public class ApiAppConfiguration extends BaseWebConfiguration implements WebSocketConfigurer { @Inject @@ -132,7 +132,7 @@ public class ApiAppConfiguration extends BaseWebConfiguration implements WebSock container.setMaxBinaryMessageBufferSize(8192); return container; } - @Value("${hostname}") + @Value("${hostname:localhost}") private String hostname; @Bean diff --git a/juick-server/src/main/java/com/juick/server/configuration/ApiInitializer.java b/juick-server/src/main/java/com/juick/server/configuration/ApiInitializer.java index b25edd9a..b789fc50 100644 --- a/juick-server/src/main/java/com/juick/server/configuration/ApiInitializer.java +++ b/juick-server/src/main/java/com/juick/server/configuration/ApiInitializer.java @@ -18,8 +18,6 @@ package com.juick.server.configuration; import com.juick.configuration.DataConfiguration; -import com.juick.server.configuration.JuickServerWebsocketConfiguration; -import com.juick.server.configuration.StorageConfiguration; import org.apache.commons.codec.CharEncoding; import org.springframework.web.filter.CharacterEncodingFilter; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; @@ -35,6 +33,7 @@ public class ApiInitializer extends AbstractAnnotationConfigDispatcherServletIni @Override protected Class[] getRootConfigClasses() { return new Class[]{ + ApiAppConfiguration.class, ApiSecurityConfig.class, DataConfiguration.class, StorageConfiguration.class diff --git a/juick-server/src/main/java/com/juick/server/configuration/ApiSecurityConfig.java b/juick-server/src/main/java/com/juick/server/configuration/ApiSecurityConfig.java index ed79c5f1..58fd4231 100644 --- a/juick-server/src/main/java/com/juick/server/configuration/ApiSecurityConfig.java +++ b/juick-server/src/main/java/com/juick/server/configuration/ApiSecurityConfig.java @@ -48,8 +48,6 @@ import java.util.concurrent.TimeUnit; */ @Configuration @EnableWebSecurity -@PropertySource("classpath:juick.conf") -@Import(ApiAppConfiguration.class) public class ApiSecurityConfig extends WebSecurityConfigurerAdapter { @Value("${auth_remember_me_key}") private String rememberMeKey; diff --git a/juick-server/src/test/java/com/juick/server/tests/MessagesTests.java b/juick-server/src/test/java/com/juick/server/tests/MessagesTests.java deleted file mode 100644 index b9bed8f1..00000000 --- a/juick-server/src/test/java/com/juick/server/tests/MessagesTests.java +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (C) 2008-2017, 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 - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package com.juick.server.tests; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.juick.ExternalToken; -import com.juick.Message; -import com.juick.Tag; -import com.juick.User; -import com.juick.configuration.RepositoryConfiguration; -import com.juick.server.EmailManager; -import com.juick.server.configuration.ApiAppConfiguration; -import com.juick.server.configuration.ApiSecurityConfig; -import com.juick.server.helpers.TagStats; -import com.juick.service.ImagesService; -import com.juick.service.MessagesService; -import com.juick.service.TagService; -import com.juick.service.UserService; -import com.juick.util.DateFormattersHolder; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.http.MediaType; -import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.MvcResult; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.util.UriComponents; -import org.springframework.web.util.UriComponentsBuilder; - -import javax.inject.Inject; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Scanner; -import java.util.stream.IntStream; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -/** - * Created by vitalyster on 25.11.2016. - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = {ApiAppConfiguration.class, ApiSecurityConfig.class, RepositoryConfiguration.class}) -@WebAppConfiguration -public class MessagesTests extends AbstractJUnit4SpringContextTests { - - private MockMvc mockMvc; - @Inject - private WebApplicationContext webApplicationContext; - - @Inject - private MessagesService messagesService; - @Inject - private UserService userService; - @Inject - private TagService tagService; - @Inject - private ObjectMapper jsonMapper; - @Inject - private ImagesService imagesService; - - private static User ugnich, freefd, juick; - static String ugnichName, ugnichPassword, freefdName, freefdPassword, juickName, juickPassword; - static Message msg; - static int juickTagId; - - private static boolean isSetUp = false; - - - @Before - public void setUp() { - mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) - .apply(SecurityMockMvcConfigurers.springSecurity()) - .dispatchOptions(true) - .build(); - if (!isSetUp) { - ugnichName = "ugnich"; - ugnichPassword = "MyPassw0rd!"; - freefdName = "freefd"; - freefdPassword = "MyPassw0rd!"; - juickName = "juick"; - juickPassword = "demo"; - int ugnichId = userService.createUser(ugnichName, ugnichPassword); - ugnich = userService.getUserByUID(ugnichId).orElseThrow(IllegalStateException::new); - int freefdId = userService.createUser(freefdName, freefdPassword); - freefd = userService.getUserByUID(freefdId).orElseThrow(IllegalStateException::new); - int juickId = userService.createUser(juickName, juickPassword); - juick = userService.getUserByUID(juickId).orElseThrow(IllegalStateException::new); - - String msgText = "Привет, я - Угнич"; - - int mid = messagesService.createMessage(ugnich.getUid(), msgText, "png", null); - msg = messagesService.getMessage(mid); - tagService.createTag("тест"); - juickTagId = tagService.createTag("juick"); - isSetUp = true; - } - } - - @Test - public void testAllUnAuthorized() throws Exception { - - mockMvc.perform(get("/")) - .andExpect(status().isMovedPermanently()); - - mockMvc.perform(get("/auth")) - .andExpect(status().is4xxClientError()); - - mockMvc.perform(get("/home")) - .andExpect(status().is4xxClientError()); - - mockMvc.perform(get("/messages/recommended")) - .andExpect(status().is4xxClientError()); - - mockMvc.perform(get("/messages/set_privacy")) - .andExpect(status().is4xxClientError()); - } - - @Test - public void homeTestWithMessages() throws Exception { - mockMvc.perform( - get("/home") - .with(httpBasic(ugnichName, ugnichPassword))) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) - .andExpect(jsonPath("$[-1].mid", is(msg.getMid()))) - .andExpect(jsonPath("$[-1].timestamp", - is(DateFormattersHolder.getMessageFormatterInstance().format(msg.getTimestamp())))) - .andExpect(jsonPath("$[-1].body", is(msg.getText()))) - .andExpect(jsonPath("$[-1].attachment.url", is("https://i.juick.com/p/1.png"))) - .andExpect(jsonPath("$[-1].attachment.small.url", is("https://i.juick.com/photos-512/1.png"))); - } - - @Test - public void homeTestWithMessagesAndRememberMe() throws Exception { - String ugnichHash = userService.getHashByUID(ugnich.getUid()); - mockMvc.perform( - get("/home") - .with(httpBasic(ugnichName, ugnichPassword))) - .andExpect(status().isOk()) - .andReturn(); - - mockMvc.perform(get("/home") - .param("hash", ugnichHash)) - .andExpect(status().isOk()); - } - - @Test - public void homeTestWithMessagesAndSimpleCors() throws Exception { - mockMvc.perform( - get("/home") - .with(httpBasic(ugnichName, ugnichPassword)) - .header("Origin", "http://api.example.net")) - .andExpect(status().isOk()) - .andExpect(header().string("Access-Control-Allow-Origin", "*")); - } - - @Test - public void homeTestWithPreflightCors() throws Exception { - mockMvc.perform( - options("/home") - .with(httpBasic(ugnichName, ugnichPassword)) - .header("Origin", "http://api.example.net") - .header("Access-Control-Request-Method", "POST") - .header("Access-Control-Request-Headers", "X-PINGOTHER, Content-Type")) - .andExpect(status().isOk()) - .andExpect(header().string("Access-Control-Allow-Origin", "*")) - .andExpect(header().string("Access-Control-Allow-Methods", "POST,GET,PUT,OPTIONS,DELETE")) - .andExpect(header().string("Access-Control-Allow-Headers", "X-PINGOTHER, Content-Type")); - } - - @Test - public void anonymousApis() throws Exception { - - - mockMvc.perform(get("/messages")) - .andExpect(status().isOk()); - - mockMvc.perform(get("/users") - .param("uname", "ugnich") - .param("uname", "freefd")) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) - .andExpect(jsonPath("$", hasSize(2))); - } - - @Test - public void tags() throws Exception { - Tag weather = tagService.getTag("weather", true); - Tag yo = tagService.getTag("yo", true); - messagesService.createMessage(ugnich.getUid(), "text", null, Arrays.asList(yo, weather)); - messagesService.createMessage(freefd.getUid(), "text2", null, Collections.singletonList(yo)); - MvcResult result = mockMvc.perform(get("/tags")) - .andExpect(status().isOk()) - .andReturn(); - List tagsFromApi = jsonMapper.readValue(result.getResponse().getContentAsString(), - new TypeReference>(){}); - TagStats yoStats = tagsFromApi.stream().filter(t -> t.getTag().getName().equals("yo")).findFirst().get(); - assertThat(yoStats.getUsageCount(), is(2)); - MvcResult result2 = mockMvc.perform(get("/tags") - .param("user_id", String.valueOf(ugnich.getUid()))) - .andExpect(status().isOk()) - .andReturn(); - List ugnichTagsFromApi = jsonMapper.readValue(result2.getResponse().getContentAsString(), - new TypeReference>(){}); - TagStats yoUgnichStats = ugnichTagsFromApi.stream().filter(t -> t.getTag().getName().equals("yo")).findFirst().get(); - assertThat(yoUgnichStats.getUsageCount(), is(1)); - } - - @Test - public void postWithReferer() throws Exception { - mockMvc.perform(post("/post") - .param("body", "yo") - .with(httpBasic(ugnichName, ugnichPassword))) - .andExpect(status().isOk()); - } - @Test - public void threadWithEphemeralNumberShouldReturn404() throws Exception { - mockMvc.perform(get("/thread").param("mid", "999999999") - .with(httpBasic(ugnichName, ugnichPassword))).andExpect(status().is4xxClientError()); - } - @Test - public void performRequestsWithIssuedToken() throws Exception { - String ugnichHash = userService.getHashByUID(ugnich.getUid()); - mockMvc.perform(get("/home")).andExpect(status().isUnauthorized()); - mockMvc.perform(get("/auth")) - .andExpect(status().isUnauthorized()); - mockMvc.perform(get("/auth").with(httpBasic(ugnichName, "wrongpassword"))) - .andExpect(status().isUnauthorized()); - MvcResult result = mockMvc.perform(get("/auth").with(httpBasic(ugnichName, ugnichPassword))) - .andExpect(status().isOk()) - .andReturn(); - String authHash = jsonMapper.readValue(result.getResponse().getContentAsString(), String.class); - assertThat(authHash, equalTo(ugnichHash)); - mockMvc.perform(get("/home").param("hash", ugnichHash)).andExpect(status().isOk()); - } - @Test - public void registerForNotificationsTests() throws Exception { - String token = "123456"; - ExternalToken registration = new ExternalToken(null, "apns", token, null); - mockMvc.perform(put("/notifications").with(httpBasic(ugnichName, ugnichPassword)) - .contentType(MediaType.APPLICATION_JSON_UTF8) - .content(jsonMapper.writeValueAsBytes(Collections.singletonList(registration)))) - .andExpect(status().isOk()); - MvcResult result = mockMvc.perform(get("/notifications") - .param("uid", String.valueOf(ugnich.getUid())) - .with(httpBasic(juickName, juickPassword))) - .andExpect(status().isOk()) - .andReturn(); - List user = jsonMapper.readValue(result.getResponse().getContentAsString(), - new TypeReference>() { - }); - assertThat(user.get(0).getTokens().get(0).getToken(), equalTo(token)); - } - @Test - public void tg2juickLinks() { - UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://juick.com/123456#23").build(); - assertThat(uriComponents.getPath().substring(1), is("123456")); - assertThat(uriComponents.getFragment(), is("23")); - } - @Test - public void notificationsTokensTest() throws Exception { - List tokens = Collections.singletonList(new ExternalToken(null, "gcm", "123456", null)); - mockMvc.perform(delete("/notifications").with(httpBasic(ugnichName, ugnichPassword)) - .contentType(MediaType.APPLICATION_JSON_UTF8) - .content(jsonMapper.writeValueAsBytes(tokens))).andExpect(status().isForbidden()); - mockMvc.perform(delete("/notifications").with(httpBasic(juickName, juickPassword)) - .contentType(MediaType.APPLICATION_JSON_UTF8) - .content(jsonMapper.writeValueAsBytes(tokens))).andExpect(status().isOk()); - } - @Test - public void notificationsSettingsAllowedOnlyForServiceUser() throws Exception { - mockMvc.perform(get("/notifications").with(httpBasic(juickName, juickPassword)) - .param("mid", "1").param("uid", String.valueOf(ugnich.getUid()))).andExpect(status().isOk()); - mockMvc.perform(get("/notifications") - .param("mid", "1").param("uid", String.valueOf(ugnich.getUid()))).andExpect(status().isUnauthorized()); - } - @Test - public void topTest() throws Exception { - int topmid = messagesService.createMessage(ugnich.getUid(), "top message", null, null); - IntStream.rangeClosed(6, 12).forEach(i -> { - messagesService.createReply(topmid, 0, i, "yo", null); - }); - - assertThat(messagesService.getPopularCandidates().get(0), is(topmid)); - Tag juickTag = tagService.getTag(juickTagId); - assertThat(juickTag.TID, is(2)); - tagService.updateTags(topmid, Collections.singletonList(juickTag)); - assertThat(messagesService.getPopularCandidates().isEmpty(), is(true)); - } - @Test - public void inReplyToScannerTest() { - String header = "<123456.56@juick.com>"; - Scanner headerScanner = new Scanner(header).useDelimiter(EmailManager.MSGID_PATTERN); - int mid = Integer.parseInt(headerScanner.next()); - int rid = Integer.parseInt(headerScanner.next()); - assertThat(mid, equalTo(123456)); - assertThat(rid, equalTo(56)); - } -} diff --git a/juick-server/src/test/java/com/juick/server/tests/RSSTests.java b/juick-server/src/test/java/com/juick/server/tests/RSSTests.java deleted file mode 100644 index 6a19123b..00000000 --- a/juick-server/src/test/java/com/juick/server/tests/RSSTests.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2008-2017, 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 - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package com.juick.server.tests; - -import com.juick.Message; -import com.juick.Tag; -import com.juick.User; -import com.juick.configuration.RepositoryConfiguration; -import com.juick.server.configuration.ApiAppConfiguration; -import com.juick.server.configuration.ApiSecurityConfig; -import com.juick.service.*; -import org.apache.commons.text.RandomStringGenerator; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.Primary; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.context.WebApplicationContext; - -import javax.inject.Inject; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static org.mockito.Mockito.when; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -/** - * Created by vitalyster on 13.12.2016. - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = {ApiAppConfiguration.class, ApiSecurityConfig.class, RepositoryConfiguration.class}) -@WebAppConfiguration -public class RSSTests { - - private MockMvc mockMvc; - @Inject - private WebApplicationContext webApplicationContext; - - @Inject - private MessagesService messagesService; - @Inject - private UserService userService; - @Inject - private TagService tagService; - - private User ugnich, freefd; - String ugnichName, ugnichPassword, freefdName, freefdPassword; - - final static RandomStringGenerator generator = new RandomStringGenerator.Builder().withinRange('a', 'z').build(); - - private static Message getMessage(final User user, final String messageText) { - Message msg = new Message(); - - msg.setMid(1); - msg.setUser(user); - msg.setText(messageText == null ? generator.generate(24) : messageText); - msg.setTags(Collections.singletonList(new Tag(generator.generate(4)))); - - return msg; - } - - private static User getUser(final int uid, final String name, final String password) { - User user = new User(); - - user.setName(name); - user.setUid(uid); - user.setCredentials(password); - user.setBanned(false); - - return user; - } - - @Before - public void setUp() { - mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) - .dispatchOptions(true) - .build(); - ugnichName = "ugnich"; - ugnichPassword = "MyPassw0rd!"; - freefdName = "freefd"; - freefdPassword = "MyPassw0rd!"; - - ugnich = getUser(1, ugnichName, ugnichPassword); - freefd = getUser(2, freefdName, freefdPassword); - - List users = new ArrayList<>(2); - users.add(ugnichName); - users.add(freefdName); - - when(userService.getUsersByName(users)) - .thenReturn(Arrays.asList(ugnich, freefd)); - when(userService.getUserByName(ugnichName)) - .thenReturn(ugnich); - when(userService.getFullyUserByName(ugnichName)) - .thenReturn(ugnich); - when(userService.getUserByName(null)) - .thenReturn(new User()); - } - - @Test - public void lastMessagesTest() throws Exception { - String msgText = "Привет, я - Угнич"; - - Message msg = getMessage(ugnich, msgText); - - when(messagesService.getMyFeed(1, 0, false)) - .thenReturn(Collections.singletonList(1)); - when(messagesService.getMessages(Collections.singletonList(1))) - .thenReturn(Collections.singletonList(msg)); - - mockMvc.perform( - get("/rss/")) - .andExpect(status().isOk()) - .andExpect(content().contentType("application/rss+xml")) - .andExpect(xpath("/rss/channel/description").string("The latest messages at Juick")); - } -} diff --git a/juick-server/src/test/java/com/juick/server/tests/ServerTests.java b/juick-server/src/test/java/com/juick/server/tests/ServerTests.java new file mode 100644 index 00000000..b1848986 --- /dev/null +++ b/juick-server/src/test/java/com/juick/server/tests/ServerTests.java @@ -0,0 +1,471 @@ +/* + * Copyright (C) 2008-2017, 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 + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.juick.server.tests; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.juick.ExternalToken; +import com.juick.Message; +import com.juick.Tag; +import com.juick.User; +import com.juick.configuration.RepositoryConfiguration; +import com.juick.server.EmailManager; +import com.juick.server.XMPPBot; +import com.juick.server.XMPPServer; +import com.juick.server.configuration.ApiAppConfiguration; +import com.juick.server.configuration.ApiSecurityConfig; +import com.juick.server.helpers.TagStats; +import com.juick.service.*; +import com.juick.util.DateFormattersHolder; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.MediaType; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.util.UriComponents; +import org.springframework.web.util.UriComponentsBuilder; +import rocks.xmpp.addr.Jid; +import rocks.xmpp.core.stanza.model.Stanza; +import rocks.xmpp.core.stanza.model.server.ServerMessage; + +import javax.inject.Inject; +import java.lang.reflect.InvocationTargetException; +import java.text.ParseException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Scanner; +import java.util.stream.IntStream; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +/** + * Created by vitalyster on 25.11.2016. + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = {ApiAppConfiguration.class, ApiSecurityConfig.class, RepositoryConfiguration.class}) +@TestPropertySource(properties = {"broken_ssl_hosts=localhost,serverstorageisfull.tld"}) +@WebAppConfiguration +public class ServerTests extends AbstractJUnit4SpringContextTests { + + private MockMvc mockMvc; + @Inject + private WebApplicationContext webApplicationContext; + + @Inject + private MessagesService messagesService; + @Inject + private UserService userService; + @Inject + private TagService tagService; + @Inject + private ObjectMapper jsonMapper; + @Inject + private ImagesService imagesService; + @Inject + private WebApplicationContext wac; + @Inject + private XMPPServer server; + @Inject + private XMPPBot bot; + @Inject + private SubscriptionService subscriptionService; + @Inject + private JdbcTemplate jdbcTemplate; + @Value("${hostname:localhost}") + private Jid jid; + + private static User ugnich, freefd, juick; + static String ugnichName, ugnichPassword, freefdName, freefdPassword, juickName, juickPassword; + static Message msg; + static int juickTagId; + + private static boolean isSetUp = false; + + + @Before + public void setUp() { + mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) + .apply(SecurityMockMvcConfigurers.springSecurity()) + .dispatchOptions(true) + .build(); + if (!isSetUp) { + ugnichName = "ugnich"; + ugnichPassword = "MyPassw0rd!"; + freefdName = "freefd"; + freefdPassword = "MyPassw0rd!"; + juickName = "juick"; + juickPassword = "demo"; + int ugnichId = userService.createUser(ugnichName, ugnichPassword); + ugnich = userService.getUserByUID(ugnichId).orElseThrow(IllegalStateException::new); + int freefdId = userService.createUser(freefdName, freefdPassword); + freefd = userService.getUserByUID(freefdId).orElseThrow(IllegalStateException::new); + int juickId = userService.createUser(juickName, juickPassword); + juick = userService.getUserByUID(juickId).orElseThrow(IllegalStateException::new); + + String msgText = "Привет, я - Угнич"; + + int mid = messagesService.createMessage(ugnich.getUid(), msgText, "png", null); + msg = messagesService.getMessage(mid); + tagService.createTag("тест"); + juickTagId = tagService.createTag("juick"); + isSetUp = true; + } + } + + @Test + public void testAllUnAuthorized() throws Exception { + + mockMvc.perform(get("/")) + .andExpect(status().isMovedPermanently()); + + mockMvc.perform(get("/auth")) + .andExpect(status().is4xxClientError()); + + mockMvc.perform(get("/home")) + .andExpect(status().is4xxClientError()); + + mockMvc.perform(get("/messages/recommended")) + .andExpect(status().is4xxClientError()); + + mockMvc.perform(get("/messages/set_privacy")) + .andExpect(status().is4xxClientError()); + } + + @Test + public void homeTestWithMessages() throws Exception { + mockMvc.perform( + get("/home") + .with(httpBasic(ugnichName, ugnichPassword))) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) + .andExpect(jsonPath("$[-1].mid", is(msg.getMid()))) + .andExpect(jsonPath("$[-1].timestamp", + is(DateFormattersHolder.getMessageFormatterInstance().format(msg.getTimestamp())))) + .andExpect(jsonPath("$[-1].body", is(msg.getText()))) + .andExpect(jsonPath("$[-1].attachment.url", is("https://i.juick.com/p/1.png"))) + .andExpect(jsonPath("$[-1].attachment.small.url", is("https://i.juick.com/photos-512/1.png"))); + } + + @Test + public void homeTestWithMessagesAndRememberMe() throws Exception { + String ugnichHash = userService.getHashByUID(ugnich.getUid()); + mockMvc.perform( + get("/home") + .with(httpBasic(ugnichName, ugnichPassword))) + .andExpect(status().isOk()) + .andReturn(); + + mockMvc.perform(get("/home") + .param("hash", ugnichHash)) + .andExpect(status().isOk()); + } + + @Test + public void homeTestWithMessagesAndSimpleCors() throws Exception { + mockMvc.perform( + get("/home") + .with(httpBasic(ugnichName, ugnichPassword)) + .header("Origin", "http://api.example.net")) + .andExpect(status().isOk()) + .andExpect(header().string("Access-Control-Allow-Origin", "*")); + } + + @Test + public void homeTestWithPreflightCors() throws Exception { + mockMvc.perform( + options("/home") + .with(httpBasic(ugnichName, ugnichPassword)) + .header("Origin", "http://api.example.net") + .header("Access-Control-Request-Method", "POST") + .header("Access-Control-Request-Headers", "X-PINGOTHER, Content-Type")) + .andExpect(status().isOk()) + .andExpect(header().string("Access-Control-Allow-Origin", "*")) + .andExpect(header().string("Access-Control-Allow-Methods", "POST,GET,PUT,OPTIONS,DELETE")) + .andExpect(header().string("Access-Control-Allow-Headers", "X-PINGOTHER, Content-Type")); + } + + @Test + public void anonymousApis() throws Exception { + + + mockMvc.perform(get("/messages")) + .andExpect(status().isOk()); + + mockMvc.perform(get("/users") + .param("uname", "ugnich") + .param("uname", "freefd")) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) + .andExpect(jsonPath("$", hasSize(2))); + } + + @Test + public void tags() throws Exception { + Tag weather = tagService.getTag("weather", true); + Tag yo = tagService.getTag("yo", true); + messagesService.createMessage(ugnich.getUid(), "text", null, Arrays.asList(yo, weather)); + messagesService.createMessage(freefd.getUid(), "text2", null, Collections.singletonList(yo)); + MvcResult result = mockMvc.perform(get("/tags")) + .andExpect(status().isOk()) + .andReturn(); + List tagsFromApi = jsonMapper.readValue(result.getResponse().getContentAsString(), + new TypeReference>(){}); + TagStats yoStats = tagsFromApi.stream().filter(t -> t.getTag().getName().equals("yo")).findFirst().get(); + assertThat(yoStats.getUsageCount(), is(2)); + MvcResult result2 = mockMvc.perform(get("/tags") + .param("user_id", String.valueOf(ugnich.getUid()))) + .andExpect(status().isOk()) + .andReturn(); + List ugnichTagsFromApi = jsonMapper.readValue(result2.getResponse().getContentAsString(), + new TypeReference>(){}); + TagStats yoUgnichStats = ugnichTagsFromApi.stream().filter(t -> t.getTag().getName().equals("yo")).findFirst().get(); + assertThat(yoUgnichStats.getUsageCount(), is(1)); + } + + @Test + public void postWithReferer() throws Exception { + mockMvc.perform(post("/post") + .param("body", "yo") + .with(httpBasic(ugnichName, ugnichPassword))) + .andExpect(status().isOk()); + } + @Test + public void threadWithEphemeralNumberShouldReturn404() throws Exception { + mockMvc.perform(get("/thread").param("mid", "999999999") + .with(httpBasic(ugnichName, ugnichPassword))).andExpect(status().is4xxClientError()); + } + @Test + public void performRequestsWithIssuedToken() throws Exception { + String ugnichHash = userService.getHashByUID(ugnich.getUid()); + mockMvc.perform(get("/home")).andExpect(status().isUnauthorized()); + mockMvc.perform(get("/auth")) + .andExpect(status().isUnauthorized()); + mockMvc.perform(get("/auth").with(httpBasic(ugnichName, "wrongpassword"))) + .andExpect(status().isUnauthorized()); + MvcResult result = mockMvc.perform(get("/auth").with(httpBasic(ugnichName, ugnichPassword))) + .andExpect(status().isOk()) + .andReturn(); + String authHash = jsonMapper.readValue(result.getResponse().getContentAsString(), String.class); + assertThat(authHash, equalTo(ugnichHash)); + mockMvc.perform(get("/home").param("hash", ugnichHash)).andExpect(status().isOk()); + } + @Test + public void registerForNotificationsTests() throws Exception { + String token = "123456"; + ExternalToken registration = new ExternalToken(null, "apns", token, null); + mockMvc.perform(put("/notifications").with(httpBasic(ugnichName, ugnichPassword)) + .contentType(MediaType.APPLICATION_JSON_UTF8) + .content(jsonMapper.writeValueAsBytes(Collections.singletonList(registration)))) + .andExpect(status().isOk()); + MvcResult result = mockMvc.perform(get("/notifications") + .param("uid", String.valueOf(ugnich.getUid())) + .with(httpBasic(juickName, juickPassword))) + .andExpect(status().isOk()) + .andReturn(); + List user = jsonMapper.readValue(result.getResponse().getContentAsString(), + new TypeReference>() { + }); + assertThat(user.get(0).getTokens().get(0).getToken(), equalTo(token)); + } + @Test + public void tg2juickLinks() { + UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://juick.com/123456#23").build(); + assertThat(uriComponents.getPath().substring(1), is("123456")); + assertThat(uriComponents.getFragment(), is("23")); + } + @Test + public void notificationsTokensTest() throws Exception { + List tokens = Collections.singletonList(new ExternalToken(null, "gcm", "123456", null)); + mockMvc.perform(delete("/notifications").with(httpBasic(ugnichName, ugnichPassword)) + .contentType(MediaType.APPLICATION_JSON_UTF8) + .content(jsonMapper.writeValueAsBytes(tokens))).andExpect(status().isForbidden()); + mockMvc.perform(delete("/notifications").with(httpBasic(juickName, juickPassword)) + .contentType(MediaType.APPLICATION_JSON_UTF8) + .content(jsonMapper.writeValueAsBytes(tokens))).andExpect(status().isOk()); + } + @Test + public void notificationsSettingsAllowedOnlyForServiceUser() throws Exception { + mockMvc.perform(get("/notifications").with(httpBasic(juickName, juickPassword)) + .param("mid", "1").param("uid", String.valueOf(ugnich.getUid()))).andExpect(status().isOk()); + mockMvc.perform(get("/notifications") + .param("mid", "1").param("uid", String.valueOf(ugnich.getUid()))).andExpect(status().isUnauthorized()); + } + @Test + public void topTest() throws Exception { + int topmid = messagesService.createMessage(ugnich.getUid(), "top message", null, null); + IntStream.rangeClosed(6, 12).forEach(i -> { + messagesService.createReply(topmid, 0, i, "yo", null); + }); + + assertThat(messagesService.getPopularCandidates().get(0), is(topmid)); + Tag juickTag = tagService.getTag(juickTagId); + assertThat(juickTag.TID, is(2)); + tagService.updateTags(topmid, Collections.singletonList(juickTag)); + assertThat(messagesService.getPopularCandidates().isEmpty(), is(true)); + } + @Test + public void inReplyToScannerTest() { + String header = "<123456.56@juick.com>"; + Scanner headerScanner = new Scanner(header).useDelimiter(EmailManager.MSGID_PATTERN); + int mid = Integer.parseInt(headerScanner.next()); + int rid = Integer.parseInt(headerScanner.next()); + assertThat(mid, equalTo(123456)); + assertThat(rid, equalTo(56)); + } + @Test + public void lastMessagesTest() throws Exception { + mockMvc.perform( + get("/rss/")) + .andExpect(status().isOk()) + .andExpect(content().contentType("application/rss+xml")) + .andExpect(xpath("/rss/channel/description").string("The latest messages at Juick")); + } + @Test + public void statusPageIsUp() throws Exception { + mockMvc.perform(get("http://localhost:8080/status").with(httpBasic(ugnichName, ugnichPassword))).andExpect(status().isOk()); + assertThat(server.getJid(), equalTo(jid)); + } + @Test + public void botIsUpAndProcessingResourceConstraints() { + int renhaId; + 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); + String xmlMessage = "Reply by @LexXПохоже нынче можно публично заявлять о своем веганстве. Your contact offline message queue is full. The message has been discarded."; + Stanza msg = server.parse(xmlMessage); + assertThat(from, equalTo(msg.getFrom())); + boolean isActive = jdbcTemplate.queryForObject("SELECT active FROM jids WHERE user_id=?", Integer.class, renhaId) == 1; + assertThat(isActive, equalTo(true)); + bot.incomingMessage((ServerMessage)msg); + isActive = jdbcTemplate.queryForObject("SELECT active FROM jids WHERE user_id=?", Integer.class, renhaId) == 1; + assertThat(isActive, equalTo(false)); + } + @Test + public void botCommandsTests() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { + assertThat(bot.processCommand(new User(), Jid.of("test@localhost"), "PING").get(), is("PONG")); + // subscription commands have two lines, others have 1 + assertThat(bot.processCommand(new User(), Jid.of("test@localhost"), "help").get().split("\n").length, is(23)); + } + + @Test + public void protocolTests() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, ParseException, JsonProcessingException { + int uid = userService.createUser("me", "secret"); + User user = userService.getUserByUID(uid).orElse(new User()); + Tag yo = tagService.getTag("yo", true); + int mid = messagesService.createMessage(uid, "yoyo", null, Collections.singletonList(yo)); + assertEquals("should be message", true, + bot.processCommand(user, Jid.of("test@localhost"), String.format("#%d", mid)).get().startsWith("@me")); + mid = messagesService.getUserBlog(user.getUid(), -1, 0).stream().reduce((first, second) -> second).get(); + assertEquals("text should match", "yoyo", + messagesService.getMessage(mid).getText()); + assertEquals("tag should match", "yo", + tagService.getMessageTags(mid).get(0).getTag().getName()); + int readerUid = userService.createUser("dummyReader", "dummySecret"); + User readerUser = userService.getUserByUID(readerUid).orElse(new User()); + assertEquals("should be subscribed", "Subscribed", + bot.processCommand(readerUser, Jid.of("dummy@localhost"), "S #" + mid).get()); + /* TODO: move from juick-legacy + assertEquals("should be favorited", "Message added to your recommendations", + juickProtocol.getReply(readerUser, "! #" + mid)); + */ + assertEquals("number of subscribed users should match", 1, + subscriptionService.getUsersSubscribedToComments(mid, uid).size()); + /* + assertEquals("should be subscribed", "Subscribed", + bot.processCommand(readerUser, Jid.of("dummy@localhost"), "S @" + user.getName()).get()); + List friends = userService.getUserFriends(readerUid); + assertEquals("number of friend users should match", 2, + friends.size()); + assertEquals("number of reader users should match", 1, + userService.getUserReaders(uid).size()); + String expectedReply = "Reply posted.\n#" + mid + "/1 " + + "http://juick.com/" + mid + "#1"; + String expectedSecondReply = "Reply posted.\n#" + mid + "/2 " + + "http://juick.com/" + mid + "#2"; + assertEquals("should be reply", expectedReply, + bot.processCommand(user, Jid.of("test@localhost"), "#" + mid + " yoyo").get()); + assertEquals("should be second reply", expectedSecondReply, + bot.processCommand(user, Jid.of("test@localhost"), "#" + mid + "/1 yoyo").get()); + Message reply = messagesService.getReplies(mid).stream().filter(m -> m.getRid() == 2).findFirst() + .orElse(new Message()); + assertEquals("should be reply to first comment", 1, reply.getReplyto()); + assertNotEquals("tags should NOT be updated", "Tags are updated", + bot.processCommand(readerUser, Jid.of("dummy@localhost"), "#" + mid + " *yo *there").get()); + assertEquals("tags should be updated", "Tags are updated", + bot.processCommand(user, Jid.of("test@localhost"), "#" + mid + " *there").get()); + assertEquals("number of tags should match", 2, + tagService.getMessageTags(mid).size()); + assertEquals("should be blacklisted", "Tag added to your blacklist", + bot.processCommand(readerUser, Jid.of("dummy@localhost"), "BL *there").get()); + assertEquals("number of subscribed users should match", 0, + subscriptionService.getSubscribedUsers(uid, mid).size()); + assertEquals("tags should be updated", "Tags are updated", + bot.processCommand(user, Jid.of("test@localhost"), "#" + mid + " *there").get()); + assertEquals("number of tags should match", 1, + tagService.getMessageTags(mid).size()); + int taggerUid = userService.createUser("dummyTagger", "dummySecret"); + User taggerUser = userService.getUserByUID(taggerUid).orElse(new User()); + assertEquals("should be subscribed", "Subscribed", + bot.processCommand(taggerUser, Jid.of("tagger@localhost"), "S *yo").get()); + assertEquals("number of subscribed users should match", 2, + subscriptionService.getSubscribedUsers(uid, mid).size()); + assertEquals("should be unsubscribed", "Unsubscribed from yo", + bot.processCommand(taggerUser, Jid.of("tagger@localhost"), "U *yo").get()); + assertEquals("number of subscribed users should match", 1, + subscriptionService.getSubscribedUsers(uid, mid).size()); + assertEquals("number of readers should match", 1, + userService.getUserReaders(uid).size()); + String readerFeed = bot.processCommand(readerUser, Jid.of("dummy@localhost"), "#").get(); + assertEquals("description should match", true, readerFeed.startsWith("Your feed")); + assertEquals("should be unsubscribed", "Unsubscribed from @" + user.getName(), + bot.processCommand(readerUser, Jid.of("dummy@localhost"), "U @" + user.getName()).get()); + assertEquals("number of readers should match", 0, + userService.getUserReaders(uid).size()); + assertEquals("number of friends should match", 1, + userService.getUserFriends(uid).size()); + assertEquals("should be unsubscribed", "Unsubscribed from #" + mid, + bot.processCommand(readerUser, Jid.of("dummy@localhost"), "u #" + mid).get()); + assertEquals("number of subscribed users should match", 0, + subscriptionService.getUsersSubscribedToComments(mid, uid).size()); + assertNotEquals("should NOT be deleted", String.format("Message %s deleted", mid), + bot.processCommand(readerUser, Jid.of("dummy@localhost"), "D #" + mid).get()); + assertEquals("should be deleted", String.format("Message %s deleted", mid), + bot.processCommand(user, Jid.of("test@localhost"), "D #" + mid).get()); + assertEquals("should not have messages", 0, messagesService.getAll(user.getUid(), 0).size()); + */ + } +} diff --git a/juick-server/src/test/java/com/juick/server/tests/XMPPServerTests.java b/juick-server/src/test/java/com/juick/server/tests/XMPPServerTests.java deleted file mode 100644 index 5a3c8e69..00000000 --- a/juick-server/src/test/java/com/juick/server/tests/XMPPServerTests.java +++ /dev/null @@ -1,190 +0,0 @@ -package com.juick.server.tests; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.juick.Tag; -import com.juick.User; -import com.juick.configuration.RepositoryConfiguration; -import com.juick.server.XMPPBot; -import com.juick.server.XMPPServer; -import com.juick.server.configuration.ApiAppConfiguration; -import com.juick.server.configuration.ApiSecurityConfig; -import com.juick.service.MessagesService; -import com.juick.service.SubscriptionService; -import com.juick.service.TagService; -import com.juick.service.UserService; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.context.WebApplicationContext; -import rocks.xmpp.addr.Jid; -import rocks.xmpp.core.stanza.model.Stanza; -import rocks.xmpp.core.stanza.model.server.ServerMessage; - -import javax.inject.Inject; -import java.lang.reflect.InvocationTargetException; -import java.text.ParseException; -import java.util.Collections; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertEquals; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -@RunWith(SpringJUnit4ClassRunner.class) -@WebAppConfiguration -@ContextConfiguration(classes = { - ApiAppConfiguration.class, ApiSecurityConfig.class, RepositoryConfiguration.class -}) -@TestPropertySource(properties = {"broken_ssl_hosts=localhost,serverstorageisfull.tld"}) -public class XMPPServerTests extends AbstractJUnit4SpringContextTests { - @Inject - private WebApplicationContext wac; - @Inject - private XMPPServer server; - @Inject - private XMPPBot bot; - @Inject - private UserService userService; - @Inject - private MessagesService messagesService; - @Inject - private TagService tagService; - @Inject - private SubscriptionService subscriptionService; - @Inject - private JdbcTemplate jdbcTemplate; - @Value("${hostname}") - private Jid jid; - - private MockMvc mockMvc; - - @Before - public void setup() { - mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); - } - @Test - public void statusPageIsUp() throws Exception { - mockMvc.perform(get("http://localhost:8080/status")).andExpect(status().isOk()); - assertThat(server.getJid(), equalTo(jid)); - } - @Test - public void botIsUpAndProcessingResourceConstraints() { - int renhaId; - 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); - String xmlMessage = "Reply by @LexXПохоже нынче можно публично заявлять о своем веганстве. Your contact offline message queue is full. The message has been discarded."; - Stanza msg = server.parse(xmlMessage); - assertThat(from, equalTo(msg.getFrom())); - boolean isActive = jdbcTemplate.queryForObject("SELECT active FROM jids WHERE user_id=?", Integer.class, renhaId) == 1; - assertThat(isActive, equalTo(true)); - bot.incomingMessage((ServerMessage)msg); - isActive = jdbcTemplate.queryForObject("SELECT active FROM jids WHERE user_id=?", Integer.class, renhaId) == 1; - assertThat(isActive, equalTo(false)); - } - @Test - public void botCommandsTests() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { - assertThat(bot.processCommand(new User(), Jid.of("test@localhost"), "PING").get(), is("PONG")); - // subscription commands have two lines, others have 1 - assertThat(bot.processCommand(new User(), Jid.of("test@localhost"), "help").get().split("\n").length, is(23)); - } - - @Test - public void protocolTests() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, ParseException, JsonProcessingException { - int uid = userService.createUser("me", "secret"); - User user = userService.getUserByUID(uid).orElse(new User()); - Tag yo = tagService.getTag("yo", true); - int mid = messagesService.createMessage(uid, "yoyo", null, Collections.singletonList(yo)); - assertEquals("should be message", true, - bot.processCommand(user, Jid.of("test@localhost"), String.format("#%d", mid)).get().startsWith("@me")); - mid = messagesService.getUserBlog(user.getUid(), -1, 0).stream().reduce((first, second) -> second).get(); - assertEquals("text should match", "yoyo", - messagesService.getMessage(mid).getText()); - assertEquals("tag should match", "yo", - tagService.getMessageTags(mid).get(0).getTag().getName()); - int readerUid = userService.createUser("dummyReader", "dummySecret"); - User readerUser = userService.getUserByUID(readerUid).orElse(new User()); - assertEquals("should be subscribed", "Subscribed", - bot.processCommand(readerUser, Jid.of("dummy@localhost"), "S #" + mid).get()); - /* TODO: move from juick-legacy - assertEquals("should be favorited", "Message added to your recommendations", - juickProtocol.getReply(readerUser, "! #" + mid)); - */ - assertEquals("number of subscribed users should match", 1, - subscriptionService.getUsersSubscribedToComments(mid, uid).size()); - /* - assertEquals("should be subscribed", "Subscribed", - bot.processCommand(readerUser, Jid.of("dummy@localhost"), "S @" + user.getName()).get()); - List friends = userService.getUserFriends(readerUid); - assertEquals("number of friend users should match", 2, - friends.size()); - assertEquals("number of reader users should match", 1, - userService.getUserReaders(uid).size()); - String expectedReply = "Reply posted.\n#" + mid + "/1 " - + "http://juick.com/" + mid + "#1"; - String expectedSecondReply = "Reply posted.\n#" + mid + "/2 " - + "http://juick.com/" + mid + "#2"; - assertEquals("should be reply", expectedReply, - bot.processCommand(user, Jid.of("test@localhost"), "#" + mid + " yoyo").get()); - assertEquals("should be second reply", expectedSecondReply, - bot.processCommand(user, Jid.of("test@localhost"), "#" + mid + "/1 yoyo").get()); - Message reply = messagesService.getReplies(mid).stream().filter(m -> m.getRid() == 2).findFirst() - .orElse(new Message()); - assertEquals("should be reply to first comment", 1, reply.getReplyto()); - assertNotEquals("tags should NOT be updated", "Tags are updated", - bot.processCommand(readerUser, Jid.of("dummy@localhost"), "#" + mid + " *yo *there").get()); - assertEquals("tags should be updated", "Tags are updated", - bot.processCommand(user, Jid.of("test@localhost"), "#" + mid + " *there").get()); - assertEquals("number of tags should match", 2, - tagService.getMessageTags(mid).size()); - assertEquals("should be blacklisted", "Tag added to your blacklist", - bot.processCommand(readerUser, Jid.of("dummy@localhost"), "BL *there").get()); - assertEquals("number of subscribed users should match", 0, - subscriptionService.getSubscribedUsers(uid, mid).size()); - assertEquals("tags should be updated", "Tags are updated", - bot.processCommand(user, Jid.of("test@localhost"), "#" + mid + " *there").get()); - assertEquals("number of tags should match", 1, - tagService.getMessageTags(mid).size()); - int taggerUid = userService.createUser("dummyTagger", "dummySecret"); - User taggerUser = userService.getUserByUID(taggerUid).orElse(new User()); - assertEquals("should be subscribed", "Subscribed", - bot.processCommand(taggerUser, Jid.of("tagger@localhost"), "S *yo").get()); - assertEquals("number of subscribed users should match", 2, - subscriptionService.getSubscribedUsers(uid, mid).size()); - assertEquals("should be unsubscribed", "Unsubscribed from yo", - bot.processCommand(taggerUser, Jid.of("tagger@localhost"), "U *yo").get()); - assertEquals("number of subscribed users should match", 1, - subscriptionService.getSubscribedUsers(uid, mid).size()); - assertEquals("number of readers should match", 1, - userService.getUserReaders(uid).size()); - String readerFeed = bot.processCommand(readerUser, Jid.of("dummy@localhost"), "#").get(); - assertEquals("description should match", true, readerFeed.startsWith("Your feed")); - assertEquals("should be unsubscribed", "Unsubscribed from @" + user.getName(), - bot.processCommand(readerUser, Jid.of("dummy@localhost"), "U @" + user.getName()).get()); - assertEquals("number of readers should match", 0, - userService.getUserReaders(uid).size()); - assertEquals("number of friends should match", 1, - userService.getUserFriends(uid).size()); - assertEquals("should be unsubscribed", "Unsubscribed from #" + mid, - bot.processCommand(readerUser, Jid.of("dummy@localhost"), "u #" + mid).get()); - assertEquals("number of subscribed users should match", 0, - subscriptionService.getUsersSubscribedToComments(mid, uid).size()); - assertNotEquals("should NOT be deleted", String.format("Message %s deleted", mid), - bot.processCommand(readerUser, Jid.of("dummy@localhost"), "D #" + mid).get()); - assertEquals("should be deleted", String.format("Message %s deleted", mid), - bot.processCommand(user, Jid.of("test@localhost"), "D #" + mid).get()); - assertEquals("should not have messages", 0, messagesService.getAll(user.getUid(), 0).size()); - */ - } -} -- cgit v1.2.3