2022-08-08 14:24:58 +02:00
|
|
|
# Copyright (c) 2018, Arigato Machine Inc.
|
|
|
|
# Copyright (c) 2018, Ansible Project
|
2022-08-05 12:28:29 +02:00
|
|
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
2020-03-09 10:11:07 +01:00
|
|
|
from __future__ import (absolute_import, division, print_function)
|
|
|
|
__metaclass__ = type
|
|
|
|
|
|
|
|
from ansible_collections.community.general.tests.unit.compat import unittest
|
|
|
|
from ansible_collections.community.general.tests.unit.compat.mock import patch, call
|
|
|
|
from ansible.errors import AnsibleError
|
|
|
|
from ansible.module_utils.urls import ConnectionError, SSLValidationError
|
|
|
|
from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError
|
|
|
|
from ansible.module_utils import six
|
|
|
|
from ansible_collections.community.general.plugins.lookup.manifold import ManifoldApiClient, LookupModule, ApiError
|
|
|
|
import json
|
|
|
|
|
|
|
|
|
|
|
|
API_FIXTURES = {
|
|
|
|
'https://api.marketplace.manifold.co/v1/resources':
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"body": {
|
|
|
|
"label": "resource-1",
|
|
|
|
"name": "Resource 1"
|
|
|
|
},
|
|
|
|
"id": "rid-1"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"body": {
|
|
|
|
"label": "resource-2",
|
|
|
|
"name": "Resource 2"
|
|
|
|
},
|
|
|
|
"id": "rid-2"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
'https://api.marketplace.manifold.co/v1/resources?label=resource-1':
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"body": {
|
|
|
|
"label": "resource-1",
|
|
|
|
"name": "Resource 1"
|
|
|
|
},
|
|
|
|
"id": "rid-1"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
'https://api.marketplace.manifold.co/v1/resources?label=resource-2':
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"body": {
|
|
|
|
"label": "resource-2",
|
|
|
|
"name": "Resource 2"
|
|
|
|
},
|
|
|
|
"id": "rid-2"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
'https://api.marketplace.manifold.co/v1/resources?team_id=tid-1':
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"body": {
|
|
|
|
"label": "resource-1",
|
|
|
|
"name": "Resource 1"
|
|
|
|
},
|
|
|
|
"id": "rid-1"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
'https://api.marketplace.manifold.co/v1/resources?project_id=pid-1':
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"body": {
|
|
|
|
"label": "resource-2",
|
|
|
|
"name": "Resource 2"
|
|
|
|
},
|
|
|
|
"id": "rid-2"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
'https://api.marketplace.manifold.co/v1/resources?project_id=pid-2':
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"body": {
|
|
|
|
"label": "resource-1",
|
|
|
|
"name": "Resource 1"
|
|
|
|
},
|
|
|
|
"id": "rid-1"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"body": {
|
|
|
|
"label": "resource-3",
|
|
|
|
"name": "Resource 3"
|
|
|
|
},
|
|
|
|
"id": "rid-3"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
'https://api.marketplace.manifold.co/v1/resources?team_id=tid-1&project_id=pid-1':
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"body": {
|
|
|
|
"label": "resource-1",
|
|
|
|
"name": "Resource 1"
|
|
|
|
},
|
|
|
|
"id": "rid-1"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
'https://api.marketplace.manifold.co/v1/projects':
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"body": {
|
|
|
|
"label": "project-1",
|
|
|
|
"name": "Project 1",
|
|
|
|
},
|
|
|
|
"id": "pid-1",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"body": {
|
|
|
|
"label": "project-2",
|
|
|
|
"name": "Project 2",
|
|
|
|
},
|
|
|
|
"id": "pid-2",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
'https://api.marketplace.manifold.co/v1/projects?label=project-2':
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"body": {
|
|
|
|
"label": "project-2",
|
|
|
|
"name": "Project 2",
|
|
|
|
},
|
|
|
|
"id": "pid-2",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
'https://api.marketplace.manifold.co/v1/credentials?resource_id=rid-1':
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"body": {
|
|
|
|
"resource_id": "rid-1",
|
|
|
|
"values": {
|
|
|
|
"RESOURCE_TOKEN_1": "token-1",
|
|
|
|
"RESOURCE_TOKEN_2": "token-2"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"id": "cid-1",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
'https://api.marketplace.manifold.co/v1/credentials?resource_id=rid-2':
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"body": {
|
|
|
|
"resource_id": "rid-2",
|
|
|
|
"values": {
|
|
|
|
"RESOURCE_TOKEN_3": "token-3",
|
|
|
|
"RESOURCE_TOKEN_4": "token-4"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"id": "cid-2",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
'https://api.marketplace.manifold.co/v1/credentials?resource_id=rid-3':
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"body": {
|
|
|
|
"resource_id": "rid-3",
|
|
|
|
"values": {
|
|
|
|
"RESOURCE_TOKEN_1": "token-5",
|
|
|
|
"RESOURCE_TOKEN_2": "token-6"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"id": "cid-3",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
'https://api.identity.manifold.co/v1/teams':
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"id": "tid-1",
|
|
|
|
"body": {
|
|
|
|
"name": "Team 1",
|
|
|
|
"label": "team-1"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"id": "tid-2",
|
|
|
|
"body": {
|
|
|
|
"name": "Team 2",
|
|
|
|
"label": "team-2"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
def mock_fixture(open_url_mock, fixture=None, data=None, headers=None):
|
|
|
|
if not headers:
|
|
|
|
headers = {}
|
|
|
|
if fixture:
|
|
|
|
data = json.dumps(API_FIXTURES[fixture])
|
|
|
|
if 'content-type' not in headers:
|
|
|
|
headers['content-type'] = 'application/json'
|
|
|
|
|
|
|
|
open_url_mock.return_value.read.return_value = data
|
|
|
|
open_url_mock.return_value.headers = headers
|
|
|
|
|
|
|
|
|
|
|
|
class TestManifoldApiClient(unittest.TestCase):
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.open_url')
|
|
|
|
def test_request_sends_default_headers(self, open_url_mock):
|
|
|
|
mock_fixture(open_url_mock, data='hello')
|
|
|
|
client = ManifoldApiClient('token-123')
|
|
|
|
client.request('test', 'endpoint')
|
|
|
|
open_url_mock.assert_called_with('https://api.test.manifold.co/v1/endpoint',
|
|
|
|
headers={'Accept': '*/*', 'Authorization': 'Bearer token-123'},
|
|
|
|
http_agent='python-manifold-ansible-1.0.0')
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.open_url')
|
|
|
|
def test_request_decodes_json(self, open_url_mock):
|
|
|
|
mock_fixture(open_url_mock, fixture='https://api.marketplace.manifold.co/v1/resources')
|
|
|
|
client = ManifoldApiClient('token-123')
|
|
|
|
self.assertIsInstance(client.request('marketplace', 'resources'), list)
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.open_url')
|
|
|
|
def test_request_streams_text(self, open_url_mock):
|
|
|
|
mock_fixture(open_url_mock, data='hello', headers={'content-type': "text/plain"})
|
|
|
|
client = ManifoldApiClient('token-123')
|
|
|
|
self.assertEqual('hello', client.request('test', 'endpoint'))
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.open_url')
|
|
|
|
def test_request_processes_parameterized_headers(self, open_url_mock):
|
|
|
|
mock_fixture(open_url_mock, data='hello')
|
|
|
|
client = ManifoldApiClient('token-123')
|
|
|
|
client.request('test', 'endpoint', headers={'X-HEADER': 'MANIFOLD'})
|
|
|
|
open_url_mock.assert_called_with('https://api.test.manifold.co/v1/endpoint',
|
|
|
|
headers={'Accept': '*/*', 'Authorization': 'Bearer token-123',
|
|
|
|
'X-HEADER': 'MANIFOLD'},
|
|
|
|
http_agent='python-manifold-ansible-1.0.0')
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.open_url')
|
|
|
|
def test_request_passes_arbitrary_parameters(self, open_url_mock):
|
|
|
|
mock_fixture(open_url_mock, data='hello')
|
|
|
|
client = ManifoldApiClient('token-123')
|
|
|
|
client.request('test', 'endpoint', use_proxy=False, timeout=5)
|
|
|
|
open_url_mock.assert_called_with('https://api.test.manifold.co/v1/endpoint',
|
|
|
|
headers={'Accept': '*/*', 'Authorization': 'Bearer token-123'},
|
|
|
|
http_agent='python-manifold-ansible-1.0.0',
|
|
|
|
use_proxy=False, timeout=5)
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.open_url')
|
|
|
|
def test_request_raises_on_incorrect_json(self, open_url_mock):
|
|
|
|
mock_fixture(open_url_mock, data='noJson', headers={'content-type': "application/json"})
|
|
|
|
client = ManifoldApiClient('token-123')
|
|
|
|
with self.assertRaises(ApiError) as context:
|
|
|
|
client.request('test', 'endpoint')
|
|
|
|
self.assertEqual('JSON response can\'t be parsed while requesting https://api.test.manifold.co/v1/endpoint:\n'
|
|
|
|
'noJson',
|
|
|
|
str(context.exception))
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.open_url')
|
|
|
|
def test_request_raises_on_status_500(self, open_url_mock):
|
|
|
|
open_url_mock.side_effect = HTTPError('https://api.test.manifold.co/v1/endpoint',
|
|
|
|
500, 'Server error', {}, six.StringIO('ERROR'))
|
|
|
|
client = ManifoldApiClient('token-123')
|
|
|
|
with self.assertRaises(ApiError) as context:
|
|
|
|
client.request('test', 'endpoint')
|
|
|
|
self.assertEqual('Server returned: HTTP Error 500: Server error while requesting '
|
|
|
|
'https://api.test.manifold.co/v1/endpoint:\nERROR',
|
|
|
|
str(context.exception))
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.open_url')
|
|
|
|
def test_request_raises_on_bad_url(self, open_url_mock):
|
|
|
|
open_url_mock.side_effect = URLError('URL is invalid')
|
|
|
|
client = ManifoldApiClient('token-123')
|
|
|
|
with self.assertRaises(ApiError) as context:
|
|
|
|
client.request('test', 'endpoint')
|
|
|
|
self.assertEqual('Failed lookup url for https://api.test.manifold.co/v1/endpoint : <url'
|
|
|
|
'open error URL is invalid>',
|
|
|
|
str(context.exception))
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.open_url')
|
|
|
|
def test_request_raises_on_ssl_error(self, open_url_mock):
|
|
|
|
open_url_mock.side_effect = SSLValidationError('SSL Error')
|
|
|
|
client = ManifoldApiClient('token-123')
|
|
|
|
with self.assertRaises(ApiError) as context:
|
|
|
|
client.request('test', 'endpoint')
|
|
|
|
self.assertEqual('Error validating the server\'s certificate for https://api.test.manifold.co/v1/endpoint: '
|
|
|
|
'SSL Error',
|
|
|
|
str(context.exception))
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.open_url')
|
|
|
|
def test_request_raises_on_connection_error(self, open_url_mock):
|
|
|
|
open_url_mock.side_effect = ConnectionError('Unknown connection error')
|
|
|
|
client = ManifoldApiClient('token-123')
|
|
|
|
with self.assertRaises(ApiError) as context:
|
|
|
|
client.request('test', 'endpoint')
|
|
|
|
self.assertEqual('Error connecting to https://api.test.manifold.co/v1/endpoint: Unknown connection error',
|
|
|
|
str(context.exception))
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.open_url')
|
|
|
|
def test_get_resources_get_all(self, open_url_mock):
|
|
|
|
url = 'https://api.marketplace.manifold.co/v1/resources'
|
|
|
|
mock_fixture(open_url_mock, fixture=url)
|
|
|
|
client = ManifoldApiClient('token-123')
|
|
|
|
self.assertListEqual(API_FIXTURES[url], client.get_resources())
|
|
|
|
open_url_mock.assert_called_with(url,
|
|
|
|
headers={'Accept': '*/*', 'Authorization': 'Bearer token-123'},
|
|
|
|
http_agent='python-manifold-ansible-1.0.0')
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.open_url')
|
|
|
|
def test_get_resources_filter_label(self, open_url_mock):
|
|
|
|
url = 'https://api.marketplace.manifold.co/v1/resources?label=resource-1'
|
|
|
|
mock_fixture(open_url_mock, fixture=url)
|
|
|
|
client = ManifoldApiClient('token-123')
|
|
|
|
self.assertListEqual(API_FIXTURES[url], client.get_resources(label='resource-1'))
|
|
|
|
open_url_mock.assert_called_with(url,
|
|
|
|
headers={'Accept': '*/*', 'Authorization': 'Bearer token-123'},
|
|
|
|
http_agent='python-manifold-ansible-1.0.0')
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.open_url')
|
|
|
|
def test_get_resources_filter_team_and_project(self, open_url_mock):
|
|
|
|
url = 'https://api.marketplace.manifold.co/v1/resources?team_id=tid-1&project_id=pid-1'
|
|
|
|
mock_fixture(open_url_mock, fixture=url)
|
|
|
|
client = ManifoldApiClient('token-123')
|
|
|
|
self.assertListEqual(API_FIXTURES[url], client.get_resources(team_id='tid-1', project_id='pid-1'))
|
|
|
|
args, kwargs = open_url_mock.call_args
|
|
|
|
url_called = args[0]
|
|
|
|
# Dict order is not guaranteed, so an url may have querystring parameters order randomized
|
|
|
|
self.assertIn('team_id=tid-1', url_called)
|
|
|
|
self.assertIn('project_id=pid-1', url_called)
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.open_url')
|
|
|
|
def test_get_teams_get_all(self, open_url_mock):
|
|
|
|
url = 'https://api.identity.manifold.co/v1/teams'
|
|
|
|
mock_fixture(open_url_mock, fixture=url)
|
|
|
|
client = ManifoldApiClient('token-123')
|
|
|
|
self.assertListEqual(API_FIXTURES[url], client.get_teams())
|
|
|
|
open_url_mock.assert_called_with(url,
|
|
|
|
headers={'Accept': '*/*', 'Authorization': 'Bearer token-123'},
|
|
|
|
http_agent='python-manifold-ansible-1.0.0')
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.open_url')
|
|
|
|
def test_get_teams_filter_label(self, open_url_mock):
|
|
|
|
url = 'https://api.identity.manifold.co/v1/teams'
|
|
|
|
mock_fixture(open_url_mock, fixture=url)
|
|
|
|
client = ManifoldApiClient('token-123')
|
|
|
|
self.assertListEqual(API_FIXTURES[url][1:2], client.get_teams(label='team-2'))
|
|
|
|
open_url_mock.assert_called_with(url,
|
|
|
|
headers={'Accept': '*/*', 'Authorization': 'Bearer token-123'},
|
|
|
|
http_agent='python-manifold-ansible-1.0.0')
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.open_url')
|
|
|
|
def test_get_projects_get_all(self, open_url_mock):
|
|
|
|
url = 'https://api.marketplace.manifold.co/v1/projects'
|
|
|
|
mock_fixture(open_url_mock, fixture=url)
|
|
|
|
client = ManifoldApiClient('token-123')
|
|
|
|
self.assertListEqual(API_FIXTURES[url], client.get_projects())
|
|
|
|
open_url_mock.assert_called_with(url,
|
|
|
|
headers={'Accept': '*/*', 'Authorization': 'Bearer token-123'},
|
|
|
|
http_agent='python-manifold-ansible-1.0.0')
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.open_url')
|
|
|
|
def test_get_projects_filter_label(self, open_url_mock):
|
|
|
|
url = 'https://api.marketplace.manifold.co/v1/projects?label=project-2'
|
|
|
|
mock_fixture(open_url_mock, fixture=url)
|
|
|
|
client = ManifoldApiClient('token-123')
|
|
|
|
self.assertListEqual(API_FIXTURES[url], client.get_projects(label='project-2'))
|
|
|
|
open_url_mock.assert_called_with(url,
|
|
|
|
headers={'Accept': '*/*', 'Authorization': 'Bearer token-123'},
|
|
|
|
http_agent='python-manifold-ansible-1.0.0')
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.open_url')
|
|
|
|
def test_get_credentials(self, open_url_mock):
|
|
|
|
url = 'https://api.marketplace.manifold.co/v1/credentials?resource_id=rid-1'
|
|
|
|
mock_fixture(open_url_mock, fixture=url)
|
|
|
|
client = ManifoldApiClient('token-123')
|
|
|
|
self.assertListEqual(API_FIXTURES[url], client.get_credentials(resource_id='rid-1'))
|
|
|
|
open_url_mock.assert_called_with(url,
|
|
|
|
headers={'Accept': '*/*', 'Authorization': 'Bearer token-123'},
|
|
|
|
http_agent='python-manifold-ansible-1.0.0')
|
|
|
|
|
|
|
|
|
|
|
|
class TestLookupModule(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
|
|
self.lookup = LookupModule()
|
|
|
|
self.lookup._load_name = "manifold"
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.ManifoldApiClient')
|
|
|
|
def test_get_all(self, client_mock):
|
|
|
|
expected_result = [{'RESOURCE_TOKEN_1': 'token-1',
|
|
|
|
'RESOURCE_TOKEN_2': 'token-2',
|
|
|
|
'RESOURCE_TOKEN_3': 'token-3',
|
|
|
|
'RESOURCE_TOKEN_4': 'token-4'
|
|
|
|
}]
|
|
|
|
client_mock.return_value.get_resources.return_value = API_FIXTURES['https://api.marketplace.manifold.co/v1/resources']
|
|
|
|
client_mock.return_value.get_credentials.side_effect = lambda x: API_FIXTURES['https://api.marketplace.manifold.co/v1/'
|
|
|
|
'credentials?resource_id={0}'.format(x)]
|
|
|
|
self.assertListEqual(expected_result, self.lookup.run([], api_token='token-123'))
|
|
|
|
client_mock.assert_called_with('token-123')
|
|
|
|
client_mock.return_value.get_resources.assert_called_with(team_id=None, project_id=None)
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.ManifoldApiClient')
|
|
|
|
def test_get_one_resource(self, client_mock):
|
|
|
|
expected_result = [{'RESOURCE_TOKEN_3': 'token-3',
|
|
|
|
'RESOURCE_TOKEN_4': 'token-4'
|
|
|
|
}]
|
|
|
|
client_mock.return_value.get_resources.return_value = API_FIXTURES['https://api.marketplace.manifold.co/v1/resources?label=resource-2']
|
|
|
|
client_mock.return_value.get_credentials.side_effect = lambda x: API_FIXTURES['https://api.marketplace.manifold.co/v1/'
|
|
|
|
'credentials?resource_id={0}'.format(x)]
|
|
|
|
self.assertListEqual(expected_result, self.lookup.run(['resource-2'], api_token='token-123'))
|
|
|
|
client_mock.return_value.get_resources.assert_called_with(team_id=None, project_id=None, label='resource-2')
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.ManifoldApiClient')
|
|
|
|
def test_get_two_resources(self, client_mock):
|
|
|
|
expected_result = [{'RESOURCE_TOKEN_1': 'token-1',
|
|
|
|
'RESOURCE_TOKEN_2': 'token-2',
|
|
|
|
'RESOURCE_TOKEN_3': 'token-3',
|
|
|
|
'RESOURCE_TOKEN_4': 'token-4'
|
|
|
|
}]
|
|
|
|
client_mock.return_value.get_resources.return_value = API_FIXTURES['https://api.marketplace.manifold.co/v1/resources']
|
|
|
|
client_mock.return_value.get_credentials.side_effect = lambda x: API_FIXTURES['https://api.marketplace.manifold.co/v1/'
|
|
|
|
'credentials?resource_id={0}'.format(x)]
|
|
|
|
self.assertListEqual(expected_result, self.lookup.run(['resource-1', 'resource-2'], api_token='token-123'))
|
|
|
|
client_mock.assert_called_with('token-123')
|
|
|
|
client_mock.return_value.get_resources.assert_called_with(team_id=None, project_id=None)
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.display')
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.ManifoldApiClient')
|
|
|
|
def test_get_resources_with_same_credential_names(self, client_mock, display_mock):
|
|
|
|
expected_result = [{'RESOURCE_TOKEN_1': 'token-5',
|
|
|
|
'RESOURCE_TOKEN_2': 'token-6'
|
|
|
|
}]
|
|
|
|
client_mock.return_value.get_resources.return_value = API_FIXTURES['https://api.marketplace.manifold.co/v1/resources?project_id=pid-2']
|
|
|
|
client_mock.return_value.get_projects.return_value = API_FIXTURES['https://api.marketplace.manifold.co/v1/projects?label=project-2']
|
|
|
|
client_mock.return_value.get_credentials.side_effect = lambda x: API_FIXTURES['https://api.marketplace.manifold.co/v1/'
|
|
|
|
'credentials?resource_id={0}'.format(x)]
|
|
|
|
self.assertListEqual(expected_result, self.lookup.run([], api_token='token-123', project='project-2'))
|
|
|
|
client_mock.assert_called_with('token-123')
|
|
|
|
display_mock.warning.assert_has_calls([
|
|
|
|
call("'RESOURCE_TOKEN_1' with label 'resource-1' was replaced by resource data with label 'resource-3'"),
|
|
|
|
call("'RESOURCE_TOKEN_2' with label 'resource-1' was replaced by resource data with label 'resource-3'")],
|
|
|
|
any_order=True
|
|
|
|
)
|
|
|
|
client_mock.return_value.get_resources.assert_called_with(team_id=None, project_id='pid-2')
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.ManifoldApiClient')
|
|
|
|
def test_filter_by_team(self, client_mock):
|
|
|
|
expected_result = [{'RESOURCE_TOKEN_1': 'token-1',
|
|
|
|
'RESOURCE_TOKEN_2': 'token-2'
|
|
|
|
}]
|
|
|
|
client_mock.return_value.get_resources.return_value = API_FIXTURES['https://api.marketplace.manifold.co/v1/resources?team_id=tid-1']
|
|
|
|
client_mock.return_value.get_teams.return_value = API_FIXTURES['https://api.identity.manifold.co/v1/teams'][0:1]
|
|
|
|
client_mock.return_value.get_credentials.side_effect = lambda x: API_FIXTURES['https://api.marketplace.manifold.co/v1/'
|
|
|
|
'credentials?resource_id={0}'.format(x)]
|
|
|
|
self.assertListEqual(expected_result, self.lookup.run([], api_token='token-123', team='team-1'))
|
|
|
|
client_mock.assert_called_with('token-123')
|
|
|
|
client_mock.return_value.get_resources.assert_called_with(team_id='tid-1', project_id=None)
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.ManifoldApiClient')
|
|
|
|
def test_filter_by_project(self, client_mock):
|
|
|
|
expected_result = [{'RESOURCE_TOKEN_3': 'token-3',
|
|
|
|
'RESOURCE_TOKEN_4': 'token-4'
|
|
|
|
}]
|
|
|
|
client_mock.return_value.get_resources.return_value = API_FIXTURES['https://api.marketplace.manifold.co/v1/resources?project_id=pid-1']
|
|
|
|
client_mock.return_value.get_projects.return_value = API_FIXTURES['https://api.marketplace.manifold.co/v1/projects'][0:1]
|
|
|
|
client_mock.return_value.get_credentials.side_effect = lambda x: API_FIXTURES['https://api.marketplace.manifold.co/v1/'
|
|
|
|
'credentials?resource_id={0}'.format(x)]
|
|
|
|
self.assertListEqual(expected_result, self.lookup.run([], api_token='token-123', project='project-1'))
|
|
|
|
client_mock.assert_called_with('token-123')
|
|
|
|
client_mock.return_value.get_resources.assert_called_with(team_id=None, project_id='pid-1')
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.ManifoldApiClient')
|
|
|
|
def test_filter_by_team_and_project(self, client_mock):
|
|
|
|
expected_result = [{'RESOURCE_TOKEN_1': 'token-1',
|
|
|
|
'RESOURCE_TOKEN_2': 'token-2'
|
|
|
|
}]
|
|
|
|
client_mock.return_value.get_resources.return_value = API_FIXTURES['https://api.marketplace.manifold.co/v1/resources?team_id=tid-1&project_id=pid-1']
|
|
|
|
client_mock.return_value.get_teams.return_value = API_FIXTURES['https://api.identity.manifold.co/v1/teams'][0:1]
|
|
|
|
client_mock.return_value.get_projects.return_value = API_FIXTURES['https://api.marketplace.manifold.co/v1/projects'][0:1]
|
|
|
|
client_mock.return_value.get_credentials.side_effect = lambda x: API_FIXTURES['https://api.marketplace.manifold.co/v1/'
|
|
|
|
'credentials?resource_id={0}'.format(x)]
|
|
|
|
self.assertListEqual(expected_result, self.lookup.run([], api_token='token-123', project='project-1'))
|
|
|
|
client_mock.assert_called_with('token-123')
|
|
|
|
client_mock.return_value.get_resources.assert_called_with(team_id=None, project_id='pid-1')
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.ManifoldApiClient')
|
|
|
|
def test_raise_team_doesnt_exist(self, client_mock):
|
|
|
|
client_mock.return_value.get_teams.return_value = []
|
|
|
|
with self.assertRaises(AnsibleError) as context:
|
|
|
|
self.lookup.run([], api_token='token-123', team='no-team')
|
|
|
|
self.assertEqual("Team 'no-team' does not exist",
|
|
|
|
str(context.exception))
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.ManifoldApiClient')
|
|
|
|
def test_raise_project_doesnt_exist(self, client_mock):
|
|
|
|
client_mock.return_value.get_projects.return_value = []
|
|
|
|
with self.assertRaises(AnsibleError) as context:
|
|
|
|
self.lookup.run([], api_token='token-123', project='no-project')
|
|
|
|
self.assertEqual("Project 'no-project' does not exist",
|
|
|
|
str(context.exception))
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.ManifoldApiClient')
|
|
|
|
def test_raise_resource_doesnt_exist(self, client_mock):
|
|
|
|
client_mock.return_value.get_resources.return_value = API_FIXTURES['https://api.marketplace.manifold.co/v1/resources']
|
|
|
|
with self.assertRaises(AnsibleError) as context:
|
|
|
|
self.lookup.run(['resource-1', 'no-resource-1', 'no-resource-2'], api_token='token-123')
|
|
|
|
self.assertEqual("Resource(s) no-resource-1, no-resource-2 do not exist",
|
|
|
|
str(context.exception))
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.ManifoldApiClient')
|
|
|
|
def test_catch_api_error(self, client_mock):
|
|
|
|
client_mock.side_effect = ApiError('Generic error')
|
|
|
|
with self.assertRaises(AnsibleError) as context:
|
|
|
|
self.lookup.run([], api_token='token-123')
|
|
|
|
self.assertEqual("API Error: Generic error",
|
|
|
|
str(context.exception))
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.ManifoldApiClient')
|
|
|
|
def test_catch_unhandled_exception(self, client_mock):
|
|
|
|
client_mock.side_effect = Exception('Unknown error')
|
|
|
|
with self.assertRaises(AnsibleError) as context:
|
|
|
|
self.lookup.run([], api_token='token-123')
|
|
|
|
self.assertTrue('Exception: Unknown error' in str(context.exception))
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.os.getenv')
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.ManifoldApiClient')
|
|
|
|
def test_falls_back_to_env_var(self, client_mock, getenv_mock):
|
|
|
|
getenv_mock.return_value = 'token-321'
|
|
|
|
client_mock.return_value.get_resources.return_value = []
|
|
|
|
client_mock.return_value.get_credentials.return_value = []
|
|
|
|
self.lookup.run([])
|
|
|
|
getenv_mock.assert_called_with('MANIFOLD_API_TOKEN')
|
|
|
|
client_mock.assert_called_with('token-321')
|
|
|
|
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.os.getenv')
|
|
|
|
@patch('ansible_collections.community.general.plugins.lookup.manifold.ManifoldApiClient')
|
|
|
|
def test_falls_raises_on_no_token(self, client_mock, getenv_mock):
|
|
|
|
getenv_mock.return_value = None
|
|
|
|
client_mock.return_value.get_resources.return_value = []
|
|
|
|
client_mock.return_value.get_credentials.return_value = []
|
|
|
|
with self.assertRaises(AnsibleError) as context:
|
|
|
|
self.lookup.run([])
|
|
|
|
self.assertEqual('API token is required. Please set api_token parameter or MANIFOLD_API_TOKEN env var',
|
|
|
|
str(context.exception))
|