text: # Copyright (c) 2018 Cisco and/or its affiliates.
  #
  # This file is part of Ansible
  #
  # Ansible is free software: you can redistribute it and/or modify
  # it under the terms of the GNU General Public License as published by
  # the Free Software Foundation, either version 3 of the License, or
  # (at your option) any later version.
  #
  # Ansible is distributed in the hope that it will be useful,
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  # GNU General Public License for more details.
  #
  # You should have received a copy of the GNU General Public License
  # along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
  #
  
  from __future__ import absolute_import, division, print_function
  __metaclass__ = type
  
  import pytest
  
  from ansible.module_utils import basic
  from ansible_collections.community.network.plugins.module_utils.network.ftd.common import HTTPMethod
  from ansible_collections.community.network.plugins.module_utils.network.ftd.fdm_swagger_client import FILE_MODEL_NAME, OperationField
  from ansible_collections.community.network.plugins.modules.network.ftd import ftd_file_download
  from ansible_collections.community.network.tests.unit.plugins.modules.utils import set_module_args, exit_json, fail_json, AnsibleFailJson, AnsibleExitJson
  
  
  class TestFtdFileDownload(object):
      module = ftd_file_download
  
      @pytest.fixture(autouse=True)
      def module_mock(self, mocker):
          return mocker.patch.multiple(basic.AnsibleModule, exit_json=exit_json, fail_json=fail_json)
  
      @pytest.fixture
      def connection_mock(self, mocker):
          connection_class_mock = mocker.patch('ansible_collections.community.network.plugins.modules.network.ftd.ftd_file_download.Connection')
          return connection_class_mock.return_value
  
      @pytest.mark.parametrize("missing_arg", ['operation', 'destination'])
      def test_module_should_fail_without_required_args(self, missing_arg):
          module_args = {'operation': 'downloadFile', 'destination': '/tmp'}
          del module_args[missing_arg]
          set_module_args(module_args)
  
          with pytest.raises(AnsibleFailJson) as ex:
              self.module.main()
  
          assert 'missing required arguments: %s' % missing_arg in str(ex.value)
  
      def test_module_should_fail_when_no_operation_spec_found(self, connection_mock):
          connection_mock.get_operation_spec.return_value = None
          set_module_args({'operation': 'nonExistingDownloadOperation', 'destination': '/tmp'})
  
          with pytest.raises(AnsibleFailJson) as ex:
              self.module.main()
  
          result = ex.value.args[0]
          assert result['failed']
          assert result['msg'] == 'Operation with specified name is not found: nonExistingDownloadOperation'
  
      def test_module_should_fail_when_not_download_operation_specified(self, connection_mock):
          connection_mock.get_operation_spec.return_value = {
              OperationField.METHOD: HTTPMethod.GET,
              OperationField.URL: '/object',
              OperationField.MODEL_NAME: 'NetworkObject'
          }
          set_module_args({'operation': 'nonDownloadOperation', 'destination': '/tmp'})
  
          with pytest.raises(AnsibleFailJson) as ex:
              self.module.main()
  
          result = ex.value.args[0]
          assert result['failed']
          assert result['msg'] == 'Invalid download operation: nonDownloadOperation. ' \
                                  'The operation must make GET request and return a file.'
  
      def test_module_should_call_download_and_return(self, connection_mock):
          connection_mock.validate_path_params.return_value = (True, None)
          connection_mock.get_operation_spec.return_value = {
              OperationField.METHOD: HTTPMethod.GET,
              OperationField.URL: '/file/{objId}',
              OperationField.MODEL_NAME: FILE_MODEL_NAME
          }
  
          set_module_args({
              'operation': 'downloadFile',
              'path_params': {'objId': '12'},
              'destination': '/tmp'
          })
          with pytest.raises(AnsibleExitJson) as ex:
              self.module.main()
  
          result = ex.value.args[0]
          assert not result['changed']
          connection_mock.download_file.assert_called_once_with('/file/{objId}', '/tmp', {'objId': '12'})
  