From 7ed3795da542bab397ee7ed8978bde896abf5cf4 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Tue, 6 Feb 2018 17:54:49 +0300 Subject: server: merge api and ws --- .../java/com/juick/api/tests/MessagesTests.java | 319 +++++++++++++++++++++ 1 file changed, 319 insertions(+) create mode 100644 juick-server/src/test/java/com/juick/api/tests/MessagesTests.java (limited to 'juick-server/src/test/java/com') diff --git a/juick-server/src/test/java/com/juick/api/tests/MessagesTests.java b/juick-server/src/test/java/com/juick/api/tests/MessagesTests.java new file mode 100644 index 00000000..fff7e02c --- /dev/null +++ b/juick-server/src/test/java/com/juick/api/tests/MessagesTests.java @@ -0,0 +1,319 @@ +/* + * 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.api.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.api.EmailManager; +import com.juick.api.configuration.ApiAppConfiguration; +import com.juick.api.configuration.ApiSecurityConfig; +import com.juick.configuration.RepositoryConfiguration; +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().is4xxClientError()); + + 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 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)); + } +} -- cgit v1.2.3