package com.juick.tests; import ch.vorburger.exec.ManagedProcessException; import ch.vorburger.mariadb4j.DB; import com.fasterxml.jackson.core.JsonProcessingException; import com.juick.Message; import com.juick.Tag; import com.juick.User; import com.juick.server.helpers.TagStats; import com.juick.server.protocol.JuickProtocol; import com.juick.server.protocol.ProtocolListener; import com.juick.server.protocol.ProtocolReply; import com.juick.service.MessagesService; import com.juick.service.SubscriptionService; import com.juick.service.TagService; import com.juick.service.UserService; import com.juick.service.search.SearchService; import com.juick.www.controllers.PageTemplates; import org.apache.commons.dbcp2.BasicDataSource; import org.apache.commons.lang3.StringEscapeUtils; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.TransactionManagementConfigurer; import javax.inject.Inject; import java.lang.reflect.InvocationTargetException; import java.text.ParseException; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; /** * Created by vt on 14.01.2016. */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration public class ApiTests { @Configuration @ComponentScan(basePackages = {"com.juick.service", "com.juick.server.protocol"}) static class Config implements TransactionManagementConfigurer { @Bean public BasicDataSource dataSource() { try { DB db = DB.newEmbeddedDB(33306); db.start(); db.createDB("juick"); db.source("schema.sql"); BasicDataSource dataSource = new BasicDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:33306/juick?autoReconnect=true&user=root"); dataSource.setValidationQuery("select 1"); return dataSource; } catch (ManagedProcessException e) { return null; } } @Bean public PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } @Override public PlatformTransactionManager annotationDrivenTransactionManager() { return transactionManager(); } @Bean @DependsOn("dataSource") public JdbcTemplate jdbcTemplate() { return new JdbcTemplate(dataSource()); } @Bean public SearchService emptySearchService() { return new SearchService() { @Override public void setMaxResult(int maxResult) { } @Override public List searchInAllMessages(String searchString, int messageIdBefore) { return Collections.emptyList(); } @Override public List searchByStringAndUser(String searchString, int userId, int messageIdBefore) { return Collections.emptyList(); } }; } @Bean public JuickProtocol juickProtocol() { return new JuickProtocol("http://localhost:8080/"); } } @Inject UserService userService; @Inject MessagesService messagesService; @Inject TagService tagService; @Inject SubscriptionService subscriptionService; @Inject JdbcTemplate jdbcTemplate; @Inject JuickProtocol juickProtocol; @Mock ProtocolListener listener; @Before public void setup() { userService.createUser("ugnich", "secret"); userService.createUser("juick", "secret"); MockitoAnnotations.initMocks(this); } @Test public void messageTests() { int user_id = userService.createUser("mmmme", "secret"); User user = userService.getUserByUID(user_id).orElse(new User()); assertEquals("it should be me", "mmmme", user.getName()); int mid = messagesService.createMessage(user_id, "yo", null, new ArrayList<>()); Message msg = messagesService.getMessage(mid); assertEquals("yo", msg.getText()); Calendar calendar = Calendar.getInstance(); calendar.setTime(msg.getDate()); assertEquals(2016, calendar.get(Calendar.YEAR)); User me = msg.getUser(); assertEquals("mmmme", me.getName()); assertEquals("mmmme", messagesService.getMessageAuthor(mid).getName()); int tagID = tagService.createTag("weather"); Tag tag = tagService.getTag(tagID); List tagList = new ArrayList<>(); tagList.add(tag); int mid2 = messagesService.createMessage(user_id, "yo2", null, tagList); Message msg2 = messagesService.getMessage(mid2); assertEquals(1, msg2.getTags().size()); assertEquals("we already have ugnich", -1, userService.createUser("ugnich", "x")); int ugnich_id = userService.createUser("hugnich", "x"); User ugnich = userService.getUserByUID(ugnich_id).orElse(new User()); int rid = messagesService.createReply(msg2.getMid(), 0, ugnich.getUid(), "bla-bla", null); assertEquals(1, rid); Message msg3 = messagesService.getMessage(mid2); assertEquals(1, msg3.getReplies()); assertEquals("weather", msg3.getTags().get(0).getName()); assertEquals(ugnich.getUid(), userService.checkPassword(ugnich.getName(), "x")); assertEquals(-1, userService.checkPassword(ugnich.getName(), "xy")); subscriptionService.subscribeMessage(msg.getMid(), ugnich.getUid()); assertEquals(1, subscriptionService.getUsersSubscribedToComments(msg.getMid(), user.getUid()).size()); messagesService.deleteMessage(user_id, mid); messagesService.deleteMessage(user_id, mid2); String htmlTagName = ">_<"; Tag htmlTag = tagService.getTag(htmlTagName, true); TagStats htmlTagStats = new TagStats(); htmlTagStats.setTag(htmlTag); String dbTagName = jdbcTemplate.queryForObject("select name from tags where name=?", String.class, StringEscapeUtils.escapeHtml4(htmlTagName)); assertNotEquals("db tags should be escaped", dbTagName, htmlTag.getName()); assertEquals("object tags should unescaped", htmlTag.getName(), StringEscapeUtils.unescapeHtml4(dbTagName)); assertEquals("template should encode escaped tag in url and show escaped tag in name", ">_<", PageTemplates.formatTags(Collections.singletonList(htmlTagStats))); } @Test public void protocolTests() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, ParseException, JsonProcessingException { juickProtocol.setListener(listener); assertEquals("juick user should have uid 2", 2, userService.getUIDbyName("juick")); int uid = userService.createUser("me", "secret"); User user = userService.getUserByUID(uid).orElse(new User()); String expectedMessage = "New message posted"; assertEquals("should be message", true, juickProtocol.getReply(user, "*yo yoyo").getResult().startsWith(expectedMessage)); int 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()); assertNotEquals("should not be error", "Error", juickProtocol.getReply(user, "#" + mid).getResult()); assertEquals("should be PONG", "PONG", juickProtocol.getReply(user, " ping \n ").getResult()); int readerUid = userService.createUser("dummyReader", "dummySecret"); User readerUser = userService.getUserByUID(readerUid).orElse(new User()); assertEquals("should be subscribed", "Subscribed", juickProtocol.getReply(readerUser, "S #" + mid).getResult()); assertEquals("number of subscribed users should match", 1, subscriptionService.getUsersSubscribedToComments(mid, uid).size()); assertEquals("should be subscribed", "Subscribed", juickProtocol.getReply(readerUser, "S @" + user.getName()).getResult()); 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 " + juickProtocol.getBaseUri() + mid + "/1"; String expectedSecondReply = "Reply posted.\n#" + mid + "/2 " + juickProtocol.getBaseUri() + mid + "/2"; assertEquals("should be reply", expectedReply, juickProtocol.getReply(user, "#" + mid + " yoyo").getResult()); assertEquals("should be second reply", expectedSecondReply, juickProtocol.getReply(user, "#" + mid + "/1 yoyo").getResult()); 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", juickProtocol.getReply(readerUser, "#" + mid + " *yo *there").getResult()); assertEquals("tags should be updated", "Tags are updated", juickProtocol.getReply(user, "#" + mid + " *there").getResult()); assertEquals("number of tags should match", 2, tagService.getMessageTags(mid).size()); assertEquals("should be blacklisted", "Tag added to your blacklist", juickProtocol.getReply(readerUser, "BL *there").getResult()); assertEquals("number of subscribed users should match", 0, subscriptionService.getSubscribedUsers(uid, mid).size()); assertEquals("tags should be updated", "Tags are updated", juickProtocol.getReply(user, "#" + mid + " *there").getResult()); 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", juickProtocol.getReply(taggerUser, "S *yo").getResult()); assertEquals("number of subscribed users should match", 2, subscriptionService.getSubscribedUsers(uid, mid).size()); assertEquals("should be unsubscribed", "Unsubscribed from yo", juickProtocol.getReply(taggerUser, "U *yo").getResult()); assertEquals("number of subscribed users should match", 1, subscriptionService.getSubscribedUsers(uid, mid).size()); assertEquals("number of readers should match", 1, userService.getUserReaders(uid).size()); ProtocolReply readerFeed = juickProtocol.getReply(readerUser, "#"); assertEquals("description should match", true, readerFeed.getResult().startsWith("Your feed")); assertEquals("should be unsubscribed", "Unsubscribed from @" + user.getName(), juickProtocol.getReply(readerUser, "U @" + user.getName()).getResult()); 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, juickProtocol.getReply(readerUser, "u #" + mid).getResult()); assertEquals("number of subscribed users should match", 0, subscriptionService.getUsersSubscribedToComments(mid, uid).size()); assertNotEquals("should NOT be deleted", String.format("Message %s deleted", mid), juickProtocol.getReply(readerUser, "D #" + mid).getResult()); assertEquals("should be deleted", String.format("Message %s deleted", mid), juickProtocol.getReply(user, "D #" + mid).getResult()); assertEquals("should not have messages", 0, messagesService.getAll(user.getUid(), 0).size()); } }