From feebccd1c539f4ae329ba6a8d934b885b7df0ab1 Mon Sep 17 00:00:00 2001 From: Anantha Krishna Bhatta Date: Fri, 8 Oct 2021 14:57:44 -0700 Subject: [PATCH] Email recipients made nested for backward compatibility with Alerting [Tests] Unit tests added/updated Signed-off-by: @akbhatta --- .../commons/notifications/model/Email.kt | 15 +- .../commons/notifications/model/EmailGroup.kt | 19 +-- .../notifications/model/EmailRecipient.kt | 119 +++++++++++++++ .../CreateNotificationConfigRequestTests.kt | 18 ++- .../action/GetPluginFeaturesResponseTests.kt | 1 + .../UpdateNotificationConfigRequestTests.kt | 18 ++- .../notifications/model/EmailGroupTests.kt | 90 +++++------ .../model/EmailRecipientTests.kt | 142 ++++++++++++++++++ .../commons/notifications/model/EmailTests.kt | 69 +++------ .../model/NotificationConfigTests.kt | 8 +- .../model/config/ConfigPropertiesTests.kt | 3 +- 11 files changed, 361 insertions(+), 141 deletions(-) create mode 100644 src/main/kotlin/org/opensearch/commons/notifications/model/EmailRecipient.kt create mode 100644 src/test/kotlin/org/opensearch/commons/notifications/model/EmailRecipientTests.kt diff --git a/src/main/kotlin/org/opensearch/commons/notifications/model/Email.kt b/src/main/kotlin/org/opensearch/commons/notifications/model/Email.kt index c8da0f85..86d5f67a 100644 --- a/src/main/kotlin/org/opensearch/commons/notifications/model/Email.kt +++ b/src/main/kotlin/org/opensearch/commons/notifications/model/Email.kt @@ -38,8 +38,8 @@ import org.opensearch.commons.notifications.NotificationConstants.EMAIL_ACCOUNT_ import org.opensearch.commons.notifications.NotificationConstants.EMAIL_GROUP_ID_LIST_TAG import org.opensearch.commons.notifications.NotificationConstants.RECIPIENT_LIST_TAG import org.opensearch.commons.utils.logger +import org.opensearch.commons.utils.objectList import org.opensearch.commons.utils.stringList -import org.opensearch.commons.utils.validateEmail import java.io.IOException /** @@ -47,15 +47,12 @@ import java.io.IOException */ data class Email( val emailAccountID: String, - val recipients: List, + val recipients: List, val emailGroupIds: List ) : BaseConfigData { init { require(!Strings.isNullOrEmpty(emailAccountID)) { "emailAccountID is null or empty" } - recipients.forEach { - validateEmail(it) - } } companion object { @@ -79,7 +76,7 @@ data class Email( @Throws(IOException::class) fun parse(parser: XContentParser): Email { var emailAccountID: String? = null - var recipients: List = listOf() + var recipients: List = listOf() var emailGroupIds: List = listOf() XContentParserUtils.ensureExpectedToken( @@ -92,7 +89,7 @@ data class Email( parser.nextToken() when (fieldName) { EMAIL_ACCOUNT_ID_TAG -> emailAccountID = parser.text() - RECIPIENT_LIST_TAG -> recipients = parser.stringList() + RECIPIENT_LIST_TAG -> recipients = parser.objectList { EmailRecipient.parse(it) } EMAIL_GROUP_ID_LIST_TAG -> emailGroupIds = parser.stringList() else -> { parser.skipChildren() @@ -111,7 +108,7 @@ data class Email( */ constructor(input: StreamInput) : this( emailAccountID = input.readString(), - recipients = input.readStringList(), + recipients = input.readList(EmailRecipient.reader), emailGroupIds = input.readStringList() ) @@ -120,7 +117,7 @@ data class Email( */ override fun writeTo(output: StreamOutput) { output.writeString(emailAccountID) - output.writeStringCollection(recipients) + output.writeList(recipients) output.writeStringCollection(emailGroupIds) } diff --git a/src/main/kotlin/org/opensearch/commons/notifications/model/EmailGroup.kt b/src/main/kotlin/org/opensearch/commons/notifications/model/EmailGroup.kt index f3beecd8..4940cc39 100644 --- a/src/main/kotlin/org/opensearch/commons/notifications/model/EmailGroup.kt +++ b/src/main/kotlin/org/opensearch/commons/notifications/model/EmailGroup.kt @@ -35,23 +35,16 @@ import org.opensearch.common.xcontent.XContentParser import org.opensearch.common.xcontent.XContentParserUtils import org.opensearch.commons.notifications.NotificationConstants.RECIPIENT_LIST_TAG import org.opensearch.commons.utils.logger -import org.opensearch.commons.utils.stringList -import org.opensearch.commons.utils.validateEmail +import org.opensearch.commons.utils.objectList import java.io.IOException /** * Data class representing Email group. */ data class EmailGroup( - val recipients: List + val recipients: List ) : BaseConfigData { - init { - recipients.forEach { - validateEmail(it) - } - } - companion object { private val log by logger(EmailGroup::class.java) @@ -72,7 +65,7 @@ data class EmailGroup( @JvmStatic @Throws(IOException::class) fun parse(parser: XContentParser): EmailGroup { - var recipients: List? = null + var recipients: List? = null XContentParserUtils.ensureExpectedToken( XContentParser.Token.START_OBJECT, @@ -83,7 +76,7 @@ data class EmailGroup( val fieldName = parser.currentName() parser.nextToken() when (fieldName) { - RECIPIENT_LIST_TAG -> recipients = parser.stringList() + RECIPIENT_LIST_TAG -> recipients = parser.objectList { EmailRecipient.parse(it) } else -> { parser.skipChildren() log.info("Unexpected field: $fieldName, while parsing EmailGroup") @@ -100,14 +93,14 @@ data class EmailGroup( * @param input StreamInput stream to deserialize data from. */ constructor(input: StreamInput) : this( - recipients = input.readStringList() + recipients = input.readList(EmailRecipient.reader) ) /** * {@inheritDoc} */ override fun writeTo(output: StreamOutput) { - output.writeStringCollection(recipients) + output.writeList(recipients) } /** diff --git a/src/main/kotlin/org/opensearch/commons/notifications/model/EmailRecipient.kt b/src/main/kotlin/org/opensearch/commons/notifications/model/EmailRecipient.kt new file mode 100644 index 00000000..78c4ae59 --- /dev/null +++ b/src/main/kotlin/org/opensearch/commons/notifications/model/EmailRecipient.kt @@ -0,0 +1,119 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +/* + * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + * + */ +package org.opensearch.commons.notifications.model + +import org.opensearch.common.io.stream.StreamInput +import org.opensearch.common.io.stream.StreamOutput +import org.opensearch.common.io.stream.Writeable +import org.opensearch.common.xcontent.ToXContent +import org.opensearch.common.xcontent.XContentBuilder +import org.opensearch.common.xcontent.XContentParser +import org.opensearch.common.xcontent.XContentParserUtils +import org.opensearch.commons.notifications.NotificationConstants.RECIPIENT_TAG +import org.opensearch.commons.utils.logger +import org.opensearch.commons.utils.validateEmail +import java.io.IOException + +/** + * Data class representing Email recipient. + */ +data class EmailRecipient( + val recipient: String +) : BaseConfigData { + + init { + validateEmail(recipient) + } + + companion object { + private val log by logger(EmailRecipient::class.java) + + /** + * reader to create instance of class from writable. + */ + val reader = Writeable.Reader { EmailRecipient(it) } + + /** + * Parser to parse xContent + */ + val xParser = XParser { parse(it) } + + /** + * Creator used in REST communication. + * @param parser XContentParser to deserialize data from. + */ + @JvmStatic + @Throws(IOException::class) + fun parse(parser: XContentParser): EmailRecipient { + var recipient: String? = null + + XContentParserUtils.ensureExpectedToken( + XContentParser.Token.START_OBJECT, + parser.currentToken(), + parser + ) + while (parser.nextToken() != XContentParser.Token.END_OBJECT) { + val fieldName = parser.currentName() + parser.nextToken() + when (fieldName) { + RECIPIENT_TAG -> recipient = parser.text() + else -> { + parser.skipChildren() + log.info("Unexpected field: $fieldName, while parsing EmailRecipient") + } + } + } + recipient ?: throw IllegalArgumentException("$RECIPIENT_TAG field absent") + return EmailRecipient(recipient) + } + } + + /** + * Constructor used in transport action communication. + * @param input StreamInput stream to deserialize data from. + */ + constructor(input: StreamInput) : this( + recipient = input.readString() + ) + + /** + * {@inheritDoc} + */ + override fun writeTo(output: StreamOutput) { + output.writeString(recipient) + } + + /** + * {@inheritDoc} + */ + override fun toXContent(builder: XContentBuilder?, params: ToXContent.Params?): XContentBuilder { + builder!! + return builder.startObject() + .field(RECIPIENT_TAG, recipient) + .endObject() + } +} diff --git a/src/test/kotlin/org/opensearch/commons/notifications/action/CreateNotificationConfigRequestTests.kt b/src/test/kotlin/org/opensearch/commons/notifications/action/CreateNotificationConfigRequestTests.kt index f190e7f6..28f337b8 100644 --- a/src/test/kotlin/org/opensearch/commons/notifications/action/CreateNotificationConfigRequestTests.kt +++ b/src/test/kotlin/org/opensearch/commons/notifications/action/CreateNotificationConfigRequestTests.kt @@ -36,6 +36,7 @@ import org.opensearch.commons.notifications.model.Chime import org.opensearch.commons.notifications.model.ConfigType import org.opensearch.commons.notifications.model.Email import org.opensearch.commons.notifications.model.EmailGroup +import org.opensearch.commons.notifications.model.EmailRecipient import org.opensearch.commons.notifications.model.MethodType import org.opensearch.commons.notifications.model.NotificationConfig import org.opensearch.commons.notifications.model.Slack @@ -84,7 +85,7 @@ internal class CreateNotificationConfigRequestTests { } private fun createEmailGroupContentConfigObject(): NotificationConfig { - val sampleEmailGroup = EmailGroup(listOf("dummy@company.com")) + val sampleEmailGroup = EmailGroup(listOf(EmailRecipient("dummy@company.com"))) return NotificationConfig( "name", "description", @@ -98,7 +99,7 @@ internal class CreateNotificationConfigRequestTests { private fun createEmailContentConfigObject(): NotificationConfig { val sampleEmail = Email( emailAccountID = "sample_1@dummy.com", - recipients = listOf("sample_2@dummy.com"), + recipients = listOf(EmailRecipient("sample_2@dummy.com")), emailGroupIds = listOf("sample_3@dummy.com") ) return NotificationConfig( @@ -365,7 +366,7 @@ internal class CreateNotificationConfigRequestTests { @Test fun `Create config should deserialize json object using parser Email Group`() { - val sampleEmailGroup = EmailGroup(listOf("dummy@company.com")) + val sampleEmailGroup = EmailGroup(listOf(EmailRecipient("dummy@company.com"))) val config = NotificationConfig( "name", "description", @@ -384,7 +385,7 @@ internal class CreateNotificationConfigRequestTests { "config_type":"email_group", "feature_list":["index_management"], "is_enabled":true, - "email_group":{"recipient_list":["dummy@company.com"]} + "email_group":{"recipient_list":[{"recipient":"dummy@company.com"}]} } } """.trimIndent() @@ -396,7 +397,7 @@ internal class CreateNotificationConfigRequestTests { fun `Update config should deserialize json object using parser Email`() { val sampleEmail = Email( emailAccountID = "sample_1@dummy.com", - recipients = listOf("sample_2@dummy.com"), + recipients = listOf(EmailRecipient("sample_2@dummy.com")), emailGroupIds = listOf("sample_3@dummy.com") ) val config = NotificationConfig( @@ -417,8 +418,11 @@ internal class CreateNotificationConfigRequestTests { "config_type":"email", "feature_list":["index_management"], "is_enabled":true, - "email":{"email_account_id":"sample_1@dummy.com","recipient_list":["sample_2@dummy.com"], - "email_group_id_list":["sample_3@dummy.com"] } + "email":{ + "email_account_id":"sample_1@dummy.com", + "recipient_list":[{"recipient":"sample_2@dummy.com"}], + "email_group_id_list":["sample_3@dummy.com"] + } } } """.trimIndent() diff --git a/src/test/kotlin/org/opensearch/commons/notifications/action/GetPluginFeaturesResponseTests.kt b/src/test/kotlin/org/opensearch/commons/notifications/action/GetPluginFeaturesResponseTests.kt index 930d430f..c9924269 100644 --- a/src/test/kotlin/org/opensearch/commons/notifications/action/GetPluginFeaturesResponseTests.kt +++ b/src/test/kotlin/org/opensearch/commons/notifications/action/GetPluginFeaturesResponseTests.kt @@ -40,6 +40,7 @@ internal class GetPluginFeaturesResponseTests { actual: GetPluginFeaturesResponse ) { assertEquals(expected.allowedConfigTypeList, actual.allowedConfigTypeList) + assertEquals(expected.allowedConfigFeatureList, actual.allowedConfigFeatureList) assertEquals(expected.pluginFeatures, actual.pluginFeatures) } diff --git a/src/test/kotlin/org/opensearch/commons/notifications/action/UpdateNotificationConfigRequestTests.kt b/src/test/kotlin/org/opensearch/commons/notifications/action/UpdateNotificationConfigRequestTests.kt index 2dfcff69..9599d60e 100644 --- a/src/test/kotlin/org/opensearch/commons/notifications/action/UpdateNotificationConfigRequestTests.kt +++ b/src/test/kotlin/org/opensearch/commons/notifications/action/UpdateNotificationConfigRequestTests.kt @@ -36,6 +36,7 @@ import org.opensearch.commons.notifications.model.Chime import org.opensearch.commons.notifications.model.ConfigType import org.opensearch.commons.notifications.model.Email import org.opensearch.commons.notifications.model.EmailGroup +import org.opensearch.commons.notifications.model.EmailRecipient import org.opensearch.commons.notifications.model.MethodType import org.opensearch.commons.notifications.model.NotificationConfig import org.opensearch.commons.notifications.model.Slack @@ -84,7 +85,7 @@ internal class UpdateNotificationConfigRequestTests { } private fun createEmailGroupContentConfigObject(): NotificationConfig { - val sampleEmailGroup = EmailGroup(listOf("dummy@company.com")) + val sampleEmailGroup = EmailGroup(listOf(EmailRecipient("dummy@company.com"))) return NotificationConfig( "name", "description", @@ -98,7 +99,7 @@ internal class UpdateNotificationConfigRequestTests { private fun createEmailContentConfigObject(): NotificationConfig { val sampleEmail = Email( emailAccountID = "sample_1@dummy.com", - recipients = listOf("sample_2@dummy.com"), + recipients = listOf(EmailRecipient("sample_2@dummy.com")), emailGroupIds = listOf("sample_3@dummy.com") ) return NotificationConfig( @@ -334,7 +335,7 @@ internal class UpdateNotificationConfigRequestTests { @Test fun `Update config should deserialize json object using parser Email Group`() { - val sampleEmailGroup = EmailGroup(listOf("dummy@company.com")) + val sampleEmailGroup = EmailGroup(listOf(EmailRecipient("dummy@company.com"))) val config = NotificationConfig( "name", "description", @@ -353,7 +354,7 @@ internal class UpdateNotificationConfigRequestTests { "config_type":"email_group", "feature_list":["index_management"], "is_enabled":true, - "email_group":{"recipient_list":["dummy@company.com"]} + "email_group":{"recipient_list":[{"recipient":"dummy@company.com"}]} } } """.trimIndent() @@ -366,7 +367,7 @@ internal class UpdateNotificationConfigRequestTests { fun `Update config should deserialize json object using parser Email`() { val sampleEmail = Email( emailAccountID = "sample_1@dummy.com", - recipients = listOf("sample_2@dummy.com"), + recipients = listOf(EmailRecipient("sample_2@dummy.com")), emailGroupIds = listOf("sample_3@dummy.com") ) val config = NotificationConfig( @@ -387,8 +388,11 @@ internal class UpdateNotificationConfigRequestTests { "config_type":"email", "feature_list":["index_management"], "is_enabled":true, - "email":{"email_account_id":"sample_1@dummy.com","recipient_list":["sample_2@dummy.com"], - "email_group_id_list":["sample_3@dummy.com"] } + "email":{ + "email_account_id":"sample_1@dummy.com", + "recipient_list":[{"recipient":"sample_2@dummy.com"}], + "email_group_id_list":["sample_3@dummy.com"] + } } } """.trimIndent() diff --git a/src/test/kotlin/org/opensearch/commons/notifications/model/EmailGroupTests.kt b/src/test/kotlin/org/opensearch/commons/notifications/model/EmailGroupTests.kt index 5146d785..dbf2f77b 100644 --- a/src/test/kotlin/org/opensearch/commons/notifications/model/EmailGroupTests.kt +++ b/src/test/kotlin/org/opensearch/commons/notifications/model/EmailGroupTests.kt @@ -29,7 +29,6 @@ package org.opensearch.commons.notifications.model import com.fasterxml.jackson.core.JsonParseException import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertDoesNotThrow import org.junit.jupiter.api.assertThrows import org.opensearch.commons.utils.createObjectFromJsonString import org.opensearch.commons.utils.getJsonString @@ -37,56 +36,26 @@ import org.opensearch.commons.utils.recreateObject internal class EmailGroupTests { - private fun checkValidEmailAddress(emailAddress: String) { - assertDoesNotThrow("should accept $emailAddress") { - EmailGroup(listOf(emailAddress)) - } - } - - private fun checkInvalidEmailAddress(emailAddress: String) { - assertThrows("Should throw an Exception for invalid email $emailAddress") { - EmailGroup(listOf(emailAddress)) - } - } - - @Test - fun `EmailGroup should accept valid email address`() { - checkValidEmailAddress("email1234@email.com") - checkValidEmailAddress("email+1234@email.com") - checkValidEmailAddress("email-1234@email.com") - checkValidEmailAddress("email_1234@email.com") - checkValidEmailAddress("email.1234@email.com") - checkValidEmailAddress("e.ma_il-1+2@test-email-domain.co.uk") - checkValidEmailAddress("email-.+_=#|@domain.com") - checkValidEmailAddress("e@mail.com") - } - - @Test - fun `EmailGroup should throw exception for invalid email address`() { - checkInvalidEmailAddress("email") - checkInvalidEmailAddress("email@") - checkInvalidEmailAddress("email@1234@email.com") - checkInvalidEmailAddress(".email@email.com") - checkInvalidEmailAddress("email.@email.com") - checkInvalidEmailAddress("email..1234@email.com") - checkInvalidEmailAddress("email@email..com") - checkInvalidEmailAddress("email@.com") - checkInvalidEmailAddress("email@email.com.") - checkInvalidEmailAddress("email@.email.com") - checkInvalidEmailAddress("email@email.com-") - checkInvalidEmailAddress("email@email_domain.com") - } - @Test fun `EmailGroup serialize and deserialize transport object should be equal`() { - val sampleEmailGroup = EmailGroup(listOf("email1@email.com", "email2@email.com")) + val sampleEmailGroup = EmailGroup( + listOf( + EmailRecipient("email1@email.com"), + EmailRecipient("email2@email.com") + ) + ) val recreatedObject = recreateObject(sampleEmailGroup) { EmailGroup(it) } assertEquals(sampleEmailGroup, recreatedObject) } @Test fun `EmailGroup serialize and deserialize using json object should be equal`() { - val sampleEmailGroup = EmailGroup(listOf("email1@email.com", "email2@email.com")) + val sampleEmailGroup = EmailGroup( + listOf( + EmailRecipient("email1@email.com"), + EmailRecipient("email2@email.com") + ) + ) val jsonString = getJsonString(sampleEmailGroup) val recreatedObject = createObjectFromJsonString(jsonString) { EmailGroup.parse(it) } assertEquals(sampleEmailGroup, recreatedObject) @@ -94,12 +63,17 @@ internal class EmailGroupTests { @Test fun `EmailGroup should deserialize json object using parser`() { - val sampleEmailGroup = EmailGroup(listOf("email1@email.com", "email2@email.com")) + val sampleEmailGroup = EmailGroup( + listOf( + EmailRecipient("email1@email.com"), + EmailRecipient("email2@email.com") + ) + ) val jsonString = """ { "recipient_list":[ - "${sampleEmailGroup.recipients[0]}", - "${sampleEmailGroup.recipients[1]}" + {"recipient":"${sampleEmailGroup.recipients[0].recipient}"}, + {"recipient":"${sampleEmailGroup.recipients[1].recipient}"} ] }" """.trimIndent() @@ -117,12 +91,17 @@ internal class EmailGroupTests { @Test fun `EmailGroup should throw exception when recipients is replaced with recipients2 in json object`() { - val sampleEmailGroup = EmailGroup(listOf("email1@email.com", "email2@email.com")) + val sampleEmailGroup = EmailGroup( + listOf( + EmailRecipient("email1@email.com"), + EmailRecipient("email2@email.com") + ) + ) val jsonString = """ { "recipient_list2":[ - "${sampleEmailGroup.recipients[0]}", - "${sampleEmailGroup.recipients[1]}" + {"recipient":"${sampleEmailGroup.recipients[0]}"}, + {"recipient":"${sampleEmailGroup.recipients[1]}"} ] }" """.trimIndent() @@ -133,8 +112,17 @@ internal class EmailGroupTests { @Test fun `EmailGroup should safely ignore extra field in json object`() { - val sampleEmailGroup = EmailGroup(listOf("email@email.com")) - val jsonString = "{\"recipient_list\":[\"${sampleEmailGroup.recipients[0]}\"], \"another\":\"field\"}" + val sampleEmailGroup = EmailGroup(listOf(EmailRecipient("email1@email.com"))) + val jsonString = """ + { + "recipient_list":[ + {"recipient":"${sampleEmailGroup.recipients[0].recipient}"} + ], + "extra_field_1":["extra", "value"], + "extra_field_2":{"extra":"value"}, + "extra_field_3":"extra value 3" + }" + """.trimIndent() val recreatedObject = createObjectFromJsonString(jsonString) { EmailGroup.parse(it) } assertEquals(sampleEmailGroup, recreatedObject) } diff --git a/src/test/kotlin/org/opensearch/commons/notifications/model/EmailRecipientTests.kt b/src/test/kotlin/org/opensearch/commons/notifications/model/EmailRecipientTests.kt new file mode 100644 index 00000000..c2f2d36d --- /dev/null +++ b/src/test/kotlin/org/opensearch/commons/notifications/model/EmailRecipientTests.kt @@ -0,0 +1,142 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +/* + * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + * + */ +package org.opensearch.commons.notifications.model + +import com.fasterxml.jackson.core.JsonParseException +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertDoesNotThrow +import org.junit.jupiter.api.assertThrows +import org.opensearch.commons.utils.createObjectFromJsonString +import org.opensearch.commons.utils.getJsonString +import org.opensearch.commons.utils.recreateObject + +internal class EmailRecipientTests { + + private fun checkValidEmailAddress(emailAddress: String) { + assertDoesNotThrow("should accept $emailAddress") { + EmailRecipient(emailAddress) + } + } + + private fun checkInvalidEmailAddress(emailAddress: String) { + assertThrows("Should throw an Exception for invalid email $emailAddress") { + EmailRecipient(emailAddress) + } + } + + @Test + fun `EmailRecipient should accept valid email address`() { + checkValidEmailAddress("email1234@email.com") + checkValidEmailAddress("email+1234@email.com") + checkValidEmailAddress("email-1234@email.com") + checkValidEmailAddress("email_1234@email.com") + checkValidEmailAddress("email.1234@email.com") + checkValidEmailAddress("e.ma_il-1+2@test-email-domain.co.uk") + checkValidEmailAddress("email-.+_=#|@domain.com") + checkValidEmailAddress("e@mail.com") + } + + @Test + fun `EmailRecipient should throw exception for invalid email address`() { + checkInvalidEmailAddress("email") + checkInvalidEmailAddress("email@") + checkInvalidEmailAddress("email@1234@email.com") + checkInvalidEmailAddress(".email@email.com") + checkInvalidEmailAddress("email.@email.com") + checkInvalidEmailAddress("email..1234@email.com") + checkInvalidEmailAddress("email@email..com") + checkInvalidEmailAddress("email@.com") + checkInvalidEmailAddress("email@email.com.") + checkInvalidEmailAddress("email@.email.com") + checkInvalidEmailAddress("email@email.com-") + checkInvalidEmailAddress("email@email_domain.com") + } + + @Test + fun `EmailRecipient serialize and deserialize transport object should be equal`() { + val sampleEmailRecipient = EmailRecipient("email1@email.com") + val recreatedObject = recreateObject(sampleEmailRecipient) { EmailRecipient(it) } + assertEquals(sampleEmailRecipient, recreatedObject) + } + + @Test + fun `EmailRecipient serialize and deserialize using json object should be equal`() { + val sampleEmailRecipient = EmailRecipient("email1@email.com") + val jsonString = getJsonString(sampleEmailRecipient) + val recreatedObject = createObjectFromJsonString(jsonString) { EmailRecipient.parse(it) } + assertEquals(sampleEmailRecipient, recreatedObject) + } + + @Test + fun `EmailRecipient should deserialize json object using parser`() { + val sampleEmailRecipient = EmailRecipient("email1@email.com") + val jsonString = """ + { + "recipient": "${sampleEmailRecipient.recipient}" + }" + """.trimIndent() + val recreatedObject = createObjectFromJsonString(jsonString) { EmailRecipient.parse(it) } + assertEquals(sampleEmailRecipient, recreatedObject) + } + + @Test + fun `EmailRecipient should throw exception when invalid json object is passed`() { + val jsonString = "sample message" + assertThrows { + createObjectFromJsonString(jsonString) { EmailRecipient.parse(it) } + } + } + + @Test + fun `EmailRecipient should throw exception when recipients is replaced with recipients2 in json object`() { + val sampleEmailRecipient = EmailRecipient("email1@email.com") + val jsonString = """ + { + "recipient2": "${sampleEmailRecipient.recipient}" + }" + """.trimIndent() + assertThrows { + createObjectFromJsonString(jsonString) { EmailRecipient.parse(it) } + } + } + + @Test + fun `EmailRecipient should safely ignore extra field in json object`() { + val sampleEmailRecipient = EmailRecipient("email@email.com") + val jsonString = """ + { + "recipient": "${sampleEmailRecipient.recipient}", + "extra_field_1":["extra", "value"], + "extra_field_2":{"extra":"value"}, + "extra_field_3":"extra value 3" + }" + """.trimIndent() + val recreatedObject = createObjectFromJsonString(jsonString) { EmailRecipient.parse(it) } + assertEquals(sampleEmailRecipient, recreatedObject) + } +} diff --git a/src/test/kotlin/org/opensearch/commons/notifications/model/EmailTests.kt b/src/test/kotlin/org/opensearch/commons/notifications/model/EmailTests.kt index 6590f08e..8e4772f5 100644 --- a/src/test/kotlin/org/opensearch/commons/notifications/model/EmailTests.kt +++ b/src/test/kotlin/org/opensearch/commons/notifications/model/EmailTests.kt @@ -29,7 +29,6 @@ package org.opensearch.commons.notifications.model import com.fasterxml.jackson.core.JsonParseException import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertDoesNotThrow import org.junit.jupiter.api.assertThrows import org.opensearch.commons.utils.createObjectFromJsonString import org.opensearch.commons.utils.getJsonString @@ -37,51 +36,14 @@ import org.opensearch.commons.utils.recreateObject internal class EmailTests { - private fun checkValidEmailAddress(emailAddress: String) { - assertDoesNotThrow("should accept $emailAddress") { - Email("sampleId", listOf(emailAddress), listOf()) - } - } - - private fun checkInvalidEmailAddress(emailAddress: String) { - assertThrows("Should throw an Exception for invalid email $emailAddress") { - Email("sampleId", listOf(emailAddress), listOf()) - } - } - - @Test - fun `Email should accept valid email address`() { - checkValidEmailAddress("email1234@email.com") - checkValidEmailAddress("email+1234@email.com") - checkValidEmailAddress("email-1234@email.com") - checkValidEmailAddress("email_1234@email.com") - checkValidEmailAddress("email.1234@email.com") - checkValidEmailAddress("e.ma_il-1+2@test-email-domain.co.uk") - checkValidEmailAddress("email-.+_=#|@domain.com") - checkValidEmailAddress("e@mail.com") - } - - @Test - fun `Email should throw exception for invalid email address`() { - checkInvalidEmailAddress("email") - checkInvalidEmailAddress("email@") - checkInvalidEmailAddress("email@1234@email.com") - checkInvalidEmailAddress(".email@email.com") - checkInvalidEmailAddress("email.@email.com") - checkInvalidEmailAddress("email..1234@email.com") - checkInvalidEmailAddress("email@email..com") - checkInvalidEmailAddress("email@.com") - checkInvalidEmailAddress("email@email.com.") - checkInvalidEmailAddress("email@.email.com") - checkInvalidEmailAddress("email@email.com-") - checkInvalidEmailAddress("email@email_domain.com") - } - @Test fun `Email serialize and deserialize transport object should be equal`() { val sampleEmail = Email( "sampleAccountId", - listOf("email1@email.com", "email2@email.com"), + listOf( + EmailRecipient("email1@email.com"), + EmailRecipient("email2@email.com") + ), listOf("sample_group_id_1", "sample_group_id_2") ) val recreatedObject = recreateObject(sampleEmail) { Email(it) } @@ -92,7 +54,10 @@ internal class EmailTests { fun `Email serialize and deserialize using json object should be equal`() { val sampleEmail = Email( "sampleAccountId", - listOf("email1@email.com", "email2@email.com"), + listOf( + EmailRecipient("email1@email.com"), + EmailRecipient("email2@email.com") + ), listOf("sample_group_id_1", "sample_group_id_2") ) val jsonString = getJsonString(sampleEmail) @@ -104,15 +69,18 @@ internal class EmailTests { fun `Email should deserialize json object using parser`() { val sampleEmail = Email( "sampleAccountId", - listOf("email1@email.com", "email2@email.com"), + listOf( + EmailRecipient("email1@email.com"), + EmailRecipient("email2@email.com") + ), listOf("sample_group_id_1", "sample_group_id_2") ) val jsonString = """ { "email_account_id":"${sampleEmail.emailAccountID}", "recipient_list":[ - "${sampleEmail.recipients[0]}", - "${sampleEmail.recipients[1]}" + {"recipient":"${sampleEmail.recipients[0].recipient}"}, + {"recipient":"${sampleEmail.recipients[1].recipient}"} ], "email_group_id_list":[ "${sampleEmail.emailGroupIds[0]}", @@ -136,15 +104,18 @@ internal class EmailTests { fun `Email should throw exception when emailAccountID is replaced with emailAccountID2 in json object`() { val sampleEmail = Email( "sampleAccountId", - listOf("email1@email.com", "email2@email.com"), + listOf( + EmailRecipient("email1@email.com"), + EmailRecipient("email2@email.com") + ), listOf("sample_group_id_1", "sample_group_id_2") ) val jsonString = """ { "email_account_id2":"${sampleEmail.emailAccountID}", "recipient_list":[ - "${sampleEmail.recipients[0]}", - "${sampleEmail.recipients[1]}" + {"recipient":"${sampleEmail.recipients[0]}"}, + {"recipient":"${sampleEmail.recipients[1]}"} ], "email_group_id_list":[ "${sampleEmail.emailGroupIds[0]}", diff --git a/src/test/kotlin/org/opensearch/commons/notifications/model/NotificationConfigTests.kt b/src/test/kotlin/org/opensearch/commons/notifications/model/NotificationConfigTests.kt index c7126ab0..0a96c8ed 100644 --- a/src/test/kotlin/org/opensearch/commons/notifications/model/NotificationConfigTests.kt +++ b/src/test/kotlin/org/opensearch/commons/notifications/model/NotificationConfigTests.kt @@ -126,7 +126,7 @@ internal class NotificationConfigTests { @Test fun `Config serialize and deserialize with email object should be equal`() { - val sampleEmail = Email("id_1234567890", listOf("email@domain.com"), listOf("groupId")) + val sampleEmail = Email("id_1234567890", listOf(EmailRecipient("email@domain.com")), listOf("groupId")) val sampleConfig = NotificationConfig( "name", "description", @@ -140,7 +140,7 @@ internal class NotificationConfigTests { @Test fun `Config serialize and deserialize with json email object should be equal`() { - val sampleEmail = Email("id_1234567890", listOf("email@domain.com"), listOf("groupId")) + val sampleEmail = Email("id_1234567890", listOf(EmailRecipient("email@domain.com")), listOf("groupId")) val sampleConfig = NotificationConfig( "name", "description", @@ -184,7 +184,7 @@ internal class NotificationConfigTests { @Test fun `Config serialize and deserialize with json emailGroup object should be equal`() { - val sampleEmailGroup = EmailGroup(listOf("email@domain.com")) + val sampleEmailGroup = EmailGroup(listOf(EmailRecipient("email@domain.com"))) val sampleConfig = NotificationConfig( "name", "description", @@ -199,7 +199,7 @@ internal class NotificationConfigTests { @Test fun `Config serialize and deserialize with emailGroup object should be equal`() { - val sampleEmailGroup = EmailGroup(listOf("email@domain.com")) + val sampleEmailGroup = EmailGroup(listOf(EmailRecipient("email@domain.com"))) val sampleConfig = NotificationConfig( "name", "description", diff --git a/src/test/kotlin/org/opensearch/commons/notifications/model/config/ConfigPropertiesTests.kt b/src/test/kotlin/org/opensearch/commons/notifications/model/config/ConfigPropertiesTests.kt index 0217c53f..80a20b88 100644 --- a/src/test/kotlin/org/opensearch/commons/notifications/model/config/ConfigPropertiesTests.kt +++ b/src/test/kotlin/org/opensearch/commons/notifications/model/config/ConfigPropertiesTests.kt @@ -5,6 +5,7 @@ import org.opensearch.commons.notifications.model.Chime import org.opensearch.commons.notifications.model.ConfigType import org.opensearch.commons.notifications.model.Email import org.opensearch.commons.notifications.model.EmailGroup +import org.opensearch.commons.notifications.model.EmailRecipient import org.opensearch.commons.notifications.model.MethodType import org.opensearch.commons.notifications.model.Slack import org.opensearch.commons.notifications.model.SmtpAccount @@ -72,7 +73,7 @@ internal class ConfigPropertiesTests { @Test fun `Validate config data parse EmailGroup`() { - val sampleEmailGroup = EmailGroup(listOf("email1@email.com", "email2@email.com")) + val sampleEmailGroup = EmailGroup(listOf(EmailRecipient("email1@email.com"), EmailRecipient("email2@email.com"))) val jsonString = getJsonString(sampleEmailGroup) val recreatedObject = createObjectFromJsonString(jsonString) { createConfigData(ConfigType.EMAIL_GROUP, it) } assertEquals(sampleEmailGroup, recreatedObject)