# -*- coding: utf-8 -*-
"""
:Module: khoros.utils.tests.test_messages
:Synopsis: This module is used by pytest to verify that messages function properly
:Created By: Jeff Shurtliff
:Last Modified: Jeff Shurtliff
:Modified Date: 10 Jul 2023
"""
import os
import sys
import pytest
import requests
from . import resources
# Define a global variable to define when the package path has been set
package_path_defined = False
[docs]
def set_package_path():
"""This function adds the high-level khoros directory to the sys.path list.
.. versionadded:: 5.1.0
"""
global package_path_defined
if not package_path_defined:
sys.path.insert(0, os.path.abspath('../..'))
package_path_defined = True
[docs]
def get_control_data(test_type):
"""This function retrieves control data to use in unit tests.
:param test_type: Nickname of the test to be performed
:type test_type: str
:returns: Payload control data in dictionary format
"""
control_data = {
'node': {'data': {'type': 'message', 'board': {'id': 'my-board'}, 'subject': 'This is the subject line'}},
'node_id': {'data': {'type': 'message', 'board': {'id': 'my-board'}, 'subject': 'This is the subject line'}},
'node_url': {'data': {'type': 'message', 'board': {'id': 'studio'}, 'subject': 'This is the subject line'}},
'body': {'data': {'type': 'message', 'board': {'id': 'my-board'},
'subject': 'Welcome', 'body': '<h1>Hello!</h1>'}},
'welcome_tag': {'data': {'type': 'message', 'board': {'id': 'my-board'}, 'subject': 'Welcome',
'tags': [{'type': 'tag', 'text': 'welcome'}]}},
'12345_tag': {'data': {'type': 'message', 'board': {'id': 'my-board'}, 'subject': 'Welcome',
'tags': [{'type': 'tag', 'text': '12345'}]}},
'hello_world_tags': {'data': {'type': 'message', 'board': {'id': 'my-board'}, 'subject': 'Welcome',
'tags': [{'type': 'tag', 'text': 'hello'}, {'type': 'tag', 'text': 'world'}]}},
'str_iter_int_tags': {'data': {'type': 'message', 'board': {'id': 'my-board'}, 'subject': 'Welcome',
'tags': [{'type': 'tag', 'text': 'hello'}, {'type': 'tag', 'text': 'world'},
{'type': 'tag', 'text': '12345'}]}},
}
return control_data.get(test_type)
[docs]
def test_count_messages():
"""This function tests the ability to retrieve a messages count for a specific board.
.. versionadded:: 5.3.0
"""
# Instantiate the Khoros object
set_package_path()
khoros_object = resources.get_core_object()
# Test retrieving the message count for a given board
messages_count = khoros_object.boards.get_message_count('support-information')
assert isinstance(messages_count, int)
[docs]
def test_construct_only_subject():
"""This function tests to ensure that a :py:exc:`khoros.errors.exceptions.MissingRequiredDataError` exception
gets raised when only a subject is passed to the :py:func:`khoros.objects.messages.construct_payload` function.
.. versionchanged:: 5.0.0
Removed the redundant return statement.
"""
with pytest.raises(exceptions.MissingRequiredDataError):
messages.construct_payload('This is the subject line')
[docs]
def test_construct_with_node():
"""This function tests constructing payload using properly formatted node data.
.. versionchanged:: 5.0.0
Removed the redundant return statement.
"""
control_data = get_control_data('node')
payload = messages.construct_payload('This is the subject line', node={"id": "my-board"})
assert payload == control_data # nosec
[docs]
def test_construct_with_node_id():
"""This function tests constructing payload using a Node ID.
.. versionchanged:: 5.0.0
Removed the redundant return statement.
"""
control_data = get_control_data('node_id')
payload = messages.construct_payload('This is the subject line', node_id='my-board')
assert payload == control_data # nosec
[docs]
def test_construct_with_node_url():
"""This function tests constructing payload using a Node URL.
.. versionchanged:: 5.0.0
Removed the redundant return statement.
"""
node_url = 'https://community.khoros.com/t5/Developer-Discussion/bd-p/studio'
control_data = get_control_data('node_url')
payload = messages.construct_payload('This is the subject line', node_url=node_url)
assert payload == control_data # nosec
[docs]
def test_construct_with_body():
"""This function tests constructing payload using a message body.
.. versionchanged:: 5.0.0
Removed the redundant return statement.
"""
control_data = get_control_data('body')
payload = messages.construct_payload('Welcome', node_id='my-board', body='<h1>Hello!</h1>')
assert payload == control_data # nosec
[docs]
def test_construct_with_one_str_tag():
"""This function tests constructing payload using a single tag in string format.
.. versionchanged:: 5.0.0
Removed the redundant return statement.
"""
control_data = get_control_data('welcome_tag')
payload = messages.construct_payload('Welcome', node_id='my-board', tags='welcome')
assert payload == control_data # nosec
[docs]
def test_construct_with_one_int_tag():
"""This function tests constructing payload using a single tag in integer format.
.. versionchanged:: 5.0.0
Removed the redundant return statement.
"""
control_data = get_control_data('12345_tag')
payload = messages.construct_payload('Welcome', node_id='my-board', tags=12345)
assert payload == control_data # nosec
[docs]
def test_construct_with_tag_iterables():
"""This function tests constructing payload providing tags as a list containing two strings.
.. versionchanged:: 5.0.0
Removed the redundant return statement.
"""
control_data = get_control_data('hello_world_tags')
list_payload = messages.construct_payload('Welcome', node_id='my-board', tags=['hello', 'world'])
tuple_payload = messages.construct_payload('Welcome', node_id='my-board', tags=('hello', 'world'))
set_payload = messages.construct_payload('Welcome', node_id='my-board', tags={'hello', 'world'})
for payload in (list_payload, tuple_payload, set_payload):
try:
assert payload == control_data # nosec
except AssertionError:
assert_tags_present(payload, ['hello', 'world'])
[docs]
def test_payload_validation():
"""This function tests the validation of the message payload to ensure invalid data raises an exception.
.. versionadded:: 4.3.0
.. versionchanged:: 5.0.0
Removed the redundant return statement.
"""
# Test null payload
with pytest.raises(exceptions.InvalidMessagePayloadError):
messages.validate_message_payload(payload=None)
# Test conversion to dictionary when JSON string
payload = '{"data": {"type": "message", "subject": "This is a message subject"}}'
payload = messages.validate_message_payload(payload)
assert isinstance(payload, dict)
# Test incorrect data type
with pytest.raises(exceptions.InvalidMessagePayloadError):
payload = [{'type': 'message'}, {'subject': 'This is a message subject'}]
messages.validate_message_payload(payload)
# Test payload that is not wrapped in the 'data' field
with pytest.raises(exceptions.InvalidMessagePayloadError):
payload = {'type': 'message', 'subject': 'This is a message subject'}
messages.validate_message_payload(payload)
# Test payload that is missing the 'type' sub-field
with pytest.raises(exceptions.InvalidMessagePayloadError):
payload = {'subject': 'This is a message subject'}
messages.validate_message_payload(payload)
# Test payload that has the incorrect 'type' value
with pytest.raises(exceptions.InvalidMessagePayloadError):
payload = {'type': 'article', 'subject': 'This is a message subject'}
messages.validate_message_payload(payload)
# Test valid payload
payload = {'data': {'type': 'message', 'subject': 'This is a message subject'}}
payload = messages.validate_message_payload(payload)
assert payload.get('data').get('type') == 'message'
[docs]
def test_kudo_message(monkeypatch):
"""This function tests the ability to kudo a message.
.. versionchanged:: 5.1.2
The function has been updated to use monkeypatching.
.. versionchanged:: 5.1.1
This function has been updated to support GitHub Workflows unit testing.
.. versionadded:: 5.1.0
"""
# Instantiate the Khoros object
set_package_path()
khoros_object = resources.get_core_object()
# Overwrite the requests.get functionality with the mock_post() function
monkeypatch.setattr(requests, 'post', resources.mock_success_post)
# Perform the API call and assert that it was successful
msg_id = '62458' # This is a message in the Stage environment used for testing
response = khoros_object.messages.kudo(msg_id)
assert response.get('status') == 'success'
[docs]
def test_flagging_message(monkeypatch):
"""This function tests the ability to flag and unflag a message as spam.
.. versionchanged:: 5.1.2
The function has been updated to use monkeypatching.
.. versionchanged:: 5.1.1
This function has been updated to support GitHub Workflows unit testing.
.. versionadded:: 5.1.0
"""
# Instantiate the Khoros object
set_package_path()
khoros_object = resources.get_core_object()
# Overwrite the requests.get functionality with the mock_post() function
monkeypatch.setattr(requests, 'put', resources.mock_success_post)
# Perform the API calls and assert that it was successful
msg_id = '62458' # This is a message in the Stage environment used for testing
response = khoros_object.messages.flag(msg_id)
assert response.get('status') == 'success'
response = khoros_object.messages.unflag(msg_id)
assert response.get('status') == 'success'
[docs]
def test_label_message(monkeypatch):
"""This function tests the ability to add a label to a message.
.. versionchanged:: 5.1.2
The function has been updated to use monkeypatching.
.. versionchanged:: 5.1.1
This function has been updated to support GitHub Workflows unit testing.
.. versionadded:: 5.1.0
"""
# Instantiate the Khoros object
set_package_path()
khoros_object = resources.get_core_object()
# Overwrite the requests.get functionality with the mock_post() function
monkeypatch.setattr(requests, 'post', resources.mock_success_post)
# Perform the API call and assert that it was successful
msg_id = '62458' # This is a message in the Stage environment used for testing
label_text = core_utils.get_random_string(8)
response = khoros_object.messages.label(msg_id, label_text)
assert response.get('status') == 'success'
[docs]
def test_tag_message(monkeypatch):
"""This function tests the ability to add a tag to a message.
.. versionchanged:: 5.1.2
The function has been updated to use monkeypatching.
.. versionchanged:: 5.1.1
This function has been updated to support GitHub Workflows unit testing.
.. versionadded:: 5.1.0
"""
# Instantiate the Khoros object
set_package_path()
khoros_object = resources.get_core_object()
# Overwrite the requests.get functionality with the mock_post() function
monkeypatch.setattr(requests, 'post', resources.mock_success_post)
# Perform the API call and assert that it was successful
msg_id = '62458' # This is a message in the Stage environment used for testing
tag_text = core_utils.get_random_string(8)
response = khoros_object.messages.tag(msg_id, tag_text)
assert response.get('status') == 'success'
# Import modules and initialize the core object
messages, exceptions = resources.import_modules('khoros.objects.messages', 'khoros.errors.exceptions')
core_utils = resources.import_modules('khoros.utils.core_utils')
khoros = resources.initialize_khoros_object()