mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-14 19:59:05 +01:00
briar-headless: Add more controller tests
Current controller line coverage: 100%
This commit is contained in:
@@ -4,6 +4,8 @@ import io.javalin.BadRequestResponse
|
||||
import io.javalin.Context
|
||||
import org.briarproject.bramble.api.identity.IdentityManager
|
||||
import org.briarproject.bramble.api.system.Clock
|
||||
import org.briarproject.bramble.util.StringUtils
|
||||
import org.briarproject.briar.api.blog.BlogConstants.MAX_BLOG_POST_BODY_LENGTH
|
||||
import org.briarproject.briar.api.blog.BlogManager
|
||||
import org.briarproject.briar.api.blog.BlogPostFactory
|
||||
import javax.annotation.concurrent.Immutable
|
||||
@@ -33,7 +35,9 @@ constructor(
|
||||
fun createPost(ctx: Context): Context {
|
||||
val text = ctx.formParam("text")
|
||||
if (text == null || text.isEmpty())
|
||||
throw BadRequestResponse("Expecting Blog text")
|
||||
throw BadRequestResponse("Expecting blog post text")
|
||||
if (StringUtils.toUtf8(text).size > MAX_BLOG_POST_BODY_LENGTH)
|
||||
throw BadRequestResponse("Too long blog post text")
|
||||
|
||||
val author = identityManager.localAuthor
|
||||
val blog = blogManager.getPersonalBlog(author)
|
||||
|
||||
@@ -2,6 +2,8 @@ package org.briarproject.briar.headless.forums
|
||||
|
||||
import io.javalin.BadRequestResponse
|
||||
import io.javalin.Context
|
||||
import org.briarproject.bramble.util.StringUtils
|
||||
import org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_NAME_LENGTH
|
||||
import org.briarproject.briar.api.forum.ForumManager
|
||||
import javax.annotation.concurrent.Immutable
|
||||
import javax.inject.Inject
|
||||
@@ -18,8 +20,10 @@ constructor(private val forumManager: ForumManager) {
|
||||
|
||||
fun create(ctx: Context): Context {
|
||||
val name = ctx.formParam("name")
|
||||
if (name == null || name.isEmpty())
|
||||
if (name == null || name.isNullOrEmpty())
|
||||
throw BadRequestResponse("Expecting Forum Name")
|
||||
if (StringUtils.toUtf8(name).size > MAX_FORUM_NAME_LENGTH)
|
||||
throw BadRequestResponse("Forum name is too long")
|
||||
return ctx.json(forumManager.addForum(name).output())
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import org.briarproject.briar.api.forum.Forum
|
||||
import javax.annotation.concurrent.Immutable
|
||||
|
||||
@Immutable
|
||||
internal class OutputForum(
|
||||
internal data class OutputForum(
|
||||
val name: String,
|
||||
val id: ByteArray
|
||||
) {
|
||||
|
||||
@@ -14,10 +14,10 @@ import org.briarproject.briar.api.sharing.InvitationResponse
|
||||
internal fun PrivateMessageHeader.output(
|
||||
contactId: ContactId,
|
||||
body: String?
|
||||
) = OutputPrivateMessage(this, contactId, body)
|
||||
) = OutputPrivateMessageHeader(this, contactId, body)
|
||||
|
||||
internal fun PrivateMessage.output(contactId: ContactId, body: String) =
|
||||
OutputPrivateMessage(this, contactId, body)
|
||||
OutputPrivateMessageHeader(this, contactId, body)
|
||||
|
||||
internal fun PrivateMessageReceivedEvent<*>.output(body: String) =
|
||||
messageHeader.output(contactId, body)
|
||||
|
||||
@@ -20,7 +20,7 @@ import javax.annotation.concurrent.Immutable
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
private const val EVENT_PRIVATE_MESSAGE =
|
||||
internal const val EVENT_PRIVATE_MESSAGE =
|
||||
"org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent"
|
||||
|
||||
@Immutable
|
||||
@@ -79,7 +79,11 @@ constructor(
|
||||
|
||||
private fun getContact(ctx: Context): Contact {
|
||||
val contactString = ctx.pathParam("contactId")
|
||||
val contactInt = Integer.parseInt(contactString)
|
||||
val contactInt = try {
|
||||
Integer.parseInt(contactString)
|
||||
} catch (e: NumberFormatException) {
|
||||
throw NotFoundResponse()
|
||||
}
|
||||
val contactId = ContactId(contactInt)
|
||||
return try {
|
||||
contactManager.getContact(contactId)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
@file:Suppress("MemberVisibilityCanBePrivate", "unused")
|
||||
|
||||
package org.briarproject.briar.headless.messaging
|
||||
|
||||
import org.briarproject.bramble.api.contact.ContactId
|
||||
@@ -8,47 +6,45 @@ import org.briarproject.briar.api.messaging.PrivateMessageHeader
|
||||
import javax.annotation.concurrent.Immutable
|
||||
|
||||
@Immutable
|
||||
internal open class OutputPrivateMessage(
|
||||
val body: String?,
|
||||
val timestamp: Long,
|
||||
val read: Boolean,
|
||||
val seen: Boolean,
|
||||
val sent: Boolean,
|
||||
val local: Boolean,
|
||||
val id: ByteArray,
|
||||
val groupId: ByteArray,
|
||||
val contactId: Int
|
||||
internal abstract class OutputPrivateMessage(
|
||||
protected open val iHeader: PrivateMessageHeader,
|
||||
protected open val iContactId: ContactId,
|
||||
open val body: String?
|
||||
) {
|
||||
open val type = "org.briarproject.briar.api.messaging.PrivateMessageHeader"
|
||||
|
||||
internal constructor(
|
||||
header: PrivateMessageHeader,
|
||||
contactId: ContactId,
|
||||
body: String?
|
||||
) : this(
|
||||
body = body,
|
||||
timestamp = header.timestamp,
|
||||
read = header.isRead,
|
||||
seen = header.isSeen,
|
||||
sent = header.isSent,
|
||||
local = header.isLocal,
|
||||
id = header.id.bytes,
|
||||
groupId = header.groupId.bytes,
|
||||
contactId = contactId.int
|
||||
)
|
||||
open val type: String get() = throw NotImplementedError()
|
||||
val contactId: Int get() = iContactId.int
|
||||
val timestamp: Long get() = iHeader.timestamp
|
||||
val read: Boolean get() = iHeader.isRead
|
||||
val seen: Boolean get() = iHeader.isSeen
|
||||
val sent: Boolean get() = iHeader.isSent
|
||||
val local: Boolean get() = iHeader.isLocal
|
||||
val id: ByteArray get() = iHeader.id.bytes
|
||||
val groupId: ByteArray get() = iHeader.groupId.bytes
|
||||
|
||||
}
|
||||
|
||||
@Immutable
|
||||
internal data class OutputPrivateMessageHeader(
|
||||
override val iHeader: PrivateMessageHeader,
|
||||
override val iContactId: ContactId,
|
||||
override val body: String?
|
||||
) : OutputPrivateMessage(iHeader, iContactId, body) {
|
||||
|
||||
override val type = "org.briarproject.briar.api.messaging.PrivateMessageHeader"
|
||||
|
||||
/**
|
||||
* Only meant for own [PrivateMessage]s directly after creation.
|
||||
*/
|
||||
internal constructor(m: PrivateMessage, contactId: ContactId, body: String) : this(
|
||||
body = body,
|
||||
timestamp = m.message.timestamp,
|
||||
read = true,
|
||||
seen = true,
|
||||
sent = true,
|
||||
local = true,
|
||||
id = m.message.id.bytes,
|
||||
groupId = m.message.groupId.bytes,
|
||||
contactId = contactId.int
|
||||
PrivateMessageHeader(
|
||||
m.message.id,
|
||||
m.message.groupId,
|
||||
m.message.timestamp,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
), contactId, body
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@file:Suppress("MemberVisibilityCanBePrivate", "unused")
|
||||
@file:Suppress("unused")
|
||||
|
||||
package org.briarproject.briar.headless.messaging
|
||||
|
||||
@@ -21,22 +21,28 @@ internal abstract class OutputPrivateRequest(header: PrivateRequest<*>, contactI
|
||||
}
|
||||
|
||||
@Immutable
|
||||
internal class OutputIntroductionRequest(header: IntroductionRequest, contactId: ContactId) :
|
||||
OutputPrivateRequest(header, contactId) {
|
||||
internal data class OutputIntroductionRequest(
|
||||
override val iHeader: IntroductionRequest,
|
||||
override val iContactId: ContactId
|
||||
) : OutputPrivateRequest(iHeader, iContactId) {
|
||||
|
||||
override val type = "org.briarproject.briar.api.introduction.IntroductionRequest"
|
||||
val alreadyContact = header.isContact
|
||||
val alreadyContact get() = iHeader.isContact
|
||||
|
||||
}
|
||||
|
||||
@Immutable
|
||||
internal class OutputInvitationRequest(header: InvitationRequest<*>, contactId: ContactId) :
|
||||
OutputPrivateRequest(header, contactId) {
|
||||
internal data class OutputInvitationRequest(
|
||||
override val iHeader: InvitationRequest<*>,
|
||||
override val iContactId: ContactId
|
||||
) : OutputPrivateRequest(iHeader, iContactId) {
|
||||
|
||||
override val type = when (header) {
|
||||
override val type = when (iHeader) {
|
||||
is ForumInvitationRequest -> "org.briarproject.briar.api.forum.ForumInvitationRequest"
|
||||
is BlogInvitationRequest -> "org.briarproject.briar.api.blog.BlogInvitationRequest"
|
||||
is GroupInvitationRequest -> "org.briarproject.briar.api.privategroup.invitation.GroupInvitationRequest"
|
||||
else -> throw AssertionError("Unknown InvitationRequest")
|
||||
}
|
||||
val canBeOpened = header.canBeOpened()
|
||||
val canBeOpened get() = iHeader.canBeOpened()
|
||||
|
||||
}
|
||||
|
||||
@@ -21,23 +21,27 @@ internal abstract class OutputPrivateResponse(header: PrivateResponse, contactId
|
||||
}
|
||||
|
||||
@Immutable
|
||||
internal class OutputIntroductionResponse(header: IntroductionResponse, contactId: ContactId) :
|
||||
OutputPrivateResponse(header, contactId) {
|
||||
internal data class OutputIntroductionResponse(
|
||||
override val iHeader: IntroductionResponse,
|
||||
override val iContactId: ContactId
|
||||
) : OutputPrivateResponse(iHeader, iContactId) {
|
||||
|
||||
override val type = "org.briarproject.briar.api.introduction.IntroductionResponse"
|
||||
val introducedAuthor = header.introducedAuthor.output()
|
||||
val introducer = header.isIntroducer
|
||||
val introducedAuthor get() = iHeader.introducedAuthor.output()
|
||||
val introducer get() = iHeader.isIntroducer
|
||||
}
|
||||
|
||||
@Immutable
|
||||
internal class OutputInvitationResponse(header: InvitationResponse, contactId: ContactId) :
|
||||
OutputPrivateResponse(header, contactId) {
|
||||
internal data class OutputInvitationResponse(
|
||||
override val iHeader: InvitationResponse,
|
||||
override val iContactId: ContactId
|
||||
) : OutputPrivateResponse(iHeader, iContactId) {
|
||||
|
||||
override val type = when (header) {
|
||||
override val type = when (iHeader) {
|
||||
is ForumInvitationResponse -> "org.briarproject.briar.api.forum.ForumInvitationResponse"
|
||||
is BlogInvitationResponse -> "org.briarproject.briar.api.blog.BlogInvitationResponse"
|
||||
is GroupInvitationResponse -> "org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse"
|
||||
else -> throw AssertionError("Unknown InvitationResponse")
|
||||
}
|
||||
val shareableId: ByteArray = header.shareableId.bytes
|
||||
val shareableId: ByteArray get() = iHeader.shareableId.bytes
|
||||
}
|
||||
|
||||
@@ -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