Skip to content

Commit

Permalink
feat: Voice.listCalls
Browse files Browse the repository at this point in the history
  • Loading branch information
SMadani committed Jun 27, 2024
1 parent 790762b commit 41ef916
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 81 deletions.
18 changes: 12 additions & 6 deletions src/main/kotlin/com/vonage/client/kt/Voice.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
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.*
import com.vonage.client.voice.ncco.Ncco
import java.net.URI
import java.time.Instant
import java.util.*

class Voice(private val voiceClient: VoiceClient) {
Expand Down Expand Up @@ -35,5 +33,13 @@ class Voice(private val voiceClient: VoiceClient) {
fun transfer(nccoUrl: URI) = transfer(nccoUrl.toString())
}

fun listCalls(filter: CallsFilter? = null): CallInfoPage = voiceClient.listCalls(filter)
}
fun listCalls(filter: (CallsFilter.Builder.() -> Unit)? = null): CallInfoPage =
if (filter == null) voiceClient.listCalls()
else voiceClient.listCalls(CallsFilter.builder().apply(filter).build())
}

fun CallsFilter.Builder.dateStart(dateStart: String): CallsFilter.Builder =
dateStart(Date.from(Instant.parse(dateStart)))

fun CallsFilter.Builder.dateEnd(dateEnd: String): CallsFilter.Builder =
dateEnd(Date.from(Instant.parse(dateEnd)))
9 changes: 3 additions & 6 deletions src/main/kotlin/com/vonage/client/kt/Vonage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@ fun VonageClient.Builder.authFromEnv(): VonageClient.Builder {
return this
}

fun VonageClient.Builder.httpConfig(init: HttpConfig.Builder.() -> Unit): VonageClient.Builder {
return this.httpConfig(HttpConfig.builder().apply(init).build())
}
fun VonageClient.Builder.httpConfig(init: HttpConfig.Builder.() -> Unit): VonageClient.Builder =
httpConfig(HttpConfig.builder().apply(init).build())

private fun env(variable: String) : String? {
return System.getenv(variable)
}
private fun env(variable: String) : String? = System.getenv(variable)
27 changes: 14 additions & 13 deletions src/test/kotlin/com/vonage/client/kt/AbstractTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ abstract class AbstractTest {
protected val networkCode = "65512"
protected val startTime = "2020-09-17T12:34:56Z"
protected val endTime = "2021-09-17T12:35:28Z"
protected val timestamp = "2016-11-14T07:45:14Z"

private val port = 8081
val wiremock: WireMockServer = WireMockServer(
Expand Down Expand Up @@ -91,19 +92,21 @@ abstract class AbstractTest {
}
if (contentType != null) {
headers contains "Content-Type" equalTo contentType.mime
if (expectedParams != null) when(contentType) {
ContentType.APPLICATION_JSON -> {
body equalTo ObjectMapper().writeValueAsString(expectedParams)
}
ContentType.FORM_URLENCODED -> {
// TODO recursive decomposition for nested params
expectedParams.forEach {k, v -> headers contains k equalTo v.toString() }
}
}
}
if (accept != null) {
headers contains "Accept" equalTo accept.mime
}
if (expectedParams != null) {
if (contentType == ContentType.APPLICATION_JSON) {
body equalTo ObjectMapper().writeValueAsString(expectedParams)
}
else {
url like "$expectedUrl\\?.+"
expectedParams.forEach { (k, v) ->
queryParams contains k equalTo v.toString()
}
}
}
}, when (httpMethod) {
HttpMethod.GET -> WireMock::get
HttpMethod.POST -> WireMock::post
Expand Down Expand Up @@ -154,10 +157,8 @@ abstract class AbstractTest {
authType: AuthType? = AuthType.JWT,
expectedResponseParams: Map<String, Any>) =

mockRequest(HttpMethod.GET, expectedUrl,
contentType = if (expectedQueryParams != null) ContentType.FORM_URLENCODED else null,
accept = ContentType.APPLICATION_JSON, authType, expectedQueryParams
).mockReturn(status, expectedResponseParams)
mockRequest(HttpMethod.GET, expectedUrl, accept = ContentType.APPLICATION_JSON, authType = authType,
expectedParams = expectedQueryParams).mockReturn(status, expectedResponseParams)


protected fun BuildingStep.mockReturn(
Expand Down
169 changes: 113 additions & 56 deletions src/test/kotlin/com/vonage/client/kt/VoiceTest.kt
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
package com.vonage.client.kt

import com.vonage.client.voice.CallDirection
import com.vonage.client.voice.CallStatus
import com.vonage.client.voice.PhoneEndpoint
import com.vonage.client.voice.*
import com.vonage.client.voice.ncco.Ncco
import com.vonage.client.voice.ncco.TalkAction
import java.net.URI
import java.time.Instant
import java.util.*
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.*

class VoiceTest : AbstractTest() {
private val voiceClient = vonage.voice
Expand All @@ -19,6 +16,85 @@ class VoiceTest : AbstractTest() {
private val callUrl = "$callsBaseUrl/$callIdStr"
private val callObj = voiceClient.call(UUID.fromString(callIdStr))
private val conversationId = "CON-f972836a-550f-45fa-956c-12a2ab5b7d22"
private val price = "23.40"
private val duration = 60
private val rate = "0.39"
private val phoneType = "phone"
private val count = 89
private val pageSize = 25
private val recordIndex = 14
private val callResponseMap = mapOf(
"_links" to mapOf(
"self" to mapOf(
"href" to "/calls/$callIdStr"
)
),
"uuid" to callIdStr,
"conversation_uuid" to conversationId,
"to" to mapOf(
"type" to phoneType,
"number" to toNumber
),
"from" to mapOf(
"type" to phoneType,
"number" to altNumber
),
"status" to "completed",
"direction" to "outbound",
"rate" to rate,
"price" to price,
"duration" to "$duration",
"start_time" to startTime,
"end_time" to endTime,
"network" to networkCode
)
private val listCallsResponse = mapOf(
"count" to count,
"page_size" to pageSize,
"record_index" to recordIndex,
"_links" to mapOf("self" to mapOf(
"href" to "/calls?page_size=$pageSize&record_index=$recordIndex&order=desc"
)),
"_embedded" to mapOf("calls" to listOf(
mapOf(),
callResponseMap
))
)

private fun assertEqualsSampleCall(callInfo: CallInfo) {
assertNotNull(callInfo)
assertEquals(callIdStr, callInfo.uuid)
assertEquals(conversationId, callInfo.conversationUuid)
val to = callInfo.to
assertNotNull(to)
assertEquals(phoneType, to.type)
assertEquals(toNumber, (to as PhoneEndpoint).number)
val from = callInfo.from
assertNotNull(from)
assertEquals(phoneType, from.type)
assertEquals(altNumber, (from as PhoneEndpoint).number)
assertEquals(CallStatus.COMPLETED, callInfo.status)
assertEquals(CallDirection.OUTBOUND, callInfo.direction)
assertEquals(rate, callInfo.rate)
assertEquals(price, callInfo.price)
assertEquals(duration, callInfo.duration)
assertEquals(Instant.parse(startTime), callInfo.startTime.toInstant())
assertEquals(Instant.parse(endTime), callInfo.endTime.toInstant())
assertEquals(networkCode, callInfo.network)
}

private fun assertEqualsSampleCallsPage(callsPage: CallInfoPage) {
assertNotNull(callsPage)
assertEquals(pageSize, callsPage.pageSize)
assertEquals(recordIndex, callsPage.recordIndex)
assertNotNull(callsPage.links?.self?.href)
assertEquals(count, callsPage.count)
val infos = callsPage.embedded?.callInfos
assertNotNull(infos)
assertEquals(2, infos.size)
assertNotNull(infos[0])
assertEqualsSampleCall(infos[1])
}

private fun testModifyCall(actionName: String = "transfer", invocation: () -> Unit,
nccoAction: Map<String, Any>? = null, nccoUrl: String? = null) {
Expand Down Expand Up @@ -62,57 +138,8 @@ class VoiceTest : AbstractTest() {

@Test
fun `get call`() {
val price = "23.40"
val duration = 60
val rate = "0.39"
val phoneType = "phone"

mockGet(expectedUrl = callUrl, expectedResponseParams = mapOf(
"_links" to mapOf(
"self" to mapOf(
"href" to "/calls/$callIdStr"
)
),
"uuid" to callIdStr,
"conversation_uuid" to conversationId,
"to" to mapOf(
"type" to phoneType,
"number" to toNumber
),
"from" to mapOf(
"type" to phoneType,
"number" to altNumber
),
"status" to "completed",
"direction" to "outbound",
"rate" to rate,
"price" to price,
"duration" to "$duration",
"start_time" to startTime,
"end_time" to endTime,
"network" to networkCode
))

val response = callObj.get()
assertNotNull(response)
assertEquals(callIdStr, response.uuid)
assertEquals(conversationId, response.conversationUuid)
val to = response.to
assertNotNull(to)
assertEquals(phoneType, to.type)
assertEquals(toNumber, (to as PhoneEndpoint).number)
val from = response.from
assertNotNull(from)
assertEquals(phoneType, from.type)
assertEquals(altNumber, (from as PhoneEndpoint).number)
assertEquals(CallStatus.COMPLETED, response.status)
assertEquals(CallDirection.OUTBOUND, response.direction)
assertEquals(rate, response.rate)
assertEquals(price, response.price)
assertEquals(duration, response.duration)
assertEquals(Instant.parse(startTime), response.startTime.toInstant())
assertEquals(Instant.parse(endTime), response.endTime.toInstant())
assertEquals(networkCode, response.network)
mockGet(expectedUrl = callUrl, expectedResponseParams = callResponseMap)
assertEqualsSampleCall(callObj.get())
}

@Test
Expand All @@ -130,4 +157,34 @@ class VoiceTest : AbstractTest() {
callObj.transfer(Ncco(TalkAction.builder(text).build()))
})
}

@Test
fun `list calls all filter parameters`() {
mockGet(callsBaseUrl, expectedQueryParams = mapOf(
"status" to "unanswered",
"date_start" to startTime,
"date_end" to endTime,
"page_size" to pageSize,
"record_index" to recordIndex,
"order" to "desc",
"conversation_uuid" to conversationId

), expectedResponseParams = listCallsResponse)

val callsPage = voiceClient.listCalls {
status(CallStatus.UNANSWERED)
dateStart(startTime); dateEnd(endTime)
pageSize(pageSize); recordIndex(recordIndex)
order(CallOrder.DESCENDING); conversationUuid(conversationId)
}

assertEqualsSampleCallsPage(callsPage)
}

@Test
fun `list calls no filter`() {
mockGet(callsBaseUrl, expectedResponseParams = listCallsResponse)
assertEqualsSampleCallsPage(voiceClient.listCalls())
}

}

0 comments on commit 41ef916

Please sign in to comment.