From 09dc2f43094a3413baec1aae4f64253fae598c6e Mon Sep 17 00:00:00 2001 From: Nitish-Kulkarni3 Date: Tue, 7 Apr 2026 10:11:57 +0530 Subject: [PATCH] chore: support for sandbox view payload and attachment --- .secrets.baseline | 34 +- README.md | 34 +- .../test_event_notifications_v1_examples.py | 124 +++- .../event_notifications_v1.py | 591 +++++++++++++++++- .../test_event_notifications_v1.py | 162 ++++- test/unit/test_event_notifications_v1.py | 399 +++++++++++- 6 files changed, 1312 insertions(+), 32 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index e08a40b..245cb88 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "^.secrets.baseline$", "lines": null }, - "generated_at": "2026-03-19T14:44:16Z", + "generated_at": "2026-04-07T04:40:35Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -65,6 +65,16 @@ } ], "results": { + "README.md": [ + { + "hashed_secret": "1f994725d7713ba16a295adc7d78dfa0e35a26f3", + "is_secret": false, + "is_verified": false, + "line_number": 1314, + "type": "Base64 High Entropy String", + "verified_result": null + } + ], "event_notifications_v1.env.hide": [ { "hashed_secret": "98103a8f40de455136eef28078548666c9f789e3", @@ -104,7 +114,7 @@ "hashed_secret": "d4c3d66fd0c38547a3c7a4c6bdc29c36911bc030", "is_secret": false, "is_verified": false, - "line_number": 1377, + "line_number": 1396, "type": "Secret Keyword", "verified_result": null }, @@ -112,7 +122,7 @@ "hashed_secret": "3235b7f8d626cde63611d2e9ec43473f4e844c67", "is_secret": false, "is_verified": false, - "line_number": 2523, + "line_number": 2625, "type": "Base64 High Entropy String", "verified_result": null } @@ -122,7 +132,7 @@ "hashed_secret": "d4c3d66fd0c38547a3c7a4c6bdc29c36911bc030", "is_secret": false, "is_verified": false, - "line_number": 628, + "line_number": 634, "type": "Secret Keyword", "verified_result": null }, @@ -130,7 +140,7 @@ "hashed_secret": "0cc20f91828bed53ddb6294968b7f9abd631a3ba", "is_secret": false, "is_verified": false, - "line_number": 1744, + "line_number": 1774, "type": "Secret Keyword", "verified_result": null }, @@ -138,7 +148,15 @@ "hashed_secret": "3235b7f8d626cde63611d2e9ec43473f4e844c67", "is_secret": false, "is_verified": false, - "line_number": 3711, + "line_number": 3849, + "type": "Base64 High Entropy String", + "verified_result": null + }, + { + "hashed_secret": "1f994725d7713ba16a295adc7d78dfa0e35a26f3", + "is_secret": false, + "is_verified": false, + "line_number": 3854, "type": "Base64 High Entropy String", "verified_result": null } @@ -148,7 +166,7 @@ "hashed_secret": "7eeef8638d6f283c8d76d7811ec6e5f198e16021", "is_secret": false, "is_verified": false, - "line_number": 7928, + "line_number": 8069, "type": "Base64 High Entropy String", "verified_result": null }, @@ -156,7 +174,7 @@ "hashed_secret": "b8473b86d4c2072ca9b08bd28e373e8253e865c4", "is_secret": false, "is_verified": false, - "line_number": 10935, + "line_number": 11162, "type": "Secret Keyword", "verified_result": null } diff --git a/README.md b/README.md index 6d3c499..af72ea4 100644 --- a/README.md +++ b/README.md @@ -168,12 +168,20 @@ source_response = event_notifications_service.create_sources( , # Event notifications service instance GUID name=, description=, - enabled=False + enabled=False, + store_notifications=True # Optional: Enable to view payload of incoming events for troubleshooting ).get_result() print(json.dumps(source_response, indent=2)) ``` +**Parameters:** +- `instance_id` (required): Event Notifications service instance GUID +- `name` (required): Name of the source +- `description` (required): Description of the source +- `enabled` (optional): Whether the source is enabled or not (default: False) +- `store_notifications` (optional): Enable to view the payload of incoming events for troubleshooting (default: False) + ### List Sources ```py @@ -364,6 +372,7 @@ Among the supported destinations, if you need to create Push Notification destin Set `pre_prod` boolean parameter to _true_ to configure destination as pre-production destination else set the value as _false_. Supported destinations are Android, iOS, Chrome, Firefox, and Safari. +**Note:** The `smtp_custom_sandbox` destination type is available for testing purposes in sandbox environments. It works similarly to `smtp_custom` but is intended for development and testing scenarios. Refer to https://cloud.ibm.com/apidocs/event-notifications#create-destination for examples. ### List Destinations ```py @@ -1300,6 +1309,23 @@ mms = '{"content": "akajdklahl", "content_type": "image/png"}' templates = '["149b0e11-8a7c-4fda-a847-5d79e01b71dc"]' markdown_content = "**Event Summary** \n\n**Toolchain ID:** `4414af34-a5c7-47d3-8f05-add4af6d78a6` \n**Content Type:** `application/json`\n\n---\n\n *Pipeline Run Details*\n\n- **Namespace:** `PR`\n- **Trigger Name:** `manual`\n- **Triggered By:** `nitish.kulkarni3@ibm.com`\n- **Build Number:** `343`\n- **Pipeline Link:** [View Pipeline Run](https://cloud.ibm.com/devops/pipelines/tekton/e9cd5aa3-a3f2-4776-8acc-26a35922386e/runs/f29ac6f5-bd2f-4a26-abb8-4249be8dbab7?env_id=ibm:yp:us-south)" +# Email attachments (optional) +email_attachment_1 = { + 'content': 'VGhpcyBpcyBhIHRlc3QgYXR0YWNobWVudCBjb250ZW50', # Base64 encoded content + 'filename': 'report.txt', + 'content_type': 'text/plain', + 'disposition': 'attachment' +} + +email_attachment_2 = { + 'content': 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==', + 'filename': 'image.png', + 'content_type': 'image/png', + 'disposition': 'attachment' +} + +email_attachments = [email_attachment_1, email_attachment_2] + notification_create_model = { 'ibmenseverity': notification_severity, 'ibmenfcmbody': json.dumps(notification_fcm_body_model), @@ -1317,6 +1343,7 @@ notification_create_model = { 'ibmenslackto': slackto, 'ibmenmms': mms, "ibmentemplates": templates, + 'attachments': email_attachments, # Add email attachments 'id': notification_id, 'source': notifications_source, 'type': type_value, @@ -1376,6 +1403,11 @@ send_notifications_response = event_notifications_service.send_notifications( - **ibmenslackto** (_Array of string_) - Array of Slack channel/member ids to which the notification to be sent. - **ibmentemplates** (_Array of string_) - Array of template IDs that needs to be applied while sending notificatin for custom domain email and slack destination. - **ibmenmarkdown** (_string_) - The markdown content of pretty formatting. + - **attachments** (_Array of EmailAttachment objects_) - Array of email attachments to be sent with the notification. Each attachment object contains: + - **content** (_string_) - Base64 encoded file content. + - **filename** (_string_) - Name of the attachment file. + - **content_type** (_string_) - MIME type of the attachment (e.g., 'text/plain', 'application/pdf', 'image/png'). + - **disposition** (_string_) - Content disposition, 'attachment'. Note: variable with \* represents the mandatory attribute. diff --git a/examples/test_event_notifications_v1_examples.py b/examples/test_event_notifications_v1_examples.py index 310e1b9..b1aeca3 100644 --- a/examples/test_event_notifications_v1_examples.py +++ b/examples/test_event_notifications_v1_examples.py @@ -69,6 +69,7 @@ destination_id19 = "" destination_id20 = "" destination_id22 = "" +destination_id_sandbox = "" safariCertificatePath = "" subscription_id = "" subscription_id1 = "" @@ -82,6 +83,7 @@ subscription_id9 = "" subscription_id10 = "" subscription_id22 = "" +subscription_id_sandbox = "" fcmServerKey = "" fcmSenderId = "" integration_id = "" @@ -239,6 +241,7 @@ def test_create_sources_example(self): name="Event Notification Create Source Acme", description="This source is used for Acme Bank", enabled=False, + store_notifications=True, ).get_result() print(json.dumps(source_response, indent=2)) @@ -429,7 +432,7 @@ def test_create_destination_example(self): """ create_destination request example """ - global destination_id, destination_id3, destination_id4, destination_id5, destination_id6, destination_id8, destination_id9, destination_id10, destination_id11, destination_id12, destination_id13, destination_id14, destination_id15, destination_id16, destination_id17, destination_id18, destination_id19, destination_id20, destination_id22 + global destination_id, destination_id3, destination_id4, destination_id5, destination_id6, destination_id8, destination_id9, destination_id10, destination_id11, destination_id12, destination_id13, destination_id14, destination_id15, destination_id16, destination_id17, destination_id18, destination_id19, destination_id20, destination_id_sandbox, destination_id22 try: print("\ncreate_destination() result:") # begin-create_destination @@ -904,6 +907,21 @@ def test_create_destination_example(self): destination = DestinationResponse.from_dict(destination_response) destination_id22 = destination.id + name = "custom_email_sandbox_destination" + typeval = "smtp_custom_sandbox" + description = "Custom Email Sandbox Destination" + + create_destination_response = self.event_notifications_service.create_destination( + instance_id, + name, + type=typeval, + description=description, + ) + + destination_response = create_destination_response.get_result() + destination: DestinationResponse = DestinationResponse.from_dict(destination_response) + destination_id_sandbox = destination.id + # end-create_destination except ApiException as e: @@ -1667,11 +1685,47 @@ def test_update_destination_example(self): print(json.dumps(update_destination_response, indent=2)) + name = "custom_email_sandbox_destination_update" + description = "Custom Email Sandbox Destination update" + + update_destination_response = self.event_notifications_service.update_destination( + instance_id, + id=destination_id_sandbox, + name=name, + description=description, + ).get_result() + + print(json.dumps(update_destination_response, indent=2)) + # end-update_destination except ApiException as e: pytest.fail(str(e)) + @needscredentials + def test_upgrade_sandbox_destination_example(self): + """ + upgrade_sandbox_destination request example + """ + try: + print("\nupgrade_sandbox_destination() result:") + # begin-upgrade_sandbox_destination + + domain = "mailx.event-notifications.test.cloud.ibm.com" + + upgrade_response = self.event_notifications_service.update_email_sandbox_destination( + instance_id, + id=destination_id_sandbox, + domain=domain, + ).get_result() + + print(json.dumps(upgrade_response, indent=2)) + + # end-upgrade_sandbox_destination + + except ApiException as e: + pytest.fail(str(e)) + @needscredentials def test_update_template_example(self): """ @@ -1853,7 +1907,7 @@ def test_create_subscription_example(self): """ create_subscription request example """ - global subscription_id, subscription_id1, subscription_id2, subscription_id3, subscription_id4, subscription_id5, subscription_id6, subscription_id7, subscription_id8, subscription_id9, subscription_id10, subscription_id22 + global subscription_id, subscription_id1, subscription_id2, subscription_id3, subscription_id4, subscription_id5, subscription_id6, subscription_id7, subscription_id8, subscription_id9, subscription_id10, subscription_id_sandbox, subscription_id22 try: print("\ncreate_subscription() result:") # begin-create_subscription @@ -2114,6 +2168,27 @@ def test_create_subscription_example(self): subscription_response = create_subscription_response.get_result() subscription_id22 = subscription_response.get("id") + subscription_create_attributes_model = { + "invited": ["testuser@in.ibm.com"], + "add_notification_payload": True, + "reply_to_mail": "reply_to_mail@us.com", + "reply_to_name": "US News", + } + + name = "subscription_custom_email_sandbox" + description = "Subscription for custom email sandbox" + create_subscription_response = self.event_notifications_service.create_subscription( + instance_id, + name, + destination_id=destination_id_sandbox, + topic_id=topic_id, + attributes=subscription_create_attributes_model, + description=description, + ) + + subscription_response = create_subscription_response.get_result() + subscription_id_sandbox = subscription_response.get("id") + except ApiException as e: pytest.fail(str(e)) @@ -2427,6 +2502,32 @@ def test_update_subscription_example(self): subscription_response = update_subscription_response.get_result() print(json.dumps(subscription_response, indent=2)) + custom_email_sandbox_update_attributes_invite_model = {"add": ["tester5@ibm.com"]} + + custom_email_sandbox_update_attributes_to_remove_model = {"remove": ["testuser@in.ibm.com"]} + + subscription_update_attributes_model = { + "invited": custom_email_sandbox_update_attributes_invite_model, + "add_notification_payload": True, + "reply_to_mail": "reply_to_mail@us.com", + "reply_to_name": "US News", + "subscribed": custom_email_sandbox_update_attributes_to_remove_model, + "unsubscribed": custom_email_sandbox_update_attributes_to_remove_model, + } + + name = "subscription_custom_email_sandbox update" + description = "Subscription for custom email sandbox updated" + update_subscription_response = self.event_notifications_service.update_subscription( + instance_id, + id=subscription_id_sandbox, + name=name, + description=description, + attributes=subscription_update_attributes_model, + ) + + subscription_response = update_subscription_response.get_result() + print(json.dumps(subscription_response, indent=2)) + # end-update_subscription except ApiException as e: pytest.fail(str(e)) @@ -2524,6 +2625,22 @@ def test_send_notifications_example(self): templates = '["149b0e11-8a7c-4fda-a847-5d79e01b71dc"]' markdown_content = "**Event Summary** \n\n**Toolchain ID:** `4414af34-a5c7-47d3-8f05-add4af6d78a6` \n**Content Type:** `application/json`\n\n---\n\n *Pipeline Run Details*\n\n- **Namespace:** `PR`\n- **Trigger Name:** `manual`\n- **Triggered By:** `nitish.kulkarni3@ibm.com`\n- **Build Number:** `343`\n- **Pipeline Link:** [View Pipeline Run](https://cloud.ibm.com/devops/pipelines/tekton/e9cd5aa3-a3f2-4776-8acc-26a35922386e/runs/f29ac6f5-bd2f-4a26-abb8-4249be8dbab7?env_id=ibm:yp:us-south)" + email_attachment_model = { + 'content': 'VGhpcyBpcyBhIHRlc3QgZmlsZSBjb250ZW50', # Base64 encoded "This is a test file content" + 'filename': 'test_document.txt', + 'content_type': 'text/plain', + 'disposition': 'attachment', + } + + email_attachment_model_2 = { + 'content': 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==', # Base64 encoded 1x1 pixel PNG + 'filename': 'test_image.png', + 'content_type': 'image/png', + 'disposition': 'attachment', + } + + email_attachments = [email_attachment_model, email_attachment_model_2] + notification_create_model = { "ibmenseverity": notification_severity, "ibmenfcmbody": json.dumps(notification_fcm_body_model), @@ -2542,6 +2659,7 @@ def test_send_notifications_example(self): "ibmenslackto": slackto, "ibmenmms": mms, "ibmentemplates": templates, + "attachments": email_attachments, "id": notification_id, "source": notifications_source, "type": type_value, @@ -2929,6 +3047,7 @@ def test_delete_subscription_example(self): subscription_id9, subscription_id10, subscription_id22, + subscription_id_sandbox, ]: delete_subscription_response = event_notifications_service.delete_subscription(instance_id, id) print( @@ -2990,6 +3109,7 @@ def test_delete_destination_example(self): destination_id19, destination_id20, destination_id22, + destination_id_sandbox, ]: delete_destination_response = event_notifications_service.delete_destination(instance_id, id) print( diff --git a/ibm_eventnotifications/event_notifications_v1.py b/ibm_eventnotifications/event_notifications_v1.py index 661d47c..40e380e 100644 --- a/ibm_eventnotifications/event_notifications_v1.py +++ b/ibm_eventnotifications/event_notifications_v1.py @@ -322,6 +322,7 @@ def create_sources( description: str, *, enabled: bool = None, + store_notifications: bool = None, **kwargs, ) -> DetailedResponse: """ @@ -334,6 +335,8 @@ def create_sources( :param str name: Name of the source. :param str description: Description of the source. :param bool enabled: (optional) Whether the source is enabled or not. + :param bool store_notifications: (optional) enable to view the payload of + incoming events for troubleshooting. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. :rtype: DetailedResponse with `dict` result representing a `SourceResponse` object @@ -357,6 +360,7 @@ def create_sources( 'name': name, 'description': description, 'enabled': enabled, + 'store_notifications': store_notifications, } data = {k: v for (k, v) in data.items() if v is not None} data = json.dumps(data) @@ -545,6 +549,7 @@ def update_source( name: str = None, description: str = None, enabled: bool = None, + store_notifications: bool = None, **kwargs, ) -> DetailedResponse: """ @@ -558,6 +563,8 @@ def update_source( :param str name: (optional) Name of the source. :param str description: (optional) Description of the source. :param bool enabled: (optional) Whether the source is enabled or not. + :param bool store_notifications: (optional) enable to view the payload of + incoming events for troubleshooting. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. :rtype: DetailedResponse with `dict` result representing a `Source` object @@ -579,6 +586,7 @@ def update_source( 'name': name, 'description': description, 'enabled': enabled, + 'store_notifications': store_notifications, } data = {k: v for (k, v) in data.items() if v is not None} data = json.dumps(data) @@ -1846,6 +1854,67 @@ def test_destination( response = self.send(request, **kwargs) return response + def update_email_sandbox_destination( + self, + instance_id: str, + id: str, + domain: str, + **kwargs, + ) -> DetailedResponse: + """ + Upgrade sandbox destination to production. + + Upgrade sandbox destination to production with custom domain. + + :param str instance_id: Unique identifier for IBM Cloud Event Notifications + instance. + :param str id: Unique identifier for Destination. + :param str domain: Email Domain. + :param dict headers: A `dict` containing the request headers + :return: A `DetailedResponse` containing the result, headers and HTTP status code. + :rtype: DetailedResponse with `dict` result representing a `DestinationResponse` object + """ + + if not instance_id: + raise ValueError('instance_id must be provided') + if not id: + raise ValueError('id must be provided') + if domain is None: + raise ValueError('domain must be provided') + headers = {} + sdk_headers = get_sdk_headers( + service_name=self.DEFAULT_SERVICE_NAME, + service_version='V1', + operation_id='update_email_sandbox_destination', + ) + headers.update(sdk_headers) + + data = { + 'domain': domain, + } + data = {k: v for (k, v) in data.items() if v is not None} + data = json.dumps(data) + headers['content-type'] = 'application/json' + + if 'headers' in kwargs: + headers.update(kwargs.get('headers')) + del kwargs['headers'] + headers['Accept'] = 'application/json' + + path_param_keys = ['instance_id', 'id'] + path_param_values = self.encode_path_vars(instance_id, id) + path_param_dict = dict(zip(path_param_keys, path_param_values)) + url = '/v1/instances/{instance_id}/destinations/{id}/upgrade'.format(**path_param_dict) + request = self.prepare_request( + method='PATCH', + url=url, + headers=headers, + data=data, + ) + + response = self.send(request, **kwargs) + return response + def update_verify_destination( self, instance_id: str, @@ -3453,6 +3522,7 @@ class Type(str, Enum): IBMCOS = 'ibmcos' PUSH_HUAWEI = 'push_huawei' SMTP_CUSTOM = 'smtp_custom' + SMTP_CUSTOM_SANDBOX = 'smtp_custom_sandbox' SMS_CUSTOM = 'sms_custom' EVENT_STREAMS = 'event_streams' APP_CONFIGURATION = 'app_configuration' @@ -4104,6 +4174,7 @@ class TypeEnum(str, Enum): IBMCOS = 'ibmcos' PUSH_HUAWEI = 'push_huawei' SMTP_CUSTOM = 'smtp_custom' + SMTP_CUSTOM_SANDBOX = 'smtp_custom_sandbox' SMS_CUSTOM = 'sms_custom' EVENT_STREAMS = 'event_streams' APP_CONFIGURATION = 'app_configuration' @@ -4188,6 +4259,7 @@ def __init__( ", ".join( [ 'DestinationConfigOneOfCustomDomainEmailDestinationConfig', + 'DestinationConfigOneOfCustomEmailSandboxDestinationConfig', 'DestinationConfigOneOfWebhookDestinationConfig', 'DestinationConfigOneOfCodeEngineDestinationConfig', 'DestinationConfigOneOfFCMDestinationConfig', @@ -4488,6 +4560,7 @@ class TypeEnum(str, Enum): IBMCOS = 'ibmcos' PUSH_HUAWEI = 'push_huawei' SMTP_CUSTOM = 'smtp_custom' + SMTP_CUSTOM_SANDBOX = 'smtp_custom_sandbox' SMS_CUSTOM = 'sms_custom' EVENT_STREAMS = 'event_streams' APP_CONFIGURATION = 'app_configuration' @@ -4635,6 +4708,7 @@ class TypeEnum(str, Enum): IBMCOS = 'ibmcos' PUSH_HUAWEI = 'push_huawei' SMTP_CUSTOM = 'smtp_custom' + SMTP_CUSTOM_SANDBOX = 'smtp_custom_sandbox' SMS_CUSTOM = 'sms_custom' EVENT_STREAMS = 'event_streams' APP_CONFIGURATION = 'app_configuration' @@ -4797,6 +4871,102 @@ def __ne__(self, other: 'ENAuthAttributes') -> bool: return not self == other +class EmailAttachment: + """ + Email attachment object. + + :attr str content: Base64 encoded file content. + :attr str filename: Name of the attachment file. + :attr str content_type: MIME type of the attachment. + :attr str disposition: Content disposition. + """ + + def __init__( + self, + content: str, + filename: str, + content_type: str, + disposition: str, + ) -> None: + """ + Initialize a EmailAttachment object. + + :param str content: Base64 encoded file content. + :param str filename: Name of the attachment file. + :param str content_type: MIME type of the attachment. + :param str disposition: Content disposition. + """ + self.content = content + self.filename = filename + self.content_type = content_type + self.disposition = disposition + + @classmethod + def from_dict(cls, _dict: Dict) -> 'EmailAttachment': + """Initialize a EmailAttachment object from a json dictionary.""" + args = {} + if 'content' in _dict: + args['content'] = _dict.get('content') + else: + raise ValueError('Required property \'content\' not present in EmailAttachment JSON') + if 'filename' in _dict: + args['filename'] = _dict.get('filename') + else: + raise ValueError('Required property \'filename\' not present in EmailAttachment JSON') + if 'content_type' in _dict: + args['content_type'] = _dict.get('content_type') + else: + raise ValueError('Required property \'content_type\' not present in EmailAttachment JSON') + if 'disposition' in _dict: + args['disposition'] = _dict.get('disposition') + else: + raise ValueError('Required property \'disposition\' not present in EmailAttachment JSON') + return cls(**args) + + @classmethod + def _from_dict(cls, _dict): + """Initialize a EmailAttachment object from a json dictionary.""" + return cls.from_dict(_dict) + + def to_dict(self) -> Dict: + """Return a json dictionary representing this model.""" + _dict = {} + if hasattr(self, 'content') and self.content is not None: + _dict['content'] = self.content + if hasattr(self, 'filename') and self.filename is not None: + _dict['filename'] = self.filename + if hasattr(self, 'content_type') and self.content_type is not None: + _dict['content_type'] = self.content_type + if hasattr(self, 'disposition') and self.disposition is not None: + _dict['disposition'] = self.disposition + return _dict + + def _to_dict(self): + """Return a json dictionary representing this model.""" + return self.to_dict() + + def __str__(self) -> str: + """Return a `str` version of this EmailAttachment object.""" + return json.dumps(self.to_dict(), indent=2) + + def __eq__(self, other: 'EmailAttachment') -> bool: + """Return `true` when self and other are equal, false otherwise.""" + if not isinstance(other, self.__class__): + return False + return self.__dict__ == other.__dict__ + + def __ne__(self, other: 'EmailAttachment') -> bool: + """Return `true` when self and other are not equal, false otherwise.""" + return not self == other + + class DispositionEnum(str, Enum): + """ + Content disposition. + """ + + ATTACHMENT = 'attachment' + + class EmailAttributesResponseInvitedItems: """ EmailAttributesResponseInvitedItems. @@ -5605,8 +5775,8 @@ class IntegrationGetResponse: Integration response object. :attr str id: ID of the integration. - :attr str type: Integration type. Allowed values are kms and hs-crypto - (deprecated) and collect_failed_events. + :attr str type: Integration type. Allowed values are kms, hs-crypto (deprecated) + and collect_failed_events. :attr IntegrationMetadata metadata: Integration Metadata object. :attr datetime created_at: Creation time of an integration. :attr datetime updated_at: Last update time of an integration. @@ -5624,7 +5794,7 @@ def __init__( Initialize a IntegrationGetResponse object. :param str id: ID of the integration. - :param str type: Integration type. Allowed values are kms and hs-crypto + :param str type: Integration type. Allowed values are kms, hs-crypto (deprecated) and collect_failed_events. :param IntegrationMetadata metadata: Integration Metadata object. :param datetime created_at: Creation time of an integration. @@ -6224,6 +6394,8 @@ class NotificationCreate: body. Value should be stringified. :attr str ibmensafaribody: (optional) Payload describing a notification Safari body. Value should be stringified. + :attr List[EmailAttachment] attachments: (optional) Email attachments to be sent + with the notification. """ # The set of defined properties for the class @@ -6260,6 +6432,7 @@ class NotificationCreate: 'ibmenfirefoxheaders', 'ibmenhuaweibody', 'ibmensafaribody', + 'attachments', ] ) @@ -6297,6 +6470,7 @@ def __init__( ibmenfirefoxheaders: str = None, ibmenhuaweibody: str = None, ibmensafaribody: str = None, + attachments: List['EmailAttachment'] = None, **kwargs, ) -> None: """ @@ -6345,6 +6519,8 @@ def __init__( Huawei body. Value should be stringified. :param str ibmensafaribody: (optional) Payload describing a notification Safari body. Value should be stringified. + :param List[EmailAttachment] attachments: (optional) Email attachments to + be sent with the notification. :param **kwargs: (optional) Any additional properties. """ self.specversion = specversion @@ -6378,6 +6554,7 @@ def __init__( self.ibmenfirefoxheaders = ibmenfirefoxheaders self.ibmenhuaweibody = ibmenhuaweibody self.ibmensafaribody = ibmensafaribody + self.attachments = attachments for _key, _value in kwargs.items(): setattr(self, _key, _value) @@ -6461,6 +6638,8 @@ def from_dict(cls, _dict: Dict) -> 'NotificationCreate': args['ibmenhuaweibody'] = _dict.get('ibmenhuaweibody') if 'ibmensafaribody' in _dict: args['ibmensafaribody'] = _dict.get('ibmensafaribody') + if 'attachments' in _dict: + args['attachments'] = [EmailAttachment.from_dict(v) for v in _dict.get('attachments')] args.update({k: v for (k, v) in _dict.items() if k not in cls._properties}) return cls(**args) @@ -6534,6 +6713,14 @@ def to_dict(self) -> Dict: _dict['ibmenhuaweibody'] = self.ibmenhuaweibody if hasattr(self, 'ibmensafaribody') and self.ibmensafaribody is not None: _dict['ibmensafaribody'] = self.ibmensafaribody + if hasattr(self, 'attachments') and self.attachments is not None: + attachments_list = [] + for v in self.attachments: + if isinstance(v, dict): + attachments_list.append(v) + else: + attachments_list.append(v.to_dict()) + _dict['attachments'] = attachments_list for _key in [k for k in vars(self).keys() if k not in NotificationCreate._properties]: _dict[_key] = getattr(self, _key) return _dict @@ -6579,19 +6766,25 @@ class NotificationResponse: Payload describing a notifications response. :attr str notification_id: (optional) Notification ID. + :attr List[EmailAttachment] attachments: (optional) Email attachments that were + sent with the notification. """ def __init__( self, *, notification_id: str = None, + attachments: List['EmailAttachment'] = None, ) -> None: """ Initialize a NotificationResponse object. :param str notification_id: (optional) Notification ID. + :param List[EmailAttachment] attachments: (optional) Email attachments that + were sent with the notification. """ self.notification_id = notification_id + self.attachments = attachments @classmethod def from_dict(cls, _dict: Dict) -> 'NotificationResponse': @@ -6599,6 +6792,8 @@ def from_dict(cls, _dict: Dict) -> 'NotificationResponse': args = {} if 'notification_id' in _dict: args['notification_id'] = _dict.get('notification_id') + if 'attachments' in _dict: + args['attachments'] = [EmailAttachment.from_dict(v) for v in _dict.get('attachments')] return cls(**args) @classmethod @@ -6611,6 +6806,14 @@ def to_dict(self) -> Dict: _dict = {} if hasattr(self, 'notification_id') and self.notification_id is not None: _dict['notification_id'] = self.notification_id + if hasattr(self, 'attachments') and self.attachments is not None: + attachments_list = [] + for v in self.attachments: + if isinstance(v, dict): + attachments_list.append(v) + else: + attachments_list.append(v.to_dict()) + _dict['attachments'] = attachments_list return _dict def _to_dict(self): @@ -8556,6 +8759,8 @@ class Source: :attr str name: The name of the source. :attr str description: The description of the source. :attr bool enabled: The status of the source. + :attr bool store_notifications: (optional) view the payload of incoming events + for troubleshooting. :attr str type: Type of the source. :attr datetime updated_at: The last updated time of the source. :attr int topic_count: The number of topics. @@ -8572,6 +8777,8 @@ def __init__( updated_at: datetime, topic_count: int, topic_names: List[str], + *, + store_notifications: bool = None, ) -> None: """ Initialize a Source object. @@ -8584,11 +8791,14 @@ def __init__( :param datetime updated_at: The last updated time of the source. :param int topic_count: The number of topics. :param List[str] topic_names: The names of the topics. + :param bool store_notifications: (optional) view the payload of incoming + events for troubleshooting. """ self.id = id self.name = name self.description = description self.enabled = enabled + self.store_notifications = store_notifications self.type = type self.updated_at = updated_at self.topic_count = topic_count @@ -8614,6 +8824,8 @@ def from_dict(cls, _dict: Dict) -> 'Source': args['enabled'] = _dict.get('enabled') else: raise ValueError('Required property \'enabled\' not present in Source JSON') + if 'store_notifications' in _dict: + args['store_notifications'] = _dict.get('store_notifications') if 'type' in _dict: args['type'] = _dict.get('type') else: @@ -8648,6 +8860,8 @@ def to_dict(self) -> Dict: _dict['description'] = self.description if hasattr(self, 'enabled') and self.enabled is not None: _dict['enabled'] = self.enabled + if hasattr(self, 'store_notifications') and self.store_notifications is not None: + _dict['store_notifications'] = self.store_notifications if hasattr(self, 'type') and self.type is not None: _dict['type'] = self.type if hasattr(self, 'updated_at') and self.updated_at is not None: @@ -8816,6 +9030,8 @@ class SourceListItem: :attr str description: Description of the source. :attr str type: Type of the source. :attr bool enabled: Whether the source is enabled or not. + :attr bool store_notifications: (optional) view the payload of incoming events + for troubleshooting. :attr datetime updated_at: Time of the last update. :attr int topic_count: Number of topics. """ @@ -8829,6 +9045,8 @@ def __init__( enabled: bool, updated_at: datetime, topic_count: int, + *, + store_notifications: bool = None, ) -> None: """ Initialize a SourceListItem object. @@ -8840,12 +9058,15 @@ def __init__( :param bool enabled: Whether the source is enabled or not. :param datetime updated_at: Time of the last update. :param int topic_count: Number of topics. + :param bool store_notifications: (optional) view the payload of incoming + events for troubleshooting. """ self.id = id self.name = name self.description = description self.type = type self.enabled = enabled + self.store_notifications = store_notifications self.updated_at = updated_at self.topic_count = topic_count @@ -8873,6 +9094,8 @@ def from_dict(cls, _dict: Dict) -> 'SourceListItem': args['enabled'] = _dict.get('enabled') else: raise ValueError('Required property \'enabled\' not present in SourceListItem JSON') + if 'store_notifications' in _dict: + args['store_notifications'] = _dict.get('store_notifications') if 'updated_at' in _dict: args['updated_at'] = string_to_datetime(_dict.get('updated_at')) else: @@ -8901,6 +9124,8 @@ def to_dict(self) -> Dict: _dict['type'] = self.type if hasattr(self, 'enabled') and self.enabled is not None: _dict['enabled'] = self.enabled + if hasattr(self, 'store_notifications') and self.store_notifications is not None: + _dict['store_notifications'] = self.store_notifications if hasattr(self, 'updated_at') and self.updated_at is not None: _dict['updated_at'] = datetime_to_string(self.updated_at) if hasattr(self, 'topic_count') and self.topic_count is not None: @@ -8934,6 +9159,8 @@ class SourceResponse: :attr str name: Name of the source. :attr str description: Description of the source. :attr bool enabled: Whether the source is enabled or not. + :attr bool store_notifications: (optional) view the payload of incoming events + for troubleshooting. :attr datetime created_at: Time of the created. """ @@ -8944,6 +9171,8 @@ def __init__( description: str, enabled: bool, created_at: datetime, + *, + store_notifications: bool = None, ) -> None: """ Initialize a SourceResponse object. @@ -8953,11 +9182,14 @@ def __init__( :param str description: Description of the source. :param bool enabled: Whether the source is enabled or not. :param datetime created_at: Time of the created. + :param bool store_notifications: (optional) view the payload of incoming + events for troubleshooting. """ self.id = id self.name = name self.description = description self.enabled = enabled + self.store_notifications = store_notifications self.created_at = created_at @classmethod @@ -8980,6 +9212,8 @@ def from_dict(cls, _dict: Dict) -> 'SourceResponse': args['enabled'] = _dict.get('enabled') else: raise ValueError('Required property \'enabled\' not present in SourceResponse JSON') + if 'store_notifications' in _dict: + args['store_notifications'] = _dict.get('store_notifications') if 'created_at' in _dict: args['created_at'] = string_to_datetime(_dict.get('created_at')) else: @@ -9002,6 +9236,8 @@ def to_dict(self) -> Dict: _dict['description'] = self.description if hasattr(self, 'enabled') and self.enabled is not None: _dict['enabled'] = self.enabled + if hasattr(self, 'store_notifications') and self.store_notifications is not None: + _dict['store_notifications'] = self.store_notifications if hasattr(self, 'created_at') and self.created_at is not None: _dict['created_at'] = datetime_to_string(self.created_at) return _dict @@ -9407,6 +9643,7 @@ class DestinationTypeEnum(str, Enum): IBMCOS = 'ibmcos' PUSH_HUAWEI = 'push_huawei' SMTP_CUSTOM = 'smtp_custom' + SMTP_CUSTOM_SANDBOX = 'smtp_custom_sandbox' SMS_CUSTOM = 'sms_custom' EVENT_STREAMS = 'event_streams' APP_CONFIGURATION = 'app_configuration' @@ -9468,6 +9705,7 @@ def __init__( 'SubscriptionCreateAttributesEmailAttributes', 'SubscriptionCreateAttributesCustomSMSAttributes', 'SubscriptionCreateAttributesCustomEmailAttributes', + 'SubscriptionCreateAttributesCustomEmailSandboxAttributes', 'SubscriptionCreateAttributesWebhookAttributes', 'SubscriptionCreateAttributesFCMAttributes', 'SubscriptionCreateAttributesSlackAttributes', @@ -9794,6 +10032,7 @@ def __init__( 'SubscriptionUpdateAttributesEmailUpdateAttributes', 'SubscriptionUpdateAttributesCustomSMSUpdateAttributes', 'SubscriptionUpdateAttributesCustomEmailUpdateAttributes', + 'SubscriptionUpdateAttributesCustomEmailSandboxUpdateAttributes', 'SubscriptionUpdateAttributesWebhookAttributes', 'SubscriptionUpdateAttributesSlackAttributes', 'SubscriptionUpdateAttributesPagerDutyAttributes', @@ -11589,6 +11828,87 @@ def __ne__(self, other: 'DestinationConfigOneOfCustomDomainEmailDestinationConfi return not self == other +class DestinationConfigOneOfCustomEmailSandboxDestinationConfig(DestinationConfigOneOf): + """ + Payload describing a custom Email Sandbox destination configuration. + + :attr str domain: (optional) Email Domain. + :attr DKIMAttributes dkim: (optional) The DKIM attributes. + :attr SPFAttributes spf: (optional) The SPF attributes. + """ + + def __init__( + self, + *, + domain: str = None, + dkim: 'DKIMAttributes' = None, + spf: 'SPFAttributes' = None, + ) -> None: + """ + Initialize a DestinationConfigOneOfCustomEmailSandboxDestinationConfig object. + + :param str domain: (optional) Email Domain. + :param DKIMAttributes dkim: (optional) The DKIM attributes. + :param SPFAttributes spf: (optional) The SPF attributes. + """ + # pylint: disable=super-init-not-called + self.domain = domain + self.dkim = dkim + self.spf = spf + + @classmethod + def from_dict(cls, _dict: Dict) -> 'DestinationConfigOneOfCustomEmailSandboxDestinationConfig': + """Initialize a DestinationConfigOneOfCustomEmailSandboxDestinationConfig object from a json dictionary.""" + args = {} + if 'domain' in _dict: + args['domain'] = _dict.get('domain') + if 'dkim' in _dict: + args['dkim'] = DKIMAttributes.from_dict(_dict.get('dkim')) + if 'spf' in _dict: + args['spf'] = SPFAttributes.from_dict(_dict.get('spf')) + return cls(**args) + + @classmethod + def _from_dict(cls, _dict): + """Initialize a DestinationConfigOneOfCustomEmailSandboxDestinationConfig object from a json dictionary.""" + return cls.from_dict(_dict) + + def to_dict(self) -> Dict: + """Return a json dictionary representing this model.""" + _dict = {} + if hasattr(self, 'domain') and self.domain is not None: + _dict['domain'] = self.domain + if hasattr(self, 'dkim') and self.dkim is not None: + if isinstance(self.dkim, dict): + _dict['dkim'] = self.dkim + else: + _dict['dkim'] = self.dkim.to_dict() + if hasattr(self, 'spf') and self.spf is not None: + if isinstance(self.spf, dict): + _dict['spf'] = self.spf + else: + _dict['spf'] = self.spf.to_dict() + return _dict + + def _to_dict(self): + """Return a json dictionary representing this model.""" + return self.to_dict() + + def __str__(self) -> str: + """Return a `str` version of this DestinationConfigOneOfCustomEmailSandboxDestinationConfig object.""" + return json.dumps(self.to_dict(), indent=2) + + def __eq__(self, other: 'DestinationConfigOneOfCustomEmailSandboxDestinationConfig') -> bool: + """Return `true` when self and other are equal, false otherwise.""" + if not isinstance(other, self.__class__): + return False + return self.__dict__ == other.__dict__ + + def __ne__(self, other: 'DestinationConfigOneOfCustomEmailSandboxDestinationConfig') -> bool: + """Return `true` when self and other are not equal, false otherwise.""" + return not self == other + + class DestinationConfigOneOfEventStreamsDestinationConfig(DestinationConfigOneOf): """ Payload describing a Event Streams destination configuration. @@ -14551,6 +14871,125 @@ def __ne__(self, other: 'SubscriptionCreateAttributesCustomEmailAttributes') -> return not self == other +class SubscriptionCreateAttributesCustomEmailSandboxAttributes(SubscriptionCreateAttributes): + """ + The attributes for an email notification. + + :attr List[str] invited: The email id string. + :attr bool add_notification_payload: Whether to add the notification payload to + the email. + :attr str reply_to_mail: The email address to reply to. + :attr str reply_to_name: The email name to reply to. + :attr str template_id_notification: (optional) The templete id for notification. + :attr str template_id_invitation: (optional) The templete id for invitation. + """ + + def __init__( + self, + invited: List[str], + add_notification_payload: bool, + reply_to_mail: str, + reply_to_name: str, + *, + template_id_notification: str = None, + template_id_invitation: str = None, + ) -> None: + """ + Initialize a SubscriptionCreateAttributesCustomEmailSandboxAttributes object. + + :param List[str] invited: The email id string. + :param bool add_notification_payload: Whether to add the notification + payload to the email. + :param str reply_to_mail: The email address to reply to. + :param str reply_to_name: The email name to reply to. + :param str template_id_notification: (optional) The templete id for + notification. + :param str template_id_invitation: (optional) The templete id for + invitation. + """ + # pylint: disable=super-init-not-called + self.invited = invited + self.add_notification_payload = add_notification_payload + self.reply_to_mail = reply_to_mail + self.reply_to_name = reply_to_name + self.template_id_notification = template_id_notification + self.template_id_invitation = template_id_invitation + + @classmethod + def from_dict(cls, _dict: Dict) -> 'SubscriptionCreateAttributesCustomEmailSandboxAttributes': + """Initialize a SubscriptionCreateAttributesCustomEmailSandboxAttributes object from a json dictionary.""" + args = {} + if 'invited' in _dict: + args['invited'] = _dict.get('invited') + else: + raise ValueError( + 'Required property \'invited\' not present in SubscriptionCreateAttributesCustomEmailSandboxAttributes JSON' + ) + if 'add_notification_payload' in _dict: + args['add_notification_payload'] = _dict.get('add_notification_payload') + else: + raise ValueError( + 'Required property \'add_notification_payload\' not present in SubscriptionCreateAttributesCustomEmailSandboxAttributes JSON' + ) + if 'reply_to_mail' in _dict: + args['reply_to_mail'] = _dict.get('reply_to_mail') + else: + raise ValueError( + 'Required property \'reply_to_mail\' not present in SubscriptionCreateAttributesCustomEmailSandboxAttributes JSON' + ) + if 'reply_to_name' in _dict: + args['reply_to_name'] = _dict.get('reply_to_name') + else: + raise ValueError( + 'Required property \'reply_to_name\' not present in SubscriptionCreateAttributesCustomEmailSandboxAttributes JSON' + ) + if 'template_id_notification' in _dict: + args['template_id_notification'] = _dict.get('template_id_notification') + if 'template_id_invitation' in _dict: + args['template_id_invitation'] = _dict.get('template_id_invitation') + return cls(**args) + + @classmethod + def _from_dict(cls, _dict): + """Initialize a SubscriptionCreateAttributesCustomEmailSandboxAttributes object from a json dictionary.""" + return cls.from_dict(_dict) + + def to_dict(self) -> Dict: + """Return a json dictionary representing this model.""" + _dict = {} + if hasattr(self, 'invited') and self.invited is not None: + _dict['invited'] = self.invited + if hasattr(self, 'add_notification_payload') and self.add_notification_payload is not None: + _dict['add_notification_payload'] = self.add_notification_payload + if hasattr(self, 'reply_to_mail') and self.reply_to_mail is not None: + _dict['reply_to_mail'] = self.reply_to_mail + if hasattr(self, 'reply_to_name') and self.reply_to_name is not None: + _dict['reply_to_name'] = self.reply_to_name + if hasattr(self, 'template_id_notification') and self.template_id_notification is not None: + _dict['template_id_notification'] = self.template_id_notification + if hasattr(self, 'template_id_invitation') and self.template_id_invitation is not None: + _dict['template_id_invitation'] = self.template_id_invitation + return _dict + + def _to_dict(self): + """Return a json dictionary representing this model.""" + return self.to_dict() + + def __str__(self) -> str: + """Return a `str` version of this SubscriptionCreateAttributesCustomEmailSandboxAttributes object.""" + return json.dumps(self.to_dict(), indent=2) + + def __eq__(self, other: 'SubscriptionCreateAttributesCustomEmailSandboxAttributes') -> bool: + """Return `true` when self and other are equal, false otherwise.""" + if not isinstance(other, self.__class__): + return False + return self.__dict__ == other.__dict__ + + def __ne__(self, other: 'SubscriptionCreateAttributesCustomEmailSandboxAttributes') -> bool: + """Return `true` when self and other are not equal, false otherwise.""" + return not self == other + + class SubscriptionCreateAttributesCustomSMSAttributes(SubscriptionCreateAttributes): """ The attributes for an custom sms notification. @@ -15369,6 +15808,152 @@ def __ne__(self, other: 'SubscriptionUpdateAttributesCodeEngineAttributes') -> b return not self == other +class SubscriptionUpdateAttributesCustomEmailSandboxUpdateAttributes(SubscriptionUpdateAttributes): + """ + The attributes for an email notification. + + :attr UpdateAttributesInvited invited: (optional) The email ids or phone + numbers. + :attr bool add_notification_payload: Whether to add the notification payload to + the email. + :attr str reply_to_mail: The email address to reply to. + :attr str reply_to_name: The email name to reply to. + :attr UpdateAttributesSubscribed subscribed: (optional) The email ids or phone + numbers. + :attr UpdateAttributesUnsubscribed unsubscribed: (optional) The email ids or + phone numbers. + :attr str template_id_notification: (optional) The templete id for notification. + :attr str template_id_invitation: (optional) The templete id for invitation. + """ + + def __init__( + self, + add_notification_payload: bool, + reply_to_mail: str, + reply_to_name: str, + *, + invited: 'UpdateAttributesInvited' = None, + subscribed: 'UpdateAttributesSubscribed' = None, + unsubscribed: 'UpdateAttributesUnsubscribed' = None, + template_id_notification: str = None, + template_id_invitation: str = None, + ) -> None: + """ + Initialize a SubscriptionUpdateAttributesCustomEmailSandboxUpdateAttributes object. + + :param bool add_notification_payload: Whether to add the notification + payload to the email. + :param str reply_to_mail: The email address to reply to. + :param str reply_to_name: The email name to reply to. + :param UpdateAttributesInvited invited: (optional) The email ids or phone + numbers. + :param UpdateAttributesSubscribed subscribed: (optional) The email ids or + phone numbers. + :param UpdateAttributesUnsubscribed unsubscribed: (optional) The email ids + or phone numbers. + :param str template_id_notification: (optional) The templete id for + notification. + :param str template_id_invitation: (optional) The templete id for + invitation. + """ + # pylint: disable=super-init-not-called + self.invited = invited + self.add_notification_payload = add_notification_payload + self.reply_to_mail = reply_to_mail + self.reply_to_name = reply_to_name + self.subscribed = subscribed + self.unsubscribed = unsubscribed + self.template_id_notification = template_id_notification + self.template_id_invitation = template_id_invitation + + @classmethod + def from_dict(cls, _dict: Dict) -> 'SubscriptionUpdateAttributesCustomEmailSandboxUpdateAttributes': + """Initialize a SubscriptionUpdateAttributesCustomEmailSandboxUpdateAttributes object from a json dictionary.""" + args = {} + if 'invited' in _dict: + args['invited'] = UpdateAttributesInvited.from_dict(_dict.get('invited')) + if 'add_notification_payload' in _dict: + args['add_notification_payload'] = _dict.get('add_notification_payload') + else: + raise ValueError( + 'Required property \'add_notification_payload\' not present in SubscriptionUpdateAttributesCustomEmailSandboxUpdateAttributes JSON' + ) + if 'reply_to_mail' in _dict: + args['reply_to_mail'] = _dict.get('reply_to_mail') + else: + raise ValueError( + 'Required property \'reply_to_mail\' not present in SubscriptionUpdateAttributesCustomEmailSandboxUpdateAttributes JSON' + ) + if 'reply_to_name' in _dict: + args['reply_to_name'] = _dict.get('reply_to_name') + else: + raise ValueError( + 'Required property \'reply_to_name\' not present in SubscriptionUpdateAttributesCustomEmailSandboxUpdateAttributes JSON' + ) + if 'subscribed' in _dict: + args['subscribed'] = UpdateAttributesSubscribed.from_dict(_dict.get('subscribed')) + if 'unsubscribed' in _dict: + args['unsubscribed'] = UpdateAttributesUnsubscribed.from_dict(_dict.get('unsubscribed')) + if 'template_id_notification' in _dict: + args['template_id_notification'] = _dict.get('template_id_notification') + if 'template_id_invitation' in _dict: + args['template_id_invitation'] = _dict.get('template_id_invitation') + return cls(**args) + + @classmethod + def _from_dict(cls, _dict): + """Initialize a SubscriptionUpdateAttributesCustomEmailSandboxUpdateAttributes object from a json dictionary.""" + return cls.from_dict(_dict) + + def to_dict(self) -> Dict: + """Return a json dictionary representing this model.""" + _dict = {} + if hasattr(self, 'invited') and self.invited is not None: + if isinstance(self.invited, dict): + _dict['invited'] = self.invited + else: + _dict['invited'] = self.invited.to_dict() + if hasattr(self, 'add_notification_payload') and self.add_notification_payload is not None: + _dict['add_notification_payload'] = self.add_notification_payload + if hasattr(self, 'reply_to_mail') and self.reply_to_mail is not None: + _dict['reply_to_mail'] = self.reply_to_mail + if hasattr(self, 'reply_to_name') and self.reply_to_name is not None: + _dict['reply_to_name'] = self.reply_to_name + if hasattr(self, 'subscribed') and self.subscribed is not None: + if isinstance(self.subscribed, dict): + _dict['subscribed'] = self.subscribed + else: + _dict['subscribed'] = self.subscribed.to_dict() + if hasattr(self, 'unsubscribed') and self.unsubscribed is not None: + if isinstance(self.unsubscribed, dict): + _dict['unsubscribed'] = self.unsubscribed + else: + _dict['unsubscribed'] = self.unsubscribed.to_dict() + if hasattr(self, 'template_id_notification') and self.template_id_notification is not None: + _dict['template_id_notification'] = self.template_id_notification + if hasattr(self, 'template_id_invitation') and self.template_id_invitation is not None: + _dict['template_id_invitation'] = self.template_id_invitation + return _dict + + def _to_dict(self): + """Return a json dictionary representing this model.""" + return self.to_dict() + + def __str__(self) -> str: + """Return a `str` version of this SubscriptionUpdateAttributesCustomEmailSandboxUpdateAttributes object.""" + return json.dumps(self.to_dict(), indent=2) + + def __eq__(self, other: 'SubscriptionUpdateAttributesCustomEmailSandboxUpdateAttributes') -> bool: + """Return `true` when self and other are equal, false otherwise.""" + if not isinstance(other, self.__class__): + return False + return self.__dict__ == other.__dict__ + + def __ne__(self, other: 'SubscriptionUpdateAttributesCustomEmailSandboxUpdateAttributes') -> bool: + """Return `true` when self and other are not equal, false otherwise.""" + return not self == other + + class SubscriptionUpdateAttributesCustomEmailUpdateAttributes(SubscriptionUpdateAttributes): """ The attributes for an email notification. diff --git a/test/integration/test_event_notifications_v1.py b/test/integration/test_event_notifications_v1.py index 4fba340..fa92552 100644 --- a/test/integration/test_event_notifications_v1.py +++ b/test/integration/test_event_notifications_v1.py @@ -77,6 +77,7 @@ subscription_id20 = "" subscription_id21 = "" subscription_id22 = "" +subscription_id_sandbox = "" fcmServerKey = "" fcmSenderId = "" integration_id = "" @@ -129,6 +130,7 @@ app_config_crn = "" app_config_template_body = "" app_config_template_id = "" +destination_id_sandbox = "" class TestEventNotificationsV1: @@ -302,6 +304,7 @@ def test_create_sources(self): name="Event Notification Create Source Acme", description="This source is used for Acme Bank", enabled=True, + store_notifications=True, ) assert create_sources_response.get_status_code() == 201 @@ -311,6 +314,7 @@ def test_create_sources(self): source = SourceResponse.from_dict(source_response) source_id = source.id assert source_id is not None + assert source.store_notifications is True # # The following status codes aren't covered by tests. @@ -375,11 +379,13 @@ def test_update_source(self): name="Event Notification update Source Acme", description="This source is used for updated Acme Bank", enabled=True, + store_notifications=False, ) assert update_source_response.get_status_code() == 200 source = update_source_response.get_result() assert source is not None + assert source.get('store_notifications') is False # # The following status codes aren't covered by tests. @@ -621,7 +627,7 @@ def test_replace_topic(self): @needscredentials def test_create_destination(self): # Construct a dict representation of a DestinationConfigParamsWebhookDestinationConfig model - global destination_id, destination_id4, destination_id5, destination_id6, destination_id7, destination_id8, destination_id9, destination_id10, destination_id11, destination_id12, destination_id13, destination_id14, destination_id15, destination_id16, destination_id17, destination_id18, destination_id19, destination_id20, destination_id22 + global destination_id, destination_id4, destination_id5, destination_id6, destination_id7, destination_id8, destination_id9, destination_id10, destination_id11, destination_id12, destination_id13, destination_id14, destination_id15, destination_id16, destination_id17, destination_id18, destination_id19, destination_id20, destination_id22, destination_id_sandbox destination_config_params_model = { "url": code_engine_URL, "verb": "post", @@ -1063,6 +1069,30 @@ def test_create_destination(self): destination_id16 = destination.id + name = "custom_email_sandbox_destination" + typeval = "smtp_custom_sandbox" + description = "Custom Email Sandbox Destination" + + create_destination_response = self.event_notifications_service.create_destination( + instance_id, + name, + type=typeval, + description=description, + ) + + assert create_destination_response.get_status_code() == 201 + destination_response = create_destination_response.get_result() + assert destination_response is not None + + destination = DestinationResponse.from_dict(destination_response) + + assert destination is not None + assert destination.name == name + assert destination.description == description + assert destination.type == typeval + + destination_id_sandbox = destination.id + name = "custom_sms_destination" typeval = "sms_custom" description = "Custom sms Destination" @@ -2057,6 +2087,28 @@ def test_update_destination(self): assert res_name == name assert res_description == description + name = "custom_email_sandbox_destination_update" + description = "Custom Email Sandbox Destination update" + + update_destination_response = self.event_notifications_service.update_destination( + instance_id, + id=destination_id_sandbox, + name=name, + description=description, + ) + + assert update_destination_response.get_status_code() == 200 + destination_response = update_destination_response.get_result() + assert destination_response is not None + + res_id = destination_response.get("id") + res_name = destination_response.get("name") + res_description = destination_response.get("description") + + assert res_id == destination_id_sandbox + assert res_name == name + assert res_description == description + destination_config_params_model = { "type": "job", "project_crn": code_engine_project_CRN, @@ -2433,10 +2485,34 @@ def test_update_template(self): assert template_response.get("type") == typeval assert template_response.get("id") == app_config_template_id + @needscredentials + def test_upgrade_sandbox_destination(self): + """ + Test upgrading sandbox destination to production + """ + domain = "upgraded.event-notifications.test.cloud.ibm.com" + + upgrade_response = self.event_notifications_service.update_email_sandbox_destination( + instance_id, + id=destination_id_sandbox, + domain=domain, + ) + + assert upgrade_response.get_status_code() == 200 + destination_response = upgrade_response.get_result() + assert destination_response is not None + + res_id = destination_response.get("id") + res_type = destination_response.get("type") + + assert res_id == destination_id_sandbox + # After upgrade, type should change from smtp_custom_sandbox to smtp_custom + assert res_type == "smtp_custom" + @needscredentials def test_create_subscription(self): # Construct a dict representation of a SubscriptionCreateAttributesSMSAttributes model - global subscription_id, subscription_id1, subscription_id2, subscription_id4, subscription_id5, subscription_id6, subscription_id8, subscription_id9, subscription_id10, subscription_id11, subscription_id12, subscription_id13, subscription_id14, subscription_id15, subscription_id16, subscription_id17, subscription_id18, subscription_id19, subscription_id20, subscription_id21, subscription_id22 + global subscription_id, subscription_id1, subscription_id2, subscription_id4, subscription_id5, subscription_id6, subscription_id8, subscription_id9, subscription_id10, subscription_id11, subscription_id12, subscription_id13, subscription_id14, subscription_id15, subscription_id16, subscription_id17, subscription_id18, subscription_id19, subscription_id20, subscription_id21, subscription_id22, subscription_id_sandbox subscription_create_attributes_model = { "signing_enabled": False, "template_id_notification": webhook_template_id, @@ -2846,6 +2922,35 @@ def test_create_subscription(self): assert subscription_name == name assert subscription_description == description + subscription_create_attributes_model = { + "invited": ["entestmonitor@gmail.com"], + "add_notification_payload": True, + "reply_to_mail": "entestmonitor@gmail.com", + "reply_to_name": "US News", + } + + name = "subscription_custom_email_sandbox" + description = "Subscription for custom email sandbox" + create_subscription_response = self.event_notifications_service.create_subscription( + instance_id, + name, + destination_id=destination_id_sandbox, + topic_id=topic_id, + attributes=subscription_create_attributes_model, + description=description, + ) + + assert create_subscription_response.get_status_code() == 201 + subscription_response = create_subscription_response.get_result() + assert subscription_response is not None + + subscription_name = subscription_response.get("name") + subscription_description = subscription_response.get("description") + subscription_id_sandbox = subscription_response.get("id") + + assert subscription_name == name + assert subscription_description == description + subscription_create_attributes_model = {'template_id_notification': code_engine_job_template_id} name = "subscription_code_engine_job" @@ -3458,6 +3563,39 @@ def test_update_subscription(self): assert subscription_name == name assert subscription_description == description + custom_email_sandbox_update_attributes_invite_model = {"add": ["entestmonitor@outlook.com"]} + + custom_email_sandbox_update_attributes_to_remove_model = {"remove": ["entestmonitor@gmail.com"]} + + subscription_update_attributes_model = { + "invited": custom_email_sandbox_update_attributes_invite_model, + "add_notification_payload": True, + "reply_to_mail": "entestmonitor@outlook.com", + "reply_to_name": "US News", + "subscribed": custom_email_sandbox_update_attributes_to_remove_model, + "unsubscribed": custom_email_sandbox_update_attributes_to_remove_model, + } + + name = "subscription_custom_email_sandbox update" + description = "Subscription for custom email sandbox updated" + update_subscription_response = self.event_notifications_service.update_subscription( + instance_id, + id=subscription_id_sandbox, + name=name, + description=description, + attributes=subscription_update_attributes_model, + ) + + assert update_subscription_response.get_status_code() == 200 + subscription_response = update_subscription_response.get_result() + assert subscription_response is not None + + subscription_name = subscription_response.get("name") + subscription_description = subscription_response.get("description") + + assert subscription_name == name + assert subscription_description == description + subscription_update_attributes_model = {'template_id_notification': code_engine_job_template_id} name = "code_engine_job_sub_updated" @@ -3711,6 +3849,23 @@ def test_send_notifications(self): mms = '{"content": "iVBORw0KGgoAAAANSUhEUgAAAFoAAAA4CAYAAAB9lO9TAAAAAXNSR0IArs4c6QAAActpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+QWRvYmUgSW1hZ2VSZWFkeTwveG1wOkNyZWF0b3JUb29sPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KKS7NPQAABO9JREFUeAHtW81x2zoQBhgn46NLYCpISpA6cCowfYjn3ZJUELmC5Og4h0AVPKeC8HWgDh5L8DGTTMR8KxoSBCzAX3us8WKGJrg/34KfqF2AkJWSJgwIA8KAMCAMCAPCgDAgDAgDwoAw8LQZ0GfFRT2egrpcmq9zwpkGzx9RXWqllsZ8Nb7GXg+Pq83SfDm3OKlzUVy8B1mfUjYxXRZTPC65ntVKfwOZ/xfFP7Npx1afFkVx0gUTJJ91seNsjvCkXHKKnrLK2k+EZ+GY83oGYlbGmFtXOS7uMRG9h+di2z5ifEefDmmPlQE9zVfxzy3y54puchq8rnT93D7Z4+PusLjoY/GParX+wQH3lJWwn5PPRHgE1dq0evEBRp/JcGxcrZ6fA8YQlt+K4u3rsfgHUgz9W2+uxxQnHxHF9p0vs9fQDS6CFgPFMNs8iVYw7PxnW0imwes/ivuMq1W9VOqZFMH+H8vDe2guJCbmC07eyLLSmKsyrg81aby6Si1E0r4UK8NM76oKo1JhTt0H56FQ1K83Od9qkZ8LpXSuerVwTEecP3LfR05OMq3WdCrpT9eWwgNGicPgYFuLL8Yz3JcLiNnFjfvBIT/TSvCEs43JMKYSusrVH3QxpBtxSXFvbHh/fWp98Y2gfi+Sra9/Zp/olsJS+SBt12m8XSHlcO7Pl4tGMnc82QpP5zxmGZf/XMV1orlXBvCBhe2sePsjlDYSOCTfonF+KTzOvotMK/3dL1y+39C4hA2sqlZ1dG7tx3KvwdEHu1K2cjZ1oOTNrAFz/o+RtYiSeC2+rLpS6pdhNXvCYXFRgHPA4Osf9b+FPpG7s0B3iMUQebN+gzkd3eyIVpdwriIAOeSnER3E+iauE40w8BQYQN4OW2pbCA6XKEKL0CsuSeHFvaIaSh3nfrHhrNNxm+032rWBb875czJMN18qtS6Qxz9yepLRlNRfPR9ijsYrS/0vdlmCghO78RZ5n3y7t2pswd1TR2Ydm0KxZ+hcVE6/YzeJ1xHDN3vxHpKFL92/TsXVK7KlN3N4Ol/v+/FXmPYtG01d4Vw2fe6vu+jh9CK7NwaQcsPWsm2Dt21XVegVl6TxdttgHMJD+DZp6Ljtqd7eN8aUY6x0RFq4LcamjtS2DT6ZS6AvIhFYcQoPDiWOOesIYdoXo6Fvf6Slfd24z/MWW0ox5whjmlBtxfCY7qdsbJu/h1gM3fHTZnC+JxhwcTeDqdKuv2/S+rSWfaLxiFzG3bIyruM1abzo6mwD1uLLB7yTtvhWrjNsaaM3kj5oc8JdiWbl3Xt5F8LtV+6F9B+QAfyu42IxPt5uO2oavO4jsoun/nF3Y7bRYttWNsbOjn6WtsbRveF3HfEVTneYTeI3ZD8RXtfQKxguyHhA3BJuBofT9AmDw+Tm9Yyxc3DC7kEXQ+TVZXhLYyRZQOpUMQ78dx27LaP0lhdHfrh6o/UBZjFz19p/Z9HoMoMPoHTtpP9IGMAP0ePbVt3HqFdLc03TI/wQfQq8dGStnuHt3VXlWvWPuxuzi0N9i4WnNtiSIj0VTeToM+p3bZhHR7drumLADmG3bQq8LZjfqZAiApIbo75x3TH7YfQJJDlmG1RsmaZzCGc4Ojd2wdLZ++EMb7AExmZs/F8rphwKFUC8in01JaZgCQPCgDAgDAgDwoAwIAwIA8KAMCAMPHUG/gKC0oz7fm25ogAAAABJRU5ErkJggg==", "content_type": "image/png"}' templates = '["' + slack_template_id + '"]' + # Construct email attachments + email_attachment_model = { + 'content': 'VGhpcyBpcyBhIHRlc3QgYXR0YWNobWVudCBjb250ZW50', + 'filename': 'test_document.txt', + 'content_type': 'text/plain', + 'disposition': 'attachment', + } + + email_attachment_model_2 = { + 'content': 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==', + 'filename': 'test_image.png', + 'content_type': 'image/png', + 'disposition': 'attachment', + } + + email_attachments = [email_attachment_model, email_attachment_model_2] + notification_create_model = { "ibmenseverity": notification_severity, "ibmenfcmbody": json.dumps(notification_fcm_body_model), @@ -3730,6 +3885,7 @@ def test_send_notifications(self): "ibmendefaultshort": "Alert Message", "ibmendefaultlong": "Alert for closing offers", "ibmensafaribody": json.dumps(notificationSafariBodymodel), + "attachments": email_attachments, "id": notification_id, "source": notifications_source, "type": type_value, @@ -4139,6 +4295,7 @@ def test_delete_subscription(self): subscription_id20, subscription_id21, subscription_id22, + subscription_id_sandbox, ]: delete_subscription_response = self.event_notifications_service.delete_subscription(instance_id, id) @@ -4190,6 +4347,7 @@ def test_delete_destination(self): destination_id19, destination_id20, destination_id22, + destination_id_sandbox, ]: delete_destination_response = self.event_notifications_service.delete_destination(instance_id, id) print( diff --git a/test/unit/test_event_notifications_v1.py b/test/unit/test_event_notifications_v1.py index ac29ec3..99c829e 100644 --- a/test/unit/test_event_notifications_v1.py +++ b/test/unit/test_event_notifications_v1.py @@ -489,7 +489,7 @@ def test_send_notifications_all_params(self): """ # Set up mock url = preprocess_url('/v1/instances/testString/notifications') - mock_response = '{"notification_id": "notification_id"}' + mock_response = '{"notification_id": "notification_id", "attachments": [{"content": "content", "filename": "filename", "content_type": "content_type", "disposition": "attachment"}]}' responses.add( responses.POST, url, @@ -498,6 +498,13 @@ def test_send_notifications_all_params(self): status=202, ) + # Construct a dict representation of a EmailAttachment model + email_attachment_model = {} + email_attachment_model['content'] = 'testString' + email_attachment_model['filename'] = 'testString' + email_attachment_model['content_type'] = 'testString' + email_attachment_model['disposition'] = 'attachment' + # Construct a dict representation of a NotificationCreate model notification_create_model = {} notification_create_model['specversion'] = '1.0' @@ -533,6 +540,7 @@ def test_send_notifications_all_params(self): notification_create_model['ibmenfirefoxheaders'] = '{"TTL":3600,"Topic":"test","Urgency":"high"}' notification_create_model['ibmenhuaweibody'] = 'testString' notification_create_model['ibmensafaribody'] = 'testString' + notification_create_model['attachments'] = [email_attachment_model] notification_create_model['foo'] = 'testString' # Set up parameter values @@ -569,7 +577,7 @@ def test_send_notifications_required_params(self): """ # Set up mock url = preprocess_url('/v1/instances/testString/notifications') - mock_response = '{"notification_id": "notification_id"}' + mock_response = '{"notification_id": "notification_id", "attachments": [{"content": "content", "filename": "filename", "content_type": "content_type", "disposition": "attachment"}]}' responses.add( responses.POST, url, @@ -607,7 +615,7 @@ def test_send_notifications_value_error(self): """ # Set up mock url = preprocess_url('/v1/instances/testString/notifications') - mock_response = '{"notification_id": "notification_id"}' + mock_response = '{"notification_id": "notification_id", "attachments": [{"content": "content", "filename": "filename", "content_type": "content_type", "disposition": "attachment"}]}' responses.add( responses.POST, url, @@ -689,7 +697,7 @@ def test_create_sources_all_params(self): """ # Set up mock url = preprocess_url('/v1/instances/testString/sources') - mock_response = '{"id": "id", "name": "name", "description": "description", "enabled": false, "created_at": "2019-01-01T12:00:00.000Z"}' + mock_response = '{"id": "id", "name": "name", "description": "description", "enabled": false, "store_notifications": false, "created_at": "2019-01-01T12:00:00.000Z"}' responses.add( responses.POST, url, @@ -703,6 +711,7 @@ def test_create_sources_all_params(self): name = 'testString' description = 'testString' enabled = True + store_notifications = False # Invoke method response = _service.create_sources( @@ -710,6 +719,7 @@ def test_create_sources_all_params(self): name, description, enabled=enabled, + store_notifications=store_notifications, headers={}, ) @@ -721,6 +731,7 @@ def test_create_sources_all_params(self): assert req_body['name'] == 'testString' assert req_body['description'] == 'testString' assert req_body['enabled'] == True + assert req_body['store_notifications'] == False def test_create_sources_all_params_with_retries(self): # Enable retries and run test_create_sources_all_params. @@ -738,7 +749,7 @@ def test_create_sources_value_error(self): """ # Set up mock url = preprocess_url('/v1/instances/testString/sources') - mock_response = '{"id": "id", "name": "name", "description": "description", "enabled": false, "created_at": "2019-01-01T12:00:00.000Z"}' + mock_response = '{"id": "id", "name": "name", "description": "description", "enabled": false, "store_notifications": false, "created_at": "2019-01-01T12:00:00.000Z"}' responses.add( responses.POST, url, @@ -752,6 +763,7 @@ def test_create_sources_value_error(self): name = 'testString' description = 'testString' enabled = True + store_notifications = False # Pass in all but one required param and check for a ValueError req_param_dict = { @@ -786,7 +798,7 @@ def test_list_sources_all_params(self): """ # Set up mock url = preprocess_url('/v1/instances/testString/sources') - mock_response = '{"total_count": 0, "offset": 6, "limit": 5, "sources": [{"id": "id", "name": "name", "description": "description", "type": "type", "enabled": false, "updated_at": "2019-01-01T12:00:00.000Z", "topic_count": 0}], "first": {"href": "href"}, "previous": {"href": "href"}, "next": {"href": "href"}}' + mock_response = '{"total_count": 0, "offset": 6, "limit": 5, "sources": [{"id": "id", "name": "name", "description": "description", "type": "type", "enabled": false, "store_notifications": false, "updated_at": "2019-01-01T12:00:00.000Z", "topic_count": 0}], "first": {"href": "href"}, "previous": {"href": "href"}, "next": {"href": "href"}}' responses.add( responses.GET, url, @@ -836,7 +848,7 @@ def test_list_sources_required_params(self): """ # Set up mock url = preprocess_url('/v1/instances/testString/sources') - mock_response = '{"total_count": 0, "offset": 6, "limit": 5, "sources": [{"id": "id", "name": "name", "description": "description", "type": "type", "enabled": false, "updated_at": "2019-01-01T12:00:00.000Z", "topic_count": 0}], "first": {"href": "href"}, "previous": {"href": "href"}, "next": {"href": "href"}}' + mock_response = '{"total_count": 0, "offset": 6, "limit": 5, "sources": [{"id": "id", "name": "name", "description": "description", "type": "type", "enabled": false, "store_notifications": false, "updated_at": "2019-01-01T12:00:00.000Z", "topic_count": 0}], "first": {"href": "href"}, "previous": {"href": "href"}, "next": {"href": "href"}}' responses.add( responses.GET, url, @@ -874,7 +886,7 @@ def test_list_sources_value_error(self): """ # Set up mock url = preprocess_url('/v1/instances/testString/sources') - mock_response = '{"total_count": 0, "offset": 6, "limit": 5, "sources": [{"id": "id", "name": "name", "description": "description", "type": "type", "enabled": false, "updated_at": "2019-01-01T12:00:00.000Z", "topic_count": 0}], "first": {"href": "href"}, "previous": {"href": "href"}, "next": {"href": "href"}}' + mock_response = '{"total_count": 0, "offset": 6, "limit": 5, "sources": [{"id": "id", "name": "name", "description": "description", "type": "type", "enabled": false, "store_notifications": false, "updated_at": "2019-01-01T12:00:00.000Z", "topic_count": 0}], "first": {"href": "href"}, "previous": {"href": "href"}, "next": {"href": "href"}}' responses.add( responses.GET, url, @@ -911,8 +923,8 @@ def test_list_sources_with_pager_get_next(self): """ # Set up a two-page mock response url = preprocess_url('/v1/instances/testString/sources') - mock_response1 = '{"next":{"href":"https://myhost.com/somePath?offset=1"},"sources":[{"id":"id","name":"name","description":"description","type":"type","enabled":false,"updated_at":"2019-01-01T12:00:00.000Z","topic_count":0}],"total_count":2,"limit":1}' - mock_response2 = '{"sources":[{"id":"id","name":"name","description":"description","type":"type","enabled":false,"updated_at":"2019-01-01T12:00:00.000Z","topic_count":0}],"total_count":2,"limit":1}' + mock_response1 = '{"next":{"href":"https://myhost.com/somePath?offset=1"},"sources":[{"id":"id","name":"name","description":"description","type":"type","enabled":false,"store_notifications":false,"updated_at":"2019-01-01T12:00:00.000Z","topic_count":0}],"total_count":2,"limit":1}' + mock_response2 = '{"sources":[{"id":"id","name":"name","description":"description","type":"type","enabled":false,"store_notifications":false,"updated_at":"2019-01-01T12:00:00.000Z","topic_count":0}],"total_count":2,"limit":1}' responses.add( responses.GET, url, @@ -949,8 +961,8 @@ def test_list_sources_with_pager_get_all(self): """ # Set up a two-page mock response url = preprocess_url('/v1/instances/testString/sources') - mock_response1 = '{"next":{"href":"https://myhost.com/somePath?offset=1"},"sources":[{"id":"id","name":"name","description":"description","type":"type","enabled":false,"updated_at":"2019-01-01T12:00:00.000Z","topic_count":0}],"total_count":2,"limit":1}' - mock_response2 = '{"sources":[{"id":"id","name":"name","description":"description","type":"type","enabled":false,"updated_at":"2019-01-01T12:00:00.000Z","topic_count":0}],"total_count":2,"limit":1}' + mock_response1 = '{"next":{"href":"https://myhost.com/somePath?offset=1"},"sources":[{"id":"id","name":"name","description":"description","type":"type","enabled":false,"store_notifications":false,"updated_at":"2019-01-01T12:00:00.000Z","topic_count":0}],"total_count":2,"limit":1}' + mock_response2 = '{"sources":[{"id":"id","name":"name","description":"description","type":"type","enabled":false,"store_notifications":false,"updated_at":"2019-01-01T12:00:00.000Z","topic_count":0}],"total_count":2,"limit":1}' responses.add( responses.GET, url, @@ -990,7 +1002,7 @@ def test_get_source_all_params(self): """ # Set up mock url = preprocess_url('/v1/instances/testString/sources/testString') - mock_response = '{"id": "id", "name": "name", "description": "description", "enabled": false, "type": "type", "updated_at": "2019-01-01T12:00:00.000Z", "topic_count": 11, "topic_names": ["topic_names"]}' + mock_response = '{"id": "id", "name": "name", "description": "description", "enabled": false, "store_notifications": false, "type": "type", "updated_at": "2019-01-01T12:00:00.000Z", "topic_count": 11, "topic_names": ["topic_names"]}' responses.add( responses.GET, url, @@ -1030,7 +1042,7 @@ def test_get_source_value_error(self): """ # Set up mock url = preprocess_url('/v1/instances/testString/sources/testString') - mock_response = '{"id": "id", "name": "name", "description": "description", "enabled": false, "type": "type", "updated_at": "2019-01-01T12:00:00.000Z", "topic_count": 11, "topic_names": ["topic_names"]}' + mock_response = '{"id": "id", "name": "name", "description": "description", "enabled": false, "store_notifications": false, "type": "type", "updated_at": "2019-01-01T12:00:00.000Z", "topic_count": 11, "topic_names": ["topic_names"]}' responses.add( responses.GET, url, @@ -1154,7 +1166,7 @@ def test_update_source_all_params(self): """ # Set up mock url = preprocess_url('/v1/instances/testString/sources/testString') - mock_response = '{"id": "id", "name": "name", "description": "description", "enabled": false, "type": "type", "updated_at": "2019-01-01T12:00:00.000Z", "topic_count": 11, "topic_names": ["topic_names"]}' + mock_response = '{"id": "id", "name": "name", "description": "description", "enabled": false, "store_notifications": false, "type": "type", "updated_at": "2019-01-01T12:00:00.000Z", "topic_count": 11, "topic_names": ["topic_names"]}' responses.add( responses.PATCH, url, @@ -1169,6 +1181,7 @@ def test_update_source_all_params(self): name = 'testString' description = 'testString' enabled = True + store_notifications = False # Invoke method response = _service.update_source( @@ -1177,6 +1190,7 @@ def test_update_source_all_params(self): name=name, description=description, enabled=enabled, + store_notifications=store_notifications, headers={}, ) @@ -1188,6 +1202,7 @@ def test_update_source_all_params(self): assert req_body['name'] == 'testString' assert req_body['description'] == 'testString' assert req_body['enabled'] == True + assert req_body['store_notifications'] == False def test_update_source_all_params_with_retries(self): # Enable retries and run test_update_source_all_params. @@ -1205,7 +1220,7 @@ def test_update_source_value_error(self): """ # Set up mock url = preprocess_url('/v1/instances/testString/sources/testString') - mock_response = '{"id": "id", "name": "name", "description": "description", "enabled": false, "type": "type", "updated_at": "2019-01-01T12:00:00.000Z", "topic_count": 11, "topic_names": ["topic_names"]}' + mock_response = '{"id": "id", "name": "name", "description": "description", "enabled": false, "store_notifications": false, "type": "type", "updated_at": "2019-01-01T12:00:00.000Z", "topic_count": 11, "topic_names": ["topic_names"]}' responses.add( responses.PATCH, url, @@ -1220,6 +1235,7 @@ def test_update_source_value_error(self): name = 'testString' description = 'testString' enabled = True + store_notifications = False # Pass in all but one required param and check for a ValueError req_param_dict = { @@ -3852,6 +3868,98 @@ def test_test_destination_value_error_with_retries(self): self.test_test_destination_value_error() +class TestUpdateEmailSandboxDestination: + """ + Test Class for update_email_sandbox_destination + """ + + @responses.activate + def test_update_email_sandbox_destination_all_params(self): + """ + update_email_sandbox_destination() + """ + # Set up mock + url = preprocess_url('/v1/instances/testString/destinations/testString/upgrade') + mock_response = '{"id": "id", "name": "name", "description": "description", "type": "webhook", "collect_failed_events": false, "config": {"params": {"domain": "domain", "dkim": {"public_key": "public_key", "selector": "selector", "verification": "verification"}, "spf": {"txt_name": "txt_name", "txt_value": "txt_value", "verification": "verification"}}}, "created_at": "2019-01-01T12:00:00.000Z"}' + responses.add( + responses.PATCH, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Set up parameter values + instance_id = 'testString' + id = 'testString' + domain = 'testString' + + # Invoke method + response = _service.update_email_sandbox_destination( + instance_id, + id, + domain, + headers={}, + ) + + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + # Validate body params + req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) + assert req_body['domain'] == 'testString' + + def test_update_email_sandbox_destination_all_params_with_retries(self): + # Enable retries and run test_update_email_sandbox_destination_all_params. + _service.enable_retries() + self.test_update_email_sandbox_destination_all_params() + + # Disable retries and run test_update_email_sandbox_destination_all_params. + _service.disable_retries() + self.test_update_email_sandbox_destination_all_params() + + @responses.activate + def test_update_email_sandbox_destination_value_error(self): + """ + test_update_email_sandbox_destination_value_error() + """ + # Set up mock + url = preprocess_url('/v1/instances/testString/destinations/testString/upgrade') + mock_response = '{"id": "id", "name": "name", "description": "description", "type": "webhook", "collect_failed_events": false, "config": {"params": {"domain": "domain", "dkim": {"public_key": "public_key", "selector": "selector", "verification": "verification"}, "spf": {"txt_name": "txt_name", "txt_value": "txt_value", "verification": "verification"}}}, "created_at": "2019-01-01T12:00:00.000Z"}' + responses.add( + responses.PATCH, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Set up parameter values + instance_id = 'testString' + id = 'testString' + domain = 'testString' + + # Pass in all but one required param and check for a ValueError + req_param_dict = { + "instance_id": instance_id, + "id": id, + "domain": domain, + } + for param in req_param_dict.keys(): + req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} + with pytest.raises(ValueError): + _service.update_email_sandbox_destination(**req_copy) + + def test_update_email_sandbox_destination_value_error_with_retries(self): + # Enable retries and run test_update_email_sandbox_destination_value_error. + _service.enable_retries() + self.test_update_email_sandbox_destination_value_error() + + # Disable retries and run test_update_email_sandbox_destination_value_error. + _service.disable_retries() + self.test_update_email_sandbox_destination_value_error() + + class TestUpdateVerifyDestination: """ Test Class for update_verify_destination @@ -7663,6 +7771,39 @@ def test_en_auth_attributes_serialization(self): assert en_auth_attributes_model_json2 == en_auth_attributes_model_json +class TestModel_EmailAttachment: + """ + Test Class for EmailAttachment + """ + + def test_email_attachment_serialization(self): + """ + Test serialization/deserialization for EmailAttachment + """ + + # Construct a json representation of a EmailAttachment model + email_attachment_model_json = {} + email_attachment_model_json['content'] = 'testString' + email_attachment_model_json['filename'] = 'testString' + email_attachment_model_json['content_type'] = 'testString' + email_attachment_model_json['disposition'] = 'attachment' + + # Construct a model instance of EmailAttachment by calling from_dict on the json representation + email_attachment_model = EmailAttachment.from_dict(email_attachment_model_json) + assert email_attachment_model != False + + # Construct a model instance of EmailAttachment by calling from_dict on the json representation + email_attachment_model_dict = EmailAttachment.from_dict(email_attachment_model_json).__dict__ + email_attachment_model2 = EmailAttachment(**email_attachment_model_dict) + + # Verify the model instances are equivalent + assert email_attachment_model == email_attachment_model2 + + # Convert model instance back to dict and verify no loss of data + email_attachment_model_json2 = email_attachment_model.to_dict() + assert email_attachment_model_json2 == email_attachment_model_json + + class TestModel_EmailAttributesResponseInvitedItems: """ Test Class for EmailAttributesResponseInvitedItems @@ -8340,6 +8481,14 @@ def test_notification_create_serialization(self): Test serialization/deserialization for NotificationCreate """ + # Construct dict forms of any model objects needed in order to build this model. + + email_attachment_model = {} # EmailAttachment + email_attachment_model['content'] = 'VGhpcyBpcyBhIHRlc3QgZG9jdW1lbnQK' + email_attachment_model['filename'] = 'test.txt' + email_attachment_model['content_type'] = 'text/plain' + email_attachment_model['disposition'] = 'attachment' + # Construct a json representation of a NotificationCreate model notification_create_model_json = {} notification_create_model_json['specversion'] = '1.0' @@ -8375,6 +8524,7 @@ def test_notification_create_serialization(self): notification_create_model_json['ibmenfirefoxheaders'] = '{"TTL":3600,"Topic":"test","Urgency":"high"}' notification_create_model_json['ibmenhuaweibody'] = 'testString' notification_create_model_json['ibmensafaribody'] = 'testString' + notification_create_model_json['attachments'] = [email_attachment_model] notification_create_model_json['foo'] = 'testString' # Construct a model instance of NotificationCreate by calling from_dict on the json representation @@ -8413,9 +8563,18 @@ def test_notification_response_serialization(self): Test serialization/deserialization for NotificationResponse """ + # Construct dict forms of any model objects needed in order to build this model. + + email_attachment_model = {} # EmailAttachment + email_attachment_model['content'] = 'VGhpcyBpcyBhIHRlc3QgZG9jdW1lbnQK' + email_attachment_model['filename'] = 'test.txt' + email_attachment_model['content_type'] = 'text/plain' + email_attachment_model['disposition'] = 'attachment' + # Construct a json representation of a NotificationResponse model notification_response_model_json = {} notification_response_model_json['notification_id'] = 'testString' + notification_response_model_json['attachments'] = [email_attachment_model] # Construct a model instance of NotificationResponse by calling from_dict on the json representation notification_response_model = NotificationResponse.from_dict(notification_response_model_json) @@ -9311,6 +9470,7 @@ def test_source_serialization(self): source_model_json['name'] = 'testString' source_model_json['description'] = 'testString' source_model_json['enabled'] = True + source_model_json['store_notifications'] = True source_model_json['type'] = 'testString' source_model_json['updated_at'] = '2019-01-01T12:00:00Z' source_model_json['topic_count'] = 38 @@ -9350,6 +9510,7 @@ def test_source_list_serialization(self): source_list_item_model['description'] = 'This source is related cloud events' source_list_item_model['type'] = 'api' source_list_item_model['enabled'] = True + source_list_item_model['store_notifications'] = True source_list_item_model['updated_at'] = '2021-08-19T05:30:03.696000Z' source_list_item_model['topic_count'] = 0 @@ -9401,6 +9562,7 @@ def test_source_list_item_serialization(self): source_list_item_model_json['description'] = 'testString' source_list_item_model_json['type'] = 'testString' source_list_item_model_json['enabled'] = True + source_list_item_model_json['store_notifications'] = True source_list_item_model_json['updated_at'] = '2019-01-01T12:00:00Z' source_list_item_model_json['topic_count'] = 0 @@ -9436,6 +9598,7 @@ def test_source_response_serialization(self): source_response_model_json['name'] = 'testString' source_response_model_json['description'] = 'testString' source_response_model_json['enabled'] = True + source_response_model_json['store_notifications'] = True source_response_model_json['created_at'] = '2019-01-01T12:00:00Z' # Construct a model instance of SourceResponse by calling from_dict on the json representation @@ -10457,6 +10620,70 @@ def test_destination_config_one_of_custom_domain_email_destination_config_serial ) +class TestModel_DestinationConfigOneOfCustomEmailSandboxDestinationConfig: + """ + Test Class for DestinationConfigOneOfCustomEmailSandboxDestinationConfig + """ + + def test_destination_config_one_of_custom_email_sandbox_destination_config_serialization(self): + """ + Test serialization/deserialization for DestinationConfigOneOfCustomEmailSandboxDestinationConfig + """ + + # Construct dict forms of any model objects needed in order to build this model. + + dkim_attributes_model = {} # DKIMAttributes + dkim_attributes_model['public_key'] = 'testString' + dkim_attributes_model['selector'] = 'testString' + dkim_attributes_model['verification'] = 'testString' + + spf_attributes_model = {} # SPFAttributes + spf_attributes_model['txt_name'] = 'testString' + spf_attributes_model['txt_value'] = 'testString' + spf_attributes_model['verification'] = 'testString' + + # Construct a json representation of a DestinationConfigOneOfCustomEmailSandboxDestinationConfig model + destination_config_one_of_custom_email_sandbox_destination_config_model_json = {} + destination_config_one_of_custom_email_sandbox_destination_config_model_json['domain'] = 'testString' + destination_config_one_of_custom_email_sandbox_destination_config_model_json['dkim'] = dkim_attributes_model + destination_config_one_of_custom_email_sandbox_destination_config_model_json['spf'] = spf_attributes_model + + # Construct a model instance of DestinationConfigOneOfCustomEmailSandboxDestinationConfig by calling from_dict on the json representation + destination_config_one_of_custom_email_sandbox_destination_config_model = ( + DestinationConfigOneOfCustomEmailSandboxDestinationConfig.from_dict( + destination_config_one_of_custom_email_sandbox_destination_config_model_json + ) + ) + assert destination_config_one_of_custom_email_sandbox_destination_config_model != False + + # Construct a model instance of DestinationConfigOneOfCustomEmailSandboxDestinationConfig by calling from_dict on the json representation + destination_config_one_of_custom_email_sandbox_destination_config_model_dict = ( + DestinationConfigOneOfCustomEmailSandboxDestinationConfig.from_dict( + destination_config_one_of_custom_email_sandbox_destination_config_model_json + ).__dict__ + ) + destination_config_one_of_custom_email_sandbox_destination_config_model2 = ( + DestinationConfigOneOfCustomEmailSandboxDestinationConfig( + **destination_config_one_of_custom_email_sandbox_destination_config_model_dict + ) + ) + + # Verify the model instances are equivalent + assert ( + destination_config_one_of_custom_email_sandbox_destination_config_model + == destination_config_one_of_custom_email_sandbox_destination_config_model2 + ) + + # Convert model instance back to dict and verify no loss of data + destination_config_one_of_custom_email_sandbox_destination_config_model_json2 = ( + destination_config_one_of_custom_email_sandbox_destination_config_model.to_dict() + ) + assert ( + destination_config_one_of_custom_email_sandbox_destination_config_model_json2 + == destination_config_one_of_custom_email_sandbox_destination_config_model_json + ) + + class TestModel_DestinationConfigOneOfEventStreamsDestinationConfig: """ Test Class for DestinationConfigOneOfEventStreamsDestinationConfig @@ -12099,6 +12326,65 @@ def test_subscription_create_attributes_custom_email_attributes_serialization(se ) +class TestModel_SubscriptionCreateAttributesCustomEmailSandboxAttributes: + """ + Test Class for SubscriptionCreateAttributesCustomEmailSandboxAttributes + """ + + def test_subscription_create_attributes_custom_email_sandbox_attributes_serialization(self): + """ + Test serialization/deserialization for SubscriptionCreateAttributesCustomEmailSandboxAttributes + """ + + # Construct a json representation of a SubscriptionCreateAttributesCustomEmailSandboxAttributes model + subscription_create_attributes_custom_email_sandbox_attributes_model_json = {} + subscription_create_attributes_custom_email_sandbox_attributes_model_json['invited'] = ['testString'] + subscription_create_attributes_custom_email_sandbox_attributes_model_json['add_notification_payload'] = False + subscription_create_attributes_custom_email_sandbox_attributes_model_json['reply_to_mail'] = 'testString' + subscription_create_attributes_custom_email_sandbox_attributes_model_json['reply_to_name'] = 'testString' + subscription_create_attributes_custom_email_sandbox_attributes_model_json['template_id_notification'] = ( + 'testString' + ) + subscription_create_attributes_custom_email_sandbox_attributes_model_json['template_id_invitation'] = ( + 'testString' + ) + + # Construct a model instance of SubscriptionCreateAttributesCustomEmailSandboxAttributes by calling from_dict on the json representation + subscription_create_attributes_custom_email_sandbox_attributes_model = ( + SubscriptionCreateAttributesCustomEmailSandboxAttributes.from_dict( + subscription_create_attributes_custom_email_sandbox_attributes_model_json + ) + ) + assert subscription_create_attributes_custom_email_sandbox_attributes_model != False + + # Construct a model instance of SubscriptionCreateAttributesCustomEmailSandboxAttributes by calling from_dict on the json representation + subscription_create_attributes_custom_email_sandbox_attributes_model_dict = ( + SubscriptionCreateAttributesCustomEmailSandboxAttributes.from_dict( + subscription_create_attributes_custom_email_sandbox_attributes_model_json + ).__dict__ + ) + subscription_create_attributes_custom_email_sandbox_attributes_model2 = ( + SubscriptionCreateAttributesCustomEmailSandboxAttributes( + **subscription_create_attributes_custom_email_sandbox_attributes_model_dict + ) + ) + + # Verify the model instances are equivalent + assert ( + subscription_create_attributes_custom_email_sandbox_attributes_model + == subscription_create_attributes_custom_email_sandbox_attributes_model2 + ) + + # Convert model instance back to dict and verify no loss of data + subscription_create_attributes_custom_email_sandbox_attributes_model_json2 = ( + subscription_create_attributes_custom_email_sandbox_attributes_model.to_dict() + ) + assert ( + subscription_create_attributes_custom_email_sandbox_attributes_model_json2 + == subscription_create_attributes_custom_email_sandbox_attributes_model_json + ) + + class TestModel_SubscriptionCreateAttributesCustomSMSAttributes: """ Test Class for SubscriptionCreateAttributesCustomSMSAttributes @@ -12686,6 +12972,87 @@ def test_subscription_update_attributes_code_engine_attributes_serialization(sel ) +class TestModel_SubscriptionUpdateAttributesCustomEmailSandboxUpdateAttributes: + """ + Test Class for SubscriptionUpdateAttributesCustomEmailSandboxUpdateAttributes + """ + + def test_subscription_update_attributes_custom_email_sandbox_update_attributes_serialization(self): + """ + Test serialization/deserialization for SubscriptionUpdateAttributesCustomEmailSandboxUpdateAttributes + """ + + # Construct dict forms of any model objects needed in order to build this model. + + update_attributes_invited_model = {} # UpdateAttributesInvited + update_attributes_invited_model['add'] = ['testString'] + update_attributes_invited_model['remove'] = ['testString'] + + update_attributes_subscribed_model = {} # UpdateAttributesSubscribed + update_attributes_subscribed_model['remove'] = ['testString'] + + update_attributes_unsubscribed_model = {} # UpdateAttributesUnsubscribed + update_attributes_unsubscribed_model['remove'] = ['testString'] + + # Construct a json representation of a SubscriptionUpdateAttributesCustomEmailSandboxUpdateAttributes model + subscription_update_attributes_custom_email_sandbox_update_attributes_model_json = {} + subscription_update_attributes_custom_email_sandbox_update_attributes_model_json['invited'] = ( + update_attributes_invited_model + ) + subscription_update_attributes_custom_email_sandbox_update_attributes_model_json['add_notification_payload'] = ( + False + ) + subscription_update_attributes_custom_email_sandbox_update_attributes_model_json['reply_to_mail'] = 'testString' + subscription_update_attributes_custom_email_sandbox_update_attributes_model_json['reply_to_name'] = 'testString' + subscription_update_attributes_custom_email_sandbox_update_attributes_model_json['subscribed'] = ( + update_attributes_subscribed_model + ) + subscription_update_attributes_custom_email_sandbox_update_attributes_model_json['unsubscribed'] = ( + update_attributes_unsubscribed_model + ) + subscription_update_attributes_custom_email_sandbox_update_attributes_model_json['template_id_notification'] = ( + 'testString' + ) + subscription_update_attributes_custom_email_sandbox_update_attributes_model_json['template_id_invitation'] = ( + 'testString' + ) + + # Construct a model instance of SubscriptionUpdateAttributesCustomEmailSandboxUpdateAttributes by calling from_dict on the json representation + subscription_update_attributes_custom_email_sandbox_update_attributes_model = ( + SubscriptionUpdateAttributesCustomEmailSandboxUpdateAttributes.from_dict( + subscription_update_attributes_custom_email_sandbox_update_attributes_model_json + ) + ) + assert subscription_update_attributes_custom_email_sandbox_update_attributes_model != False + + # Construct a model instance of SubscriptionUpdateAttributesCustomEmailSandboxUpdateAttributes by calling from_dict on the json representation + subscription_update_attributes_custom_email_sandbox_update_attributes_model_dict = ( + SubscriptionUpdateAttributesCustomEmailSandboxUpdateAttributes.from_dict( + subscription_update_attributes_custom_email_sandbox_update_attributes_model_json + ).__dict__ + ) + subscription_update_attributes_custom_email_sandbox_update_attributes_model2 = ( + SubscriptionUpdateAttributesCustomEmailSandboxUpdateAttributes( + **subscription_update_attributes_custom_email_sandbox_update_attributes_model_dict + ) + ) + + # Verify the model instances are equivalent + assert ( + subscription_update_attributes_custom_email_sandbox_update_attributes_model + == subscription_update_attributes_custom_email_sandbox_update_attributes_model2 + ) + + # Convert model instance back to dict and verify no loss of data + subscription_update_attributes_custom_email_sandbox_update_attributes_model_json2 = ( + subscription_update_attributes_custom_email_sandbox_update_attributes_model.to_dict() + ) + assert ( + subscription_update_attributes_custom_email_sandbox_update_attributes_model_json2 + == subscription_update_attributes_custom_email_sandbox_update_attributes_model_json + ) + + class TestModel_SubscriptionUpdateAttributesCustomEmailUpdateAttributes: """ Test Class for SubscriptionUpdateAttributesCustomEmailUpdateAttributes