From 87a1068fffd17195dd23d29a5f78af3648e9bd77 Mon Sep 17 00:00:00 2001 From: Sina Madani Date: Mon, 5 Aug 2024 12:57:23 +0100 Subject: [PATCH] Finish tests --- .../kotlin/com/vonage/client/kt/Numbers.kt | 4 +- src/main/kotlin/com/vonage/client/kt/Voice.kt | 4 +- .../com/vonage/client/kt/AbstractTest.kt | 5 + .../com/vonage/client/kt/MessagesTest.kt | 1 - .../com/vonage/client/kt/NumbersTest.kt | 252 +++++++++++++++++- .../kotlin/com/vonage/client/kt/SmsTest.kt | 7 +- .../kotlin/com/vonage/client/kt/VerifyTest.kt | 4 - .../kotlin/com/vonage/client/kt/VoiceTest.kt | 3 +- 8 files changed, 256 insertions(+), 24 deletions(-) diff --git a/src/main/kotlin/com/vonage/client/kt/Numbers.kt b/src/main/kotlin/com/vonage/client/kt/Numbers.kt index 4f8f269..b73d59b 100644 --- a/src/main/kotlin/com/vonage/client/kt/Numbers.kt +++ b/src/main/kotlin/com/vonage/client/kt/Numbers.kt @@ -19,7 +19,9 @@ import com.vonage.client.numbers.* class Numbers(private val numbersClient: NumbersClient) { - inner class ExistingNumber(val countryCode: String, val msisdn: String) { + fun number(countryCode: String, msisdn: String) = ExistingNumber(countryCode, msisdn) + + inner class ExistingNumber internal constructor(val countryCode: String, val msisdn: String) { fun buy(targetApiKey: String? = null) = numbersClient.buyNumber(countryCode, msisdn, targetApiKey) diff --git a/src/main/kotlin/com/vonage/client/kt/Voice.kt b/src/main/kotlin/com/vonage/client/kt/Voice.kt index fb5068e..42b4939 100644 --- a/src/main/kotlin/com/vonage/client/kt/Voice.kt +++ b/src/main/kotlin/com/vonage/client/kt/Voice.kt @@ -25,9 +25,7 @@ class Voice(private val voiceClient: VoiceClient) { fun call(callId: String): ExistingCall = ExistingCall(callId) - fun call(callId: UUID): ExistingCall = call(callId.toString()) - - inner class ExistingCall(val callId: String) { + inner class ExistingCall internal constructor(val callId: String) { fun info(): CallInfo = voiceClient.getCallDetails(callId) diff --git a/src/test/kotlin/com/vonage/client/kt/AbstractTest.kt b/src/test/kotlin/com/vonage/client/kt/AbstractTest.kt index 7f6c02e..e6bd8f3 100644 --- a/src/test/kotlin/com/vonage/client/kt/AbstractTest.kt +++ b/src/test/kotlin/com/vonage/client/kt/AbstractTest.kt @@ -52,8 +52,13 @@ abstract class AbstractTest { protected val testUuid: UUID = UUID.fromString(testUuidStr) protected val toNumber = "447712345689" protected val altNumber = "447700900001" + protected val brand = "Nexmo KT" protected val text = "Hello, World!" + protected val sipUri = "sip:rebekka@sip.example.com" + protected val clientRef = "my-personal-reference" protected val textHexEncoded = "48656c6c6f2c20576f726c6421" + protected val entityId = "1101407360000017170" + protected val contentId = "1107158078772563946" protected val smsMessageId = "0C000000217B7F02" protected val callIdStr = "63f61863-4a51-4f6b-86e1-46edebcf9356" protected val networkCode = "65512" diff --git a/src/test/kotlin/com/vonage/client/kt/MessagesTest.kt b/src/test/kotlin/com/vonage/client/kt/MessagesTest.kt index b46f40a..14ae0cd 100644 --- a/src/test/kotlin/com/vonage/client/kt/MessagesTest.kt +++ b/src/test/kotlin/com/vonage/client/kt/MessagesTest.kt @@ -96,7 +96,6 @@ class MessagesTest : AbstractTest() { @Test fun `send SMS text all parameters`() { - val clientRef = "My reference" val webhookUrl = "https://example.com/status" val ttl = 9000 val contentId = "1107457532145798767" diff --git a/src/test/kotlin/com/vonage/client/kt/NumbersTest.kt b/src/test/kotlin/com/vonage/client/kt/NumbersTest.kt index 21ed9ec..41b4a59 100644 --- a/src/test/kotlin/com/vonage/client/kt/NumbersTest.kt +++ b/src/test/kotlin/com/vonage/client/kt/NumbersTest.kt @@ -16,23 +16,259 @@ package com.vonage.client.kt import com.vonage.client.numbers.* +import com.vonage.client.numbers.UpdateNumberRequest.CallbackType +import java.util.* import kotlin.test.* class NumbersTest : AbstractTest() { private val numbersClient = vonage.numbers - private val numbersBaseUrl = "/numbers" private val country = "GB" + private val targetApiKey = "1a2345b7" + private val moHttpUrl = "$callbackUrl/inbound-sms" + private val moSmppSysType = "inbound" + private val voiceStatusCallback = "$callbackUrl/status" + private val featureNames = Feature.entries.map(Feature::name) + private val pattern = "1337*" + private val count = 1247 + private val size = 25 + private val index = 6 + private val existingNumber = numbersClient.number(country, toNumber) private val baseRequestParams = mapOf( - "country" to country, - "msisdn" to toNumber + "country" to existingNumber.countryCode, + "msisdn" to existingNumber.msisdn ) - private val successResponseJson = """ - { - "error-code": "200", - "error-code-label": "success" + private val targetApiKeyMap = mapOf("target_api_key" to targetApiKey) + private val successResponseMap = mapOf( + "error-code" to "200", + "error-code-label" to "success" + ) + + private fun mockAction(endpoint: String, additionalParams: Map = mapOf()) { + mockPostQueryParams( + expectedUrl = "/number/$endpoint", + expectedRequestParams = baseRequestParams + additionalParams, + authType = AuthType.API_KEY_SECRET_HEADER, + expectedResponseParams = successResponseMap + ) + } + + private fun assertOwnedNumbers(params: Map, invocation: Numbers.() -> ListNumbersResponse) { + val type = Type.MOBILE_LVN + val voiceCallbackType = CallbackType.SIP + val messagesCallbackValue = "aaaaaaaa-bbbb-cccc-dddd-0123456789ab" + + mockGet( + expectedUrl = "/account/numbers", + expectedQueryParams = params, + authType = AuthType.API_KEY_SECRET_HEADER, + expectedResponseParams = mapOf( + "count" to count, + "numbers" to listOf( + mapOf(), + baseRequestParams + mapOf( + "moHttpUrl" to moHttpUrl, + "type" to type.name.lowercase().replace('_', '-'), + "features" to featureNames, + "messagesCallbackType" to "app", + "messagesCallbackValue" to messagesCallbackValue, + "voiceCallbackType" to voiceCallbackType.name.lowercase(), + "voiceCallbackValue" to sipUri, + "app_id" to applicationId + ) + ) + ) + ) + + val response = invocation.invoke(numbersClient) + assertNotNull(response) + assertEquals(count, response.count) + val numbers = response.numbers + assertNotNull(numbers) + assertEquals(2, numbers.size) + + val empty = numbers[0] + assertNotNull(empty) + assertNull(empty.msisdn) + assertNull(empty.country) + assertNull(empty.voiceCallbackType) + assertNull(empty.voiceCallbackValue) + assertNull(empty.messagesCallbackValue) + assertNull(empty.moHttpUrl) + assertNull(empty.type) + assertNull(empty.features) + + val main = numbers[1] + assertNotNull(main) + assertEquals(country, main.country) + assertEquals(toNumber, main.msisdn) + assertEquals(moHttpUrl, main.moHttpUrl) + assertEquals(type, Type.fromString(main.type)) + assertEquals(featureNames, main.features.toList()) + assertEquals(UUID.fromString(messagesCallbackValue), main.messagesCallbackValue) + assertEquals(voiceCallbackType, CallbackType.fromString(main.voiceCallbackType)) + assertEquals(sipUri, main.voiceCallbackValue) + } + + private fun assertAvailableNumbers(params: Map, invocation: Numbers.() -> SearchNumbersResponse) { + val landline = "44800123456" + mockGet( + expectedUrl = "/number/search", + expectedQueryParams = params, + authType = AuthType.API_KEY_SECRET_HEADER, + expectedResponseParams = mapOf( + "count" to count, + "numbers" to listOf( + mapOf("cost" to "1.29"), + mapOf( + "country" to country, + "msisdn" to landline, + "type" to "landline-toll-free", + "cost" to "3.80", + "features" to listOf("VOICE") + ), + baseRequestParams + mapOf( + "features" to listOf("SMS", "MMS"), + "type" to "mobile-lvn" + ) + ) + ) + ) + + val response = invocation.invoke(numbersClient) + assertNotNull(response) + assertEquals(count, response.count) + val numbers = response.numbers + assertNotNull(numbers) + assertEquals(3, numbers.size) + + val costOnly = numbers[0] + assertNotNull(costOnly) + assertEquals(1.29, costOnly.cost.toDouble()) + assertNull(costOnly.type) + assertNull(costOnly.country) + assertNull(costOnly.msisdn) + assertNull(costOnly.features) + + val main = numbers[1] + assertNotNull(main) + assertEquals(Type.LANDLINE_TOLL_FREE, Type.fromString(main.type)) + assertEquals(3.80, main.cost.toDouble()) + assertEquals(landline, main.msisdn) + assertEquals(country, main.country) + val mainFeatures = main.features + assertNotNull(mainFeatures) + assertEquals(1, mainFeatures.size) + assertEquals(Feature.VOICE, Feature.fromString(mainFeatures[0])) + + val mobile = numbers[2] + assertEquals(country, mobile.country) + assertEquals(toNumber, mobile.msisdn) + assertEquals(Type.MOBILE_LVN, Type.fromString(mobile.type)) + val mobileFeatures = mobile.features + assertNotNull(mobileFeatures) + assertEquals(2, mobileFeatures.size) + assertEquals(Feature.SMS, Feature.fromString(mobileFeatures[0])) + assertEquals(Feature.MMS, Feature.fromString(mobileFeatures[1])) + assertNull(mobile.cost) + } + + @Test + fun `buy number`() { + mockAction("buy") + existingNumber.buy() + } + + @Test + fun `buy number with target api key`() { + mockAction("buy", targetApiKeyMap) + existingNumber.buy(targetApiKey) + } + + @Test + fun `cancel number`() { + mockAction("cancel") + existingNumber.cancel() + } + + @Test + fun `cancel number with target api key`() { + mockAction("cancel", targetApiKeyMap) + existingNumber.cancel(targetApiKey) + } + + @Test + fun `update no parameters`() { + mockAction("update") + existingNumber.update {} + } + + @Test + fun `update all parameters`() { + mockAction("update", mapOf( + "app_id" to applicationId, + "moHttpUrl" to moHttpUrl, + "moSmppSysType" to moSmppSysType, + "voiceStatusCallback" to voiceStatusCallback, + "voiceCallbackType" to "tel", + "voiceCallbackValue" to altNumber + )) + existingNumber.update { + applicationId(applicationId) + moHttpUrl(moHttpUrl); moSmppSysType(moSmppSysType) + voiceStatusCallback(voiceStatusCallback) + voiceCallback(CallbackType.TEL, altNumber) } - """.trimIndent() + } + @Test + fun `list owned numbers no parameters`() { + assertOwnedNumbers(mapOf()) { listOwned() } + } + @Test + fun `list owned numbers all parameters`() { + val hasApplication = true + assertOwnedNumbers(mapOf( + "country" to country, + "application_id" to applicationId, + "has_application" to hasApplication, + "pattern" to pattern, + "search_pattern" to 2, + "size" to size, + "index" to index + )) { + listOwned { + country(country) + applicationId(applicationId) + hasApplication(hasApplication) + pattern(SearchPattern.ENDS_WITH, pattern) + size(size); index(index) + } + } + } + @Test + fun `search available numbers no parameters`() { + assertAvailableNumbers(mapOf()) { + searchAvailable { } + } + } + + @Test + fun `search available numbers all parameters`() { + assertAvailableNumbers(mapOf( + "country" to country, + "pattern" to pattern, + "search_pattern" to 0, + "features" to featureNames.joinToString(","), + "size" to size, + "index" to index + )) { + searchAvailable { + country(country); size(size); index(index) + pattern(SearchPattern.STARTS_WITH, pattern) + features(Feature.SMS, Feature.MMS, Feature.VOICE) + } + } + } } \ No newline at end of file diff --git a/src/test/kotlin/com/vonage/client/kt/SmsTest.kt b/src/test/kotlin/com/vonage/client/kt/SmsTest.kt index b7c80cd..7d98294 100644 --- a/src/test/kotlin/com/vonage/client/kt/SmsTest.kt +++ b/src/test/kotlin/com/vonage/client/kt/SmsTest.kt @@ -24,14 +24,11 @@ import kotlin.test.* class SmsTest : AbstractTest() { private val smsClient = vonage.sms private val sendUrl = "/sms/json" - private val from = "Nexmo" - private val clientRef = "my-personal-reference" + private val from = brand private val accountRef = "customer1234" private val ttl = 900000 private val statusReport = true - private val callback = "https://example.com/sms-dlr" - private val entityId = "1101456324675322134" - private val contentId = "1107457532145798767" + private val callback = "$exampleUrlBase/sms-dlr" private val udhBinary = byteArrayOf(0x05, 0x00, 0x03, 0x7A, 0x02, 0x01) @OptIn(ExperimentalStdlibApi::class) private val udhHex = udhBinary.toHexString(HexFormat.UpperCase) diff --git a/src/test/kotlin/com/vonage/client/kt/VerifyTest.kt b/src/test/kotlin/com/vonage/client/kt/VerifyTest.kt index 0586cec..0d429f1 100644 --- a/src/test/kotlin/com/vonage/client/kt/VerifyTest.kt +++ b/src/test/kotlin/com/vonage/client/kt/VerifyTest.kt @@ -29,8 +29,6 @@ class VerifyTest : AbstractTest() { private val requestIdStr = "c11236f4-00bf-4b89-84ba-88b25df97315" private val requestId = UUID.fromString(requestIdStr) private val requestIdUrl = "$baseUrl/$requestIdStr" - private val brand = "Nexmo KT" - private val clientRef = "my-personal-reference" private val timeout = 60 private val fraudCheck = false private val sandbox = true @@ -38,8 +36,6 @@ class VerifyTest : AbstractTest() { private val code = "1228864" private val locale = "ja-jp" private val whatsappNumber = "447700400080" - private val entityId = "1101407360000017170" - private val contentId = "1107158078772563946" private val appHash = "ABC123def45" private val toEmail = "alice@example.com" private val fromEmail = "bob@example.org" diff --git a/src/test/kotlin/com/vonage/client/kt/VoiceTest.kt b/src/test/kotlin/com/vonage/client/kt/VoiceTest.kt index 80ba092..54bc226 100644 --- a/src/test/kotlin/com/vonage/client/kt/VoiceTest.kt +++ b/src/test/kotlin/com/vonage/client/kt/VoiceTest.kt @@ -27,7 +27,7 @@ class VoiceTest : AbstractTest() { private val voiceClient = vonage.voice private val callsBaseUrl = "/v1/calls" private val callUrl = "$callsBaseUrl/$callIdStr" - private val callObj = voiceClient.call(UUID.fromString(callIdStr)) + private val callObj = voiceClient.call(callIdStr) private val conversationId = "CON-f972836a-550f-45fa-956c-12a2ab5b7d22" private val price = "23.40" private val duration = 60 @@ -45,7 +45,6 @@ class VoiceTest : AbstractTest() { private val onAnswerUrl = "https://example.com/ncco.json" private val websocketUri = "wss://example.com/socket" private val ringbackTone = "http://example.com/ringbackTone.wav" - private val sipUri = "sip:rebekka@sip.example.com" private val wsContentType = "audio/l16;rate=8000" private val userToUserHeader = "56a390f3d2b7310023a" private val conversationName = "selective-audio Demo"