mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-13 19:29:06 +01:00
briar-headless: Add more controller tests
Current controller line coverage: 100%
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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) }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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() }
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user