"""Unit tests for nautobot_device_onboarding.netdev_keeper module and its classes.

(c) 2020-2021 Network To Code
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
  http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

from socket import gaierror
from unittest import mock

from django.test import TestCase
from nautobot.dcim.models import Site, DeviceRole, Platform

from nautobot_device_onboarding.exceptions import OnboardException
from nautobot_device_onboarding.helpers import onboarding_task_fqdn_to_ip
from nautobot_device_onboarding.models import OnboardingTask


class NetdevKeeperTestCase(TestCase):
    """Test the NetdevKeeper Class."""

    def setUp(self):
        """Create a superuser and token for API calls."""
        self.site1 = Site.objects.create(name="USWEST", slug="uswest")
        self.device_role1 = DeviceRole.objects.create(name="Firewall", slug="firewall")

        self.platform1 = Platform.objects.create(name="JunOS", slug="junos", napalm_driver="junos")
        # self.platform2 = Platform.objects.create(name="Cisco NX-OS", slug="cisco-nx-os")

        self.onboarding_task4 = OnboardingTask.objects.create(
            ip_address="ntc123.local", site=self.site1, role=self.device_role1, platform=self.platform1
        )

        self.onboarding_task5 = OnboardingTask.objects.create(
            ip_address="bad.local", site=self.site1, role=self.device_role1, platform=self.platform1
        )

        self.onboarding_task7 = OnboardingTask.objects.create(
            ip_address="192.0.2.1/32", site=self.site1, role=self.device_role1, platform=self.platform1
        )

    @mock.patch("nautobot_device_onboarding.helpers.socket.gethostbyname")
    def test_check_ip(self, mock_get_hostbyname):
        """Check DNS to IP address."""
        # Look up response value
        mock_get_hostbyname.return_value = "192.0.2.1"

        # FQDN -> IP
        onboarding_task_fqdn_to_ip(ot=self.onboarding_task4)

        # Run the check to change the IP address
        self.assertEqual(self.onboarding_task4.ip_address, "192.0.2.1")

    @mock.patch("nautobot_device_onboarding.helpers.socket.gethostbyname")
    def test_failed_check_ip(self, mock_get_hostbyname):
        """Check DNS to IP address failing."""
        # Look up a failed response
        mock_get_hostbyname.side_effect = gaierror(8)

        # Check for bad.local raising an exception
        with self.assertRaises(OnboardException) as exc_info:
            onboarding_task_fqdn_to_ip(ot=self.onboarding_task5)
            self.assertEqual(exc_info.exception.message, "ERROR failed to complete DNS lookup: bad.local")
            self.assertEqual(exc_info.exception.reason, "fail-dns")

        # Check for exception with prefix address entered
        with self.assertRaises(OnboardException) as exc_info:
            onboarding_task_fqdn_to_ip(ot=self.onboarding_task7)
            self.assertEqual(exc_info.exception.reason, "fail-prefix")
            self.assertEqual(exc_info.exception.message, "ERROR appears a prefix was entered: 192.0.2.1/32")

[((49, 5, 49, 74), 'unittest.mock.patch', 'mock.patch', ({(49, 16, 49, 73): '"""nautobot_device_onboarding.helpers.socket.gethostbyname"""'}, {}), "('nautobot_device_onboarding.helpers.socket.gethostbyname')", False, 'from unittest import mock\n'), ((61, 5, 61, 74), 'unittest.mock.patch', 'mock.patch', ({(61, 16, 61, 73): '"""nautobot_device_onboarding.helpers.socket.gethostbyname"""'}, {}), "('nautobot_device_onboarding.helpers.socket.gethostbyname')", False, 'from unittest import mock\n'), ((31, 21, 31, 70), 'nautobot.dcim.models.Site.objects.create', 'Site.objects.create', (), '', False, 'from nautobot.dcim.models import Site, DeviceRole, Platform\n'), ((32, 28, 32, 87), 'nautobot.dcim.models.DeviceRole.objects.create', 'DeviceRole.objects.create', (), '', False, 'from nautobot.dcim.models import Site, DeviceRole, Platform\n'), ((34, 25, 34, 99), 'nautobot.dcim.models.Platform.objects.create', 'Platform.objects.create', (), '', False, 'from nautobot.dcim.models import Site, DeviceRole, Platform\n'), ((37, 32, 39, 9), 'nautobot_device_onboarding.models.OnboardingTask.objects.create', 'OnboardingTask.objects.create', (), '', False, 'from nautobot_device_onboarding.models import OnboardingTask\n'), ((41, 32, 43, 9), 'nautobot_device_onboarding.models.OnboardingTask.objects.create', 'OnboardingTask.objects.create', (), '', False, 'from nautobot_device_onboarding.models import OnboardingTask\n'), ((45, 32, 47, 9), 'nautobot_device_onboarding.models.OnboardingTask.objects.create', 'OnboardingTask.objects.create', (), '', False, 'from nautobot_device_onboarding.models import OnboardingTask\n'), ((56, 8, 56, 60), 'nautobot_device_onboarding.helpers.onboarding_task_fqdn_to_ip', 'onboarding_task_fqdn_to_ip', (), '', False, 'from nautobot_device_onboarding.helpers import onboarding_task_fqdn_to_ip\n'), ((65, 42, 65, 53), 'socket.gaierror', 'gaierror', ({(65, 51, 65, 52): '8'}, {}), '(8)', False, 'from socket import gaierror\n'), ((69, 12, 69, 64), 'nautobot_device_onboarding.helpers.onboarding_task_fqdn_to_ip', 'onboarding_task_fqdn_to_ip', (), '', False, 'from nautobot_device_onboarding.helpers import onboarding_task_fqdn_to_ip\n'), ((75, 12, 75, 64), 'nautobot_device_onboarding.helpers.onboarding_task_fqdn_to_ip', 'onboarding_task_fqdn_to_ip', (), '', False, 'from nautobot_device_onboarding.helpers import onboarding_task_fqdn_to_ip\n')]