briar-headless: Add more controller tests

Current controller line coverage: 100%
This commit is contained in:
Torsten Grote
2018-08-27 17:37:10 -03:00
parent 159fd34c0c
commit 98d1ea7730
17 changed files with 573 additions and 126 deletions

View File

@@ -0,0 +1,44 @@
package org.briarproject.briar.headless
import io.javalin.Context
import io.javalin.core.util.ContextUtil
import io.mockk.mockk
import org.briarproject.bramble.api.contact.Contact
import org.briarproject.bramble.api.contact.ContactId
import org.briarproject.bramble.api.contact.ContactManager
import org.briarproject.bramble.api.identity.Author
import org.briarproject.bramble.api.identity.IdentityManager
import org.briarproject.bramble.api.identity.LocalAuthor
import org.briarproject.bramble.api.sync.Group
import org.briarproject.bramble.api.sync.Message
import org.briarproject.bramble.api.system.Clock
import org.briarproject.bramble.test.TestUtils.*
import org.briarproject.bramble.util.StringUtils.getRandomString
import org.skyscreamer.jsonassert.JSONAssert.assertEquals
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
abstract class ControllerTest {
protected val contactManager = mockk<ContactManager>()
protected val identityManager = mockk<IdentityManager>()
protected val clock = mockk<Clock>()
protected val ctx = mockk<Context>()
private val request = mockk<HttpServletRequest>(relaxed = true)
private val response = mockk<HttpServletResponse>(relaxed = true)
private val outputCtx = ContextUtil.init(request, response)
protected val group: Group = getGroup(getClientId(), 0)
protected val author: Author = getAuthor()
protected val localAuthor: LocalAuthor = getLocalAuthor()
protected val contact = Contact(ContactId(1), author, localAuthor.id, true, true)
protected val message: Message = getMessage(group.id)
protected val body: String = getRandomString(5)
protected val timestamp = 42L
protected fun assertJsonEquals(json: String, obj: Any) {
assertEquals(json, outputCtx.json(obj).resultString(), false)
}
}

View File

@@ -1,63 +1,128 @@
package org.briarproject.briar.headless.blogs
import io.javalin.Context
import io.javalin.BadRequestResponse
import io.javalin.json.JavalinJson.toJson
import io.mockk.Runs
import io.mockk.every
import io.mockk.just
import io.mockk.mockk
import io.mockk.slot
import io.mockk.verifySequence
import org.briarproject.bramble.api.identity.Author.Status.OURSELVES
import org.briarproject.bramble.api.identity.IdentityManager
import org.briarproject.bramble.api.system.Clock
import org.briarproject.bramble.test.TestUtils.*
import org.briarproject.bramble.api.sync.MessageId
import org.briarproject.bramble.util.StringUtils.getRandomString
import org.briarproject.briar.api.blog.Blog
import org.briarproject.briar.api.blog.BlogManager
import org.briarproject.briar.api.blog.BlogPostFactory
import org.briarproject.briar.api.blog.BlogPostHeader
import org.briarproject.briar.api.blog.*
import org.briarproject.briar.api.blog.BlogConstants.MAX_BLOG_POST_BODY_LENGTH
import org.briarproject.briar.api.blog.MessageType.POST
import org.junit.jupiter.api.Assertions.assertEquals
import org.briarproject.briar.headless.ControllerTest
import org.briarproject.briar.headless.output
import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Test
class BlogControllerTest {
internal class BlogControllerTest : ControllerTest() {
private val blogManager = mockk<BlogManager>()
private val blogPostFactory = mockk<BlogPostFactory>()
private val identityManager = mockk<IdentityManager>()
private val clock = mockk<Clock>()
private val ctx = mockk<Context>()
private val blogController =
BlogController(blogManager, blogPostFactory, identityManager, clock)
private val controller =
BlogController(blogManager, blogPostFactory, identityManager, clock)
private val group = getGroup(getClientId(), 0)
private val author = getAuthor()
private val blog = Blog(group, author, false)
private val message = getMessage(group.id)
private val body = getRandomString(5)
private val parentId: MessageId? = null
private val rssFeed = false
private val read = true
private val header = BlogPostHeader(
POST,
group.id,
message.id,
parentId,
message.timestamp,
timestamp,
author,
OURSELVES,
rssFeed,
read
)
@Test
fun testCreate() {
val post = BlogPost(message, null, localAuthor)
every { ctx.formParam("text") } returns body
every { identityManager.localAuthor } returns localAuthor
every { blogManager.getPersonalBlog(localAuthor) } returns blog
every { clock.currentTimeMillis() } returns message.timestamp
every {
blogPostFactory.createBlogPost(
message.groupId,
message.timestamp,
parentId,
localAuthor,
body
)
} returns post
every { blogManager.addLocalPost(post) } just Runs
every { blogManager.getPostHeader(post.message.groupId, post.message.id) } returns header
every { ctx.json(header.output(body)) } returns ctx
controller.createPost(ctx)
}
@Test
fun testCreateNoText() {
every { ctx.formParam("text") } returns null
assertThrows(BadRequestResponse::class.java) { controller.createPost(ctx) }
}
@Test
fun testCreateEmptyText() {
every { ctx.formParam("text") } returns ""
assertThrows(BadRequestResponse::class.java) { controller.createPost(ctx) }
}
@Test
fun testCreateTooLongText() {
every { ctx.formParam("text") } returns getRandomString(MAX_BLOG_POST_BODY_LENGTH + 1)
assertThrows(BadRequestResponse::class.java) { controller.createPost(ctx) }
}
@Test
fun testList() {
val header = BlogPostHeader(POST, group.id, message.id, null, 0, 0, author, OURSELVES, true,
true)
val slot = slot<List<OutputBlogPost>>()
every { blogManager.blogs } returns listOf(blog)
every { blogManager.getPostHeaders(any()) } returns listOf(header)
every { blogManager.getPostBody(any()) } returns body
every { ctx.json(capture(slot)) } returns ctx
every { blogManager.getPostHeaders(group.id) } returns listOf(header)
every { blogManager.getPostBody(message.id) } returns body
every { ctx.json(listOf(header.output(body))) } returns ctx
blogController.listPosts(ctx)
controller.listPosts(ctx)
}
assertEquals(1, slot.captured.size)
assertEquals(header.id.bytes, slot.captured[0].id)
assertEquals(body, slot.captured[0].body)
@Test
fun testEmptyList() {
every { blogManager.blogs } returns listOf(blog)
every { blogManager.getPostHeaders(group.id) } returns emptyList()
every { ctx.json(emptyList<OutputBlogPost>()) } returns ctx
verifySequence {
blogManager.blogs
blogManager.getPostHeaders(group.id)
blogManager.getPostBody(message.id)
ctx.json(slot.captured)
}
controller.listPosts(ctx)
}
@Test
fun testOutputBlogPost() {
val json = """
{
"body": "$body",
"author": ${toJson(author.output())},
"authorStatus": "ourselves",
"type": "post",
"id": ${toJson(header.id.bytes)},
"parentId": $parentId,
"read": $read,
"rssFeed": $rssFeed,
"timestamp": ${message.timestamp},
"timestampReceived": $timestamp
}
"""
assertJsonEquals(json, header.output(body))
}
}

View File

@@ -0,0 +1,52 @@
package org.briarproject.briar.headless.contact
import io.javalin.json.JavalinJson.toJson
import io.mockk.every
import org.briarproject.bramble.api.contact.Contact
import org.briarproject.briar.headless.ControllerTest
import org.briarproject.briar.headless.output
import org.junit.jupiter.api.Test
internal class ContactControllerTest : ControllerTest() {
private val controller = ContactController(contactManager)
@Test
fun testEmptyContactList() {
every { contactManager.activeContacts } returns emptyList<Contact>()
every { ctx.json(emptyList<OutputContact>()) } returns ctx
controller.list(ctx)
}
@Test
fun testList() {
every { contactManager.activeContacts } returns listOf(contact)
every { ctx.json(listOf(contact.output())) } returns ctx
controller.list(ctx)
}
@Test
fun testOutputContact() {
val json = """
{
"id": ${contact.id.int},
"author": ${toJson(author.output())},
"verified": ${contact.isVerified}
}
"""
assertJsonEquals(json, contact.output())
}
@Test
fun testOutputAuthor() {
val json = """
{
"id": ${toJson(author.id.bytes)},
"name": "${author.name}",
"publicKey": ${toJson(author.publicKey)}
}
"""
assertJsonEquals(json, author.output())
}
}

View File

@@ -0,0 +1,61 @@
package org.briarproject.briar.headless.forums
import io.javalin.BadRequestResponse
import io.mockk.every
import io.mockk.mockk
import org.briarproject.bramble.test.TestUtils.getRandomBytes
import org.briarproject.bramble.util.StringUtils.getRandomString
import org.briarproject.briar.api.forum.Forum
import org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_NAME_LENGTH
import org.briarproject.briar.api.forum.ForumManager
import org.briarproject.briar.headless.ControllerTest
import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Test
internal class ForumControllerTest : ControllerTest() {
private val forumManager = mockk<ForumManager>()
private val controller = ForumController(forumManager)
private val forum = Forum(group, getRandomString(5), getRandomBytes(5))
@Test
fun list() {
every { forumManager.forums } returns listOf(forum)
every { ctx.json(listOf(forum.output())) } returns ctx
controller.list(ctx)
}
@Test
fun create() {
every { ctx.formParam("name") } returns forum.name
every { forumManager.addForum(forum.name) } returns forum
every { ctx.json(forum.output()) } returns ctx
controller.create(ctx)
}
@Test
fun createNoName() {
every { ctx.formParam("name") } returns null
assertThrows(BadRequestResponse::class.java) { controller.create(ctx) }
}
@Test
fun createEmptyName() {
every { ctx.formParam("name") } returns ""
assertThrows(BadRequestResponse::class.java) { controller.create(ctx) }
}
@Test
fun createTooLongName() {
every { ctx.formParam("name") } returns getRandomString(MAX_FORUM_NAME_LENGTH + 1)
assertThrows(BadRequestResponse::class.java) { controller.create(ctx) }
}
}

View File

@@ -0,0 +1,180 @@
package org.briarproject.briar.headless.messaging
import io.javalin.BadRequestResponse
import io.javalin.Context
import io.javalin.NotFoundResponse
import io.javalin.json.JavalinJson.toJson
import io.mockk.*
import org.briarproject.bramble.api.contact.ContactId
import org.briarproject.bramble.api.db.NoSuchContactException
import org.briarproject.bramble.test.ImmediateExecutor
import org.briarproject.bramble.util.StringUtils.getRandomString
import org.briarproject.briar.api.messaging.*
import org.briarproject.briar.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH
import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent
import org.briarproject.briar.headless.ControllerTest
import org.briarproject.briar.headless.WebSocketController
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Test
internal class MessagingControllerImplTest : ControllerTest() {
private val messagingManager = mockk<MessagingManager>()
private val conversationManager = mockk<ConversationManager>()
private val privateMessageFactory = mockk<PrivateMessageFactory>()
private val webSocketController = mockk<WebSocketController>()
private val dbExecutor = ImmediateExecutor()
private val controller = MessagingControllerImpl(
messagingManager,
conversationManager,
privateMessageFactory,
contactManager,
webSocketController,
dbExecutor,
clock
)
private val header = PrivateMessageHeader(message.id, group.id, timestamp, true, true, true, true)
private val headers = listOf(header)
@Test
fun list() {
expectGetContact()
every { conversationManager.getMessageHeaders(contact.id) } returns headers
every { messagingManager.getMessageBody(message.id) } returns body
every { ctx.json(listOf(header.output(contact.id, body))) } returns ctx
controller.list(ctx)
}
@Test
fun emptyList() {
every { ctx.pathParam("contactId") } returns contact.id.int.toString()
every { contactManager.getContact(contact.id) } returns contact
every { conversationManager.getMessageHeaders(contact.id) } returns emptyList<PrivateMessageHeader>()
every { ctx.json(emptyList<OutputPrivateMessageHeader>()) } returns ctx
controller.list(ctx)
}
@Test
fun listInvalidContactId() {
testInvalidContactId { controller.list(ctx) }
}
@Test
fun listNonexistentContactId() {
testNonexistentContactId { controller.list(ctx) }
}
@Test
fun write() {
val privateMessage = PrivateMessage(message)
val slot = CapturingSlot<OutputPrivateMessageHeader>()
expectGetContact()
every { ctx.formParam("message") } returns body
every { messagingManager.getContactGroup(contact) } returns group
every { clock.currentTimeMillis() } returns timestamp
every {
privateMessageFactory.createPrivateMessage(
group.id,
timestamp,
body
)
} returns privateMessage
every { messagingManager.addLocalMessage(privateMessage) } just runs
every { ctx.json(capture(slot)) } returns ctx
controller.write(ctx)
val output = slot.captured
assertEquals(contact.id.int, output.contactId)
assertEquals(body, output.body)
assertEquals(message.id.bytes, output.id)
}
@Test
fun writeInvalidContactId() {
testInvalidContactId { controller.write(ctx) }
}
@Test
fun writeNonexistentContactId() {
testNonexistentContactId { controller.write(ctx) }
}
@Test
fun writeNonexistentBody() {
expectGetContact()
every { ctx.formParam("message") } returns null
assertThrows(BadRequestResponse::class.java) { controller.write(ctx) }
}
@Test
fun writeEmptyBody() {
expectGetContact()
every { ctx.formParam("message") } returns ""
assertThrows(BadRequestResponse::class.java) { controller.write(ctx) }
}
@Test
fun writeTooLongBody() {
expectGetContact()
every { ctx.formParam("message") } returns getRandomString(MAX_PRIVATE_MESSAGE_BODY_LENGTH + 1)
assertThrows(BadRequestResponse::class.java) { controller.write(ctx) }
}
@Test
fun privateMessageEvent() {
val event = PrivateMessageReceivedEvent(header, contact.id)
every { messagingManager.getMessageBody(message.id) } returns body
every { webSocketController.sendEvent(EVENT_PRIVATE_MESSAGE, event.output(body)) } just runs
controller.eventOccurred(event)
}
@Test
fun testOutputPrivateMessageHeader() {
val json = """
{
"body": "$body",
"type": "org.briarproject.briar.api.messaging.PrivateMessageHeader",
"timestamp": $timestamp,
"groupId": ${toJson(header.groupId.bytes)},
"contactId": ${contact.id.int},
"local": ${header.isLocal},
"seen": ${header.isSeen},
"read": ${header.isRead},
"sent": ${header.isSent},
"id": ${toJson(header.id.bytes)}
}
"""
assertJsonEquals(json, header.output(contact.id, body))
}
private fun expectGetContact() {
every { ctx.pathParam("contactId") } returns contact.id.int.toString()
every { contactManager.getContact(contact.id) } returns contact
}
private fun testNonexistentContactId(function: () -> Context) {
every { ctx.pathParam("contactId") } returns "42"
every { contactManager.getContact(ContactId(42)) } throws NoSuchContactException()
assertThrows(NotFoundResponse::class.java) { function.invoke() }
}
private fun testInvalidContactId(function: () -> Context) {
every { ctx.pathParam("contactId") } returns "foo"
assertThrows(NotFoundResponse::class.java) { function.invoke() }
}
}