From e9753f1629b868c8a2b9523434462fef54bb7194 Mon Sep 17 00:00:00 2001 From: Sina Madani Date: Wed, 26 Jun 2024 17:57:59 +0100 Subject: [PATCH] feat: Add modify call methods --- src/main/kotlin/com/vonage/client/kt/Voice.kt | 31 +++++++++++++-- .../com/vonage/client/kt/AbstractTest.kt | 36 ++++++++++++++---- .../com/vonage/client/kt/MessagesTest.kt | 5 ++- .../kotlin/com/vonage/client/kt/VerifyTest.kt | 12 +++--- .../kotlin/com/vonage/client/kt/VoiceTest.kt | 38 +++++++++++++++++-- 5 files changed, 101 insertions(+), 21 deletions(-) diff --git a/src/main/kotlin/com/vonage/client/kt/Voice.kt b/src/main/kotlin/com/vonage/client/kt/Voice.kt index 8560944..027b04f 100644 --- a/src/main/kotlin/com/vonage/client/kt/Voice.kt +++ b/src/main/kotlin/com/vonage/client/kt/Voice.kt @@ -1,14 +1,39 @@ package com.vonage.client.kt import com.vonage.client.voice.CallInfo +import com.vonage.client.voice.CallInfoPage +import com.vonage.client.voice.CallsFilter import com.vonage.client.voice.VoiceClient +import com.vonage.client.voice.ncco.Ncco +import java.net.URI import java.util.* class Voice(private val voiceClient: VoiceClient) { - fun getCall(callId: UUID): CallInfo = getCall(callId.toString()) + fun call(callId: String): Call = Call(callId) - fun getCall(callId: String): CallInfo = voiceClient.getCallDetails(callId) + fun call(callId: UUID): Call = call(callId.toString()) - + inner class Call(val callId: String) { + + fun get(): CallInfo = voiceClient.getCallDetails(callId) + + fun hangup() = voiceClient.terminateCall(callId) + + fun mute() = voiceClient.muteCall(callId) + + fun unmute() = voiceClient.unmuteCall(callId) + + fun earmuff() = voiceClient.earmuffCall(callId) + + fun unearmuff() = voiceClient.unearmuffCall(callId) + + fun transfer(ncco: Ncco) = voiceClient.transferCall(callId, ncco) + + fun transfer(nccoUrl: String) = voiceClient.transferCall(callId, nccoUrl) + + fun transfer(nccoUrl: URI) = transfer(nccoUrl.toString()) + } + + fun listCalls(filter: CallsFilter? = null): CallInfoPage = voiceClient.listCalls(filter) } \ No newline at end of file diff --git a/src/test/kotlin/com/vonage/client/kt/AbstractTest.kt b/src/test/kotlin/com/vonage/client/kt/AbstractTest.kt index af05a09..3372450 100644 --- a/src/test/kotlin/com/vonage/client/kt/AbstractTest.kt +++ b/src/test/kotlin/com/vonage/client/kt/AbstractTest.kt @@ -112,17 +112,38 @@ abstract class AbstractTest { else -> throw IllegalArgumentException("Unhandled HTTP method: $httpMethod") }) - protected fun mockJsonJwtPost(expectedUrl: String, - expectedRequestParams: Map? = null, - status: Int = 200, - expectedResponseParams: Map? = null) = + private fun mockP(requestMethod: HttpMethod, expectedUrl: String, + expectedRequestParams: Map? = null, + status: Int = 200, authType: AuthType? = AuthType.JWT, + expectedResponseParams: Map? = null) = - mockRequest(HttpMethod.POST, expectedUrl, + mockRequest(requestMethod, expectedUrl, contentType = if (expectedRequestParams != null) ContentType.APPLICATION_JSON else null, accept = if (expectedResponseParams != null && status < 400) ContentType.APPLICATION_JSON else null, - AuthType.JWT, expectedRequestParams + authType = authType, expectedRequestParams ).mockReturn(status, expectedResponseParams) + protected fun mockPost(expectedUrl: String, + expectedRequestParams: Map? = null, + status: Int = 200, + authType: AuthType? = AuthType.JWT, + expectedResponseParams: Map? = null) = + mockP(HttpMethod.POST, expectedUrl, expectedRequestParams, status, authType, expectedResponseParams) + + protected fun mockPut(expectedUrl: String, + expectedRequestParams: Map? = null, + status: Int = 200, + authType: AuthType? = AuthType.JWT, + expectedResponseParams: Map? = null) = + mockP(HttpMethod.PUT, expectedUrl, expectedRequestParams, status, authType, expectedResponseParams) + + protected fun mockPatch(expectedUrl: String, + expectedRequestParams: Map? = null, + status: Int = 200, + authType: AuthType? = AuthType.JWT, + expectedResponseParams: Map? = null) = + mockP(HttpMethod.PUT, expectedUrl, expectedRequestParams, status, authType, expectedResponseParams) + protected fun mockDelete(expectedUrl: String, authType: AuthType? = null) = mockRequest(HttpMethod.DELETE, expectedUrl, authType = authType).mockReturn(204) @@ -134,8 +155,7 @@ abstract class AbstractTest { mockRequest(HttpMethod.GET, expectedUrl, contentType = if (expectedQueryParams != null) ContentType.FORM_URLENCODED else null, - accept = ContentType.APPLICATION_JSON, - authType = authType, expectedQueryParams + accept = ContentType.APPLICATION_JSON, authType, expectedQueryParams ).mockReturn(status, expectedResponseParams) diff --git a/src/test/kotlin/com/vonage/client/kt/MessagesTest.kt b/src/test/kotlin/com/vonage/client/kt/MessagesTest.kt index c9a3e5c..47f9731 100644 --- a/src/test/kotlin/com/vonage/client/kt/MessagesTest.kt +++ b/src/test/kotlin/com/vonage/client/kt/MessagesTest.kt @@ -34,7 +34,10 @@ class MessagesTest : AbstractTest() { val status = 202 val expectedResponseParams = mapOf("message_uuid" to messageUuid) - mockJsonJwtPost(sendUrl, expectedBodyParams, status, expectedResponseParams) + mockPost( + expectedUrl = sendUrl, expectedRequestParams = expectedBodyParams, + status = status, expectedResponseParams = expectedResponseParams + ) assertEquals(messageUuid, messagesClient.send(req)) // TODO fix mocking full url diff --git a/src/test/kotlin/com/vonage/client/kt/VerifyTest.kt b/src/test/kotlin/com/vonage/client/kt/VerifyTest.kt index 9344e34..0e381be 100644 --- a/src/test/kotlin/com/vonage/client/kt/VerifyTest.kt +++ b/src/test/kotlin/com/vonage/client/kt/VerifyTest.kt @@ -53,7 +53,7 @@ class VerifyTest : AbstractTest() { @Test fun `send verification single workflow required parameters`() { for (channel in Channel.entries) { - mockJsonJwtPost( + mockPost( baseUrl, status = 202, expectedRequestParams = mapOf( "brand" to brand, "workflow" to listOf( mapOf( @@ -92,7 +92,7 @@ class VerifyTest : AbstractTest() { @Test fun `send verification all workflows and parameters`() { - mockJsonJwtPost(baseUrl, + mockPost(baseUrl, expectedRequestParams = mapOf( "brand" to brand, "client_ref" to clientRef, @@ -170,7 +170,7 @@ class VerifyTest : AbstractTest() { @Test fun `next workflow`() { val expectedUrl = "$requestIdUrl/next-workflow" - mockJsonJwtPost(expectedUrl) + mockPost(expectedUrl) verifyClient.nextWorkflow(requestIdStr) verifyClient.nextWorkflow(requestId) assertVerifyResponseException(expectedUrl, HttpMethod.POST) { @@ -185,7 +185,7 @@ class VerifyTest : AbstractTest() { fun `check valid verification code`() { val call: () -> Boolean = {verifyClient.isValidVerificationCode(requestIdStr, code)} - mockJsonJwtPost(requestIdUrl, checkCodeRequestParams, 200) + mockPost(requestIdUrl, checkCodeRequestParams, 200) assertTrue(call.invoke()) verifyClient.checkVerificationCode(requestIdStr, code) verifyClient.checkVerificationCode(requestId, code) @@ -194,14 +194,14 @@ class VerifyTest : AbstractTest() { val title = "Invalid Code" - mockJsonJwtPost(requestIdUrl, checkCodeRequestParams, 400, mapOf( + mockPost(requestIdUrl, checkCodeRequestParams, 400, expectedResponseParams = mapOf( "title" to title, "type" to "https://www.developer.vonage.com/api-errors/verify#invalid-code", "detail" to "The code you provided does not match the expected value." )) assertFalse(call.invoke()) - mockJsonJwtPost(requestIdUrl, checkCodeRequestParams, 410, mapOf( + mockPost(requestIdUrl, checkCodeRequestParams, 410, expectedResponseParams = mapOf( "title" to title, "type" to "https://www.developer.vonage.com/api-errors/verify#expired", "detail" to "An incorrect code has been provided too many times. Workflow terminated." diff --git a/src/test/kotlin/com/vonage/client/kt/VoiceTest.kt b/src/test/kotlin/com/vonage/client/kt/VoiceTest.kt index 96f30aa..9c45f07 100644 --- a/src/test/kotlin/com/vonage/client/kt/VoiceTest.kt +++ b/src/test/kotlin/com/vonage/client/kt/VoiceTest.kt @@ -11,10 +11,42 @@ import kotlin.test.assertNotNull class VoiceTest : AbstractTest() { private val voiceClient = vonage.voice - private val callsUrl = "/v1/calls" + private val callsBaseUrl = "/v1/calls" private val callIdStr = "63f61863-4a51-4f6b-86e1-46edebcf9356" + private val callUrl = "$callsBaseUrl/$callIdStr" + private val callObj = voiceClient.call(UUID.fromString(callIdStr)) private val conversationId = "CON-f972836a-550f-45fa-956c-12a2ab5b7d22" + private fun testModifyCall(actionName: String, invocation: () -> Unit) { + mockPut(expectedUrl = callUrl, expectedRequestParams = mapOf("action" to actionName), status = 204) + invocation.invoke() + } + + @Test + fun `terminate call`() { + testModifyCall("hangup", callObj::hangup) + } + + @Test + fun `mute call`() { + testModifyCall("mute", callObj::mute) + } + + @Test + fun `umute call`() { + testModifyCall("unmute", callObj::unmute) + } + + @Test + fun `earmuff call`() { + testModifyCall("earmuff", callObj::earmuff) + } + + @Test + fun `umearmuff call`() { + testModifyCall("unearmuff", callObj::unearmuff) + } + @Test fun `get call`() { val price = "23.40" @@ -22,7 +54,7 @@ class VoiceTest : AbstractTest() { val rate = "0.39" val phoneType = "phone" - mockGet(expectedUrl = "$callsUrl/$callIdStr", expectedResponseParams = mapOf( + mockGet(expectedUrl = callUrl, expectedResponseParams = mapOf( "_links" to mapOf( "self" to mapOf( "href" to "/calls/$callIdStr" @@ -48,7 +80,7 @@ class VoiceTest : AbstractTest() { "network" to networkCode )) - val response = voiceClient.getCall(UUID.fromString(callIdStr)) + val response = callObj.get() assertNotNull(response) assertEquals(callIdStr, response.uuid) assertEquals(conversationId, response.conversationUuid)