155 lines
5.1 KiB
Python
155 lines
5.1 KiB
Python
from unittest import TestCase, mock
|
|
|
|
from mycroft import MycroftSkill
|
|
from mycroft.messagebus import Message
|
|
from mycroft.skills import skill_api_method
|
|
from mycroft.skills.api import SkillApi
|
|
|
|
|
|
class Skill(MycroftSkill):
|
|
"""Test skill with registered API methods."""
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.registered_methods = {}
|
|
|
|
def add_event(self, event_type, func):
|
|
"""Mock handler of add_event, simply storing type and method.
|
|
|
|
Used in testing to verify the wrapped methods
|
|
"""
|
|
self.registered_methods[event_type] = func
|
|
|
|
@skill_api_method
|
|
def test_method(self):
|
|
"""Documentation."""
|
|
return True
|
|
|
|
@skill_api_method
|
|
def test_method2(self, arg):
|
|
"""Documentation."""
|
|
return 'TestResult'
|
|
|
|
|
|
def load_test_skill():
|
|
"""Helper for setting up the test skill.
|
|
|
|
Returns:
|
|
(MycroftSkill): created test skill
|
|
"""
|
|
bus = mock.Mock()
|
|
test_skill = Skill()
|
|
test_skill.skill_id = 'test_skill'
|
|
test_skill.bind(bus)
|
|
return test_skill
|
|
|
|
|
|
def create_skill_api_from_skill(skill):
|
|
"""Helper creating an api from a skill.
|
|
|
|
Args:
|
|
skill (MycroftSkill): Skill to create api from.
|
|
|
|
Returns:
|
|
(SkillApi): API for the skill.
|
|
"""
|
|
SkillApi.connect_bus(skill.bus)
|
|
return SkillApi(skill.public_api)
|
|
|
|
|
|
class testSkillMethod(TestCase):
|
|
"""Tests for the MycroftSkill class API setup."""
|
|
def test_public_api_event(self):
|
|
"""Test that public api event handler is created."""
|
|
test_skill = load_test_skill()
|
|
self.assertTrue(
|
|
'test_skill.public_api' in test_skill.registered_methods
|
|
)
|
|
|
|
def test_public_api(self):
|
|
"""Test that the public_api structure matches the decorators."""
|
|
test_skill = load_test_skill()
|
|
# Check that methods has been added
|
|
self.assertTrue('test_method' in test_skill.public_api)
|
|
self.assertTrue('test_method2' in test_skill.public_api)
|
|
# Test docstring
|
|
self.assertEqual(test_skill.public_api['test_method']['help'],
|
|
'Documentation.')
|
|
# Test type
|
|
self.assertEqual(test_skill.public_api['test_method']['type'],
|
|
'{}.{}'.format(test_skill.skill_id, 'test_method'))
|
|
|
|
def test_public_api_method(self):
|
|
"""Verify message from wrapped api method."""
|
|
test_skill = load_test_skill()
|
|
api_method = test_skill.registered_methods['test_skill.test_method']
|
|
|
|
# Call method
|
|
call_msg = Message('test_skill.test_method',
|
|
data={'args': [], 'kwargs': {}})
|
|
api_method(call_msg)
|
|
# Check response sent on the bus is the same as the method's return
|
|
# value
|
|
response = test_skill.bus.emit.call_args[0][0]
|
|
self.assertEqual(response.data['result'], test_skill.test_method())
|
|
|
|
def test_public_api_request(self):
|
|
"""Test public api request handling.
|
|
|
|
Ensures that a request for the skill's available public api returns
|
|
expected content.
|
|
"""
|
|
test_skill = load_test_skill()
|
|
sent_message = None
|
|
|
|
def capture_sent_message(message):
|
|
"""Capture sent message."""
|
|
nonlocal sent_message
|
|
sent_message = message
|
|
|
|
test_skill.bus.emit.side_effect = capture_sent_message
|
|
get_api_method = test_skill.registered_methods['test_skill.public_api']
|
|
request_api_msg = Message('test_skill.public_api')
|
|
|
|
# Ensure that the sent public api contains the correct items
|
|
get_api_method(request_api_msg)
|
|
public_api = sent_message.data
|
|
self.assertTrue('test_method' in public_api)
|
|
self.assertTrue('test_method2' in public_api)
|
|
self.assertEqual(len(public_api), 2)
|
|
|
|
|
|
class TestApiObject(TestCase):
|
|
"""Tests for the generated SkillApi objects."""
|
|
def test_create_api_object(self):
|
|
"""Check that expected methods are available."""
|
|
test_skill = load_test_skill()
|
|
test_api = create_skill_api_from_skill(test_skill)
|
|
|
|
hasattr(test_api, 'test_method')
|
|
hasattr(test_api, 'test_method2')
|
|
|
|
def test_call_api_method(self):
|
|
"""Ensure that calling the methods works as expected."""
|
|
test_skill = load_test_skill()
|
|
test_api = create_skill_api_from_skill(test_skill)
|
|
|
|
expected_response = 'all is good'
|
|
sent_message = None
|
|
|
|
def capture_sent_message(message):
|
|
"""Capture sent message and return expected response message."""
|
|
nonlocal sent_message
|
|
sent_message = message
|
|
return Message('', data={'result': expected_response})
|
|
|
|
test_api.bus.wait_for_response.side_effect = capture_sent_message
|
|
|
|
response = test_api.test_method('hello', person='you')
|
|
|
|
# Verify response
|
|
self.assertEqual(response, expected_response)
|
|
# Verify sent message
|
|
self.assertEqual(sent_message.msg_type, 'test_skill.test_method')
|
|
self.assertEqual(sent_message.data['args'], ('hello',))
|
|
self.assertEqual(sent_message.data['kwargs'], {'person': 'you'})
|