Repository: cisagov/manage.get.gov

Issue:
Check Domain availability via epp-Testing
### Issue Description

When adding the /availability endpoint we will need to send a CheckDomain request to epp to see if the domain is available. This epp function is already implemented in domain.py and is called available(). It just needs to be tested and updated if the test show any problem with the implementation

### AC

- [x] unit tests added for available
- [x] manually test via sandbox with OT&E to be sure that this is working as expected 
- [x] update the implementation as needed or desired
- [x] in your tests, ensure that this function can be called by just doing Domain.available() and not by having an instance of a domain

### Additional Context (optional)

This must be tested by using Domain.available because the /availability endpoint (when implemented) will not have access to any particular domain object and this function needs to be able to be performed on its own.

### Issue Link
blocks: #1015 


Discussion:

Resolving patch:
diff --git a/src/epplibwrapper/__init__.py b/src/epplibwrapper/__init__.py
--- a/src/epplibwrapper/__init__.py
+++ b/src/epplibwrapper/__init__.py
@@ -45,6 +45,7 @@
     from .client import CLIENT, commands
     from .errors import RegistryError, ErrorCode
     from epplib.models import common
+    from epplib import responses
 except ImportError:
     pass
 
@@ -52,6 +53,7 @@
     "CLIENT",
     "commands",
     "common",
+    "responses",
     "ErrorCode",
     "RegistryError",
 ]


Test patch:
diff --git a/src/registrar/tests/test_models_domain.py b/src/registrar/tests/test_models_domain.py
--- a/src/registrar/tests/test_models_domain.py
+++ b/src/registrar/tests/test_models_domain.py
@@ -5,7 +5,7 @@
 """
 from django.test import TestCase
 from django.db.utils import IntegrityError
-from unittest.mock import patch, call
+from unittest.mock import MagicMock, patch, call
 import datetime
 from registrar.models import Domain
 
@@ -20,6 +20,7 @@
 from epplibwrapper import (
     commands,
     common,
+    responses,
     RegistryError,
     ErrorCode,
 )
@@ -268,6 +269,114 @@ def tearDown(self) -> None:
         super().tearDown()
 
 
+class TestDomainAvailable(MockEppLib):
+    """Test Domain.available"""
+
+    # No SetUp or tearDown necessary for these tests
+
+    def test_domain_available(self):
+        """
+        Scenario: Testing whether an available domain is available
+            Should return True
+
+            Mock response to mimic EPP Response
+            Validate CheckDomain command is called
+            Validate response given mock
+        """
+
+        def side_effect(_request, cleaned):
+            return MagicMock(
+                res_data=[
+                    responses.check.CheckDomainResultData(
+                        name="available.gov", avail=True, reason=None
+                    )
+                ],
+            )
+
+        patcher = patch("registrar.models.domain.registry.send")
+        mocked_send = patcher.start()
+        mocked_send.side_effect = side_effect
+
+        available = Domain.available("available.gov")
+        mocked_send.assert_has_calls(
+            [
+                call(
+                    commands.CheckDomain(
+                        ["available.gov"],
+                    ),
+                    cleaned=True,
+                )
+            ]
+        )
+        self.assertTrue(available)
+        patcher.stop()
+
+    def test_domain_unavailable(self):
+        """
+        Scenario: Testing whether an unavailable domain is available
+            Should return False
+
+            Mock response to mimic EPP Response
+            Validate CheckDomain command is called
+            Validate response given mock
+        """
+
+        def side_effect(_request, cleaned):
+            return MagicMock(
+                res_data=[
+                    responses.check.CheckDomainResultData(
+                        name="unavailable.gov", avail=False, reason="In Use"
+                    )
+                ],
+            )
+
+        patcher = patch("registrar.models.domain.registry.send")
+        mocked_send = patcher.start()
+        mocked_send.side_effect = side_effect
+
+        available = Domain.available("unavailable.gov")
+        mocked_send.assert_has_calls(
+            [
+                call(
+                    commands.CheckDomain(
+                        ["unavailable.gov"],
+                    ),
+                    cleaned=True,
+                )
+            ]
+        )
+        self.assertFalse(available)
+        patcher.stop()
+
+    def test_domain_available_with_value_error(self):
+        """
+        Scenario: Testing whether an invalid domain is available
+            Should throw ValueError
+
+            Validate ValueError is raised
+        """
+        with self.assertRaises(ValueError):
+            Domain.available("invalid-string")
+
+    def test_domain_available_unsuccessful(self):
+        """
+        Scenario: Testing behavior when registry raises a RegistryError
+
+            Validate RegistryError is raised
+        """
+
+        def side_effect(_request, cleaned):
+            raise RegistryError(code=ErrorCode.COMMAND_SYNTAX_ERROR)
+
+        patcher = patch("registrar.models.domain.registry.send")
+        mocked_send = patcher.start()
+        mocked_send.side_effect = side_effect
+
+        with self.assertRaises(RegistryError):
+            Domain.available("raises-error.gov")
+        patcher.stop()
+
+
 class TestRegistrantContacts(MockEppLib):
     """Rule: Registrants may modify their WHOIS data"""