/*
* 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.juick.Message;
import com.juick.Tag;
import com.juick.User;
import com.juick.api.ApiServer;
import com.juick.api.TGBot;
import com.juick.server.configuration.BaseWebConfiguration;
import com.juick.api.configuration.ApiSecurityConfig;
import com.juick.api.configuration.MessengerConfiguration;
import com.juick.configuration.MockDataConfiguration;
import com.juick.server.helpers.TagStats;
import com.juick.service.MessagesService;
import com.juick.service.TagService;
import com.juick.service.UserService;
import com.juick.test.util.MockUtils;
import com.juick.util.DateFormattersHolder;
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.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
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.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 org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.socket.client.WebSocketConnectionManager;
import javax.inject.Inject;
import java.time.Instant;
import java.util.*;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
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
@WebAppConfiguration
public class MessagesTests {
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.juick.api.controllers")
@Import(value = {BaseWebConfiguration.class, ApiSecurityConfig.class,
MockDataConfiguration.class, MessengerConfiguration.class})
static class Config {
@Bean
WebSocketConnectionManager connectionManager() {
return Mockito.mock(WebSocketConnectionManager.class);
}
@Bean
TGBot tgBot() {
return Mockito.mock(TGBot.class);
}
@Bean
ApiServer apiServer() {
return Mockito.mock(ApiServer.class);
}
}
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;
@Before
public void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.apply(SecurityMockMvcConfigurers.springSecurity())
.dispatchOptions(true)
.build();
ugnichName = "ugnich";
ugnichPassword = "MyPassw0rd!";
freefdName = "freefd";
freefdPassword = "MyPassw0rd!";
ugnich = MockUtils.mockUser(1, ugnichName, ugnichPassword);
freefd = MockUtils.mockUser(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 testAllUnAuthorized() throws Exception {
mockMvc.perform(get("/"))
.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 {
String msgText = "Привет, я - Угнич";
Message msg = MockUtils.mockMessage(1, ugnich, msgText);
Instant now = Instant.now();
msg.setTimestamp(now);
when(messagesService.getMyFeed(1, 0, true))
.thenReturn(Collections.singletonList(1));
when(messagesService.getMessages(Collections.singletonList(1)))
.thenReturn(Collections.singletonList(msg));
mockMvc.perform(
get("/home")
.with(httpBasic(ugnichName, ugnichPassword)))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$", hasSize(1)))
.andExpect(jsonPath("$[0].mid", is(1)))
.andExpect(jsonPath("$[0].timestamp", is(DateFormattersHolder.getMessageFormatterInstance().format(now))))
.andExpect(jsonPath("$[0].body", is(msgText)));
}
@Test
public void homeTestWithMessagesAndRememberMe() throws Exception {
String msgText = "Привет, я - Угнич";
String hash = "12345678";
User user = MockUtils.mockUser(1, ugnichName, ugnichPassword);
Message msg = MockUtils.mockMessage(1, user, msgText);
when(userService.getUIDbyName(ugnichName))
.thenReturn(1);
when(userService.getUserByName(ugnichName))
.thenReturn(user);
when(userService.getUserByUID(1))
.thenReturn(Optional.of(user));
when(userService.getFullyUserByName(ugnichName))
.thenReturn(user);
when(messagesService.getMyFeed(1, 0, true))
.thenReturn(Collections.singletonList(1));
when(messagesService.getMessages(Collections.singletonList(1)))
.thenReturn(Collections.singletonList(msg));
when(userService.getUIDbyHash(hash))
.thenReturn(1);
mockMvc.perform(
get("/home")
.with(httpBasic(ugnichName, ugnichPassword)))
.andExpect(status().isOk())
.andReturn();
when(userService.getUserByHash(hash))
.thenReturn(user);
mockMvc.perform(get("/home")
.param("hash", hash))
.andExpect(status().isOk());
}
@Test
public void homeTestWithMessagesAndSimpleCors() throws Exception {
User user = MockUtils.mockUser(1, ugnichName, ugnichPassword);
Message msg = MockUtils.mockMessage(1, user, null);
when(userService.getFullyUserByName(ugnichName))
.thenReturn(user);
when(userService.getUserByName(ugnichName))
.thenReturn(user);
when(messagesService.getMyFeed(1, 0, false))
.thenReturn(Collections.singletonList(1));
when(messagesService.getMessages(Collections.singletonList(1)))
.thenReturn(Collections.singletonList(msg));
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 {
User user = MockUtils.mockUser(1, ugnichName, ugnichPassword);
when(userService.getFullyUserByName(ugnichName))
.thenReturn(user);
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 = new Tag("weather");
TagStats sw = new TagStats();
sw.setTag(weather);
sw.setUsageCount(15);
Tag yo = new Tag("yo");
TagStats sy = new TagStats();
sy.setTag(yo);
sy.setUsageCount(5);
when(tagService.getUserTagStats(1)).thenReturn(Collections.singletonList(sy));
when(tagService.getTagStats()).thenReturn(Arrays.asList(sy, sw));
mockMvc.perform(get("/tags"))
.andExpect(status().isOk())
.andExpect(jsonPath("$", hasSize(2)));
mockMvc.perform(get("/tags")
.param("user_id", "1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$", hasSize(1)))
.andExpect(jsonPath("$[0].messages", is(5)));
}
@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());
}
}