diff --git a/src/djangooidc/tests/test_views.py b/src/djangooidc/tests/test_views.py index 63b23df96..4193f723b 100644 --- a/src/djangooidc/tests/test_views.py +++ b/src/djangooidc/tests/test_views.py @@ -35,155 +35,155 @@ class ViewsTest(TestCase): pass def test_openid_sets_next(self, mock_client): - # setup - callback_url = reverse("openid_login_callback") - # mock - mock_client.create_authn_request.side_effect = self.say_hi - mock_client.get_default_acr_value.side_effect = self.create_acr - # test - response = self.client.get(reverse("login"), {"next": callback_url}) - # assert - session = mock_client.create_authn_request.call_args[0][0] - self.assertEqual(session["next"], callback_url) - self.assertEqual(response.status_code, 200) - self.assertContains(response, "Hi") + with less_console_noise(): + # setup + callback_url = reverse("openid_login_callback") + # mock + mock_client.create_authn_request.side_effect = self.say_hi + mock_client.get_default_acr_value.side_effect = self.create_acr + # test + response = self.client.get(reverse("login"), {"next": callback_url}) + # assert + session = mock_client.create_authn_request.call_args[0][0] + self.assertEqual(session["next"], callback_url) + self.assertEqual(response.status_code, 200) + self.assertContains(response, "Hi") def test_openid_raises(self, mock_client): - # mock - mock_client.create_authn_request.side_effect = Exception("Test") - # test with less_console_noise(): + # mock + mock_client.create_authn_request.side_effect = Exception("Test") + # test response = self.client.get(reverse("login")) - # assert - self.assertEqual(response.status_code, 500) - self.assertTemplateUsed(response, "500.html") - self.assertIn("Server error", response.content.decode("utf-8")) + # assert + self.assertEqual(response.status_code, 500) + self.assertTemplateUsed(response, "500.html") + self.assertIn("Server error", response.content.decode("utf-8")) def test_callback_with_no_session_state(self, mock_client): """If the local session is None (ie the server restarted while user was logged out), we do not throw an exception. Rather, we attempt to login again.""" - # mock - mock_client.get_default_acr_value.side_effect = self.create_acr - mock_client.callback.side_effect = NoStateDefined() - # test with less_console_noise(): + # mock + mock_client.get_default_acr_value.side_effect = self.create_acr + mock_client.callback.side_effect = NoStateDefined() + # test response = self.client.get(reverse("openid_login_callback")) - # assert - self.assertEqual(response.status_code, 302) - self.assertEqual(response.url, "/") + # assert + self.assertEqual(response.status_code, 302) + self.assertEqual(response.url, "/") def test_login_callback_reads_next(self, mock_client): - # setup - session = self.client.session - session["next"] = reverse("logout") - session.save() - # mock - mock_client.callback.side_effect = self.user_info - # test - with patch("djangooidc.views.requires_step_up_auth", return_value=False), less_console_noise(): - response = self.client.get(reverse("openid_login_callback")) - # assert - self.assertEqual(response.status_code, 302) - self.assertEqual(response.url, reverse("logout")) + with less_console_noise(): + # setup + session = self.client.session + session["next"] = reverse("logout") + session.save() + # mock + mock_client.callback.side_effect = self.user_info + # test + with patch("djangooidc.views.requires_step_up_auth", return_value=False), less_console_noise(): + response = self.client.get(reverse("openid_login_callback")) + # assert + self.assertEqual(response.status_code, 302) + self.assertEqual(response.url, reverse("logout")) def test_login_callback_no_step_up_auth(self, mock_client): """Walk through login_callback when requires_step_up_auth returns False and assert that we have a redirect to /""" - # setup - session = self.client.session - session.save() - # mock - mock_client.callback.side_effect = self.user_info - # test - with patch("djangooidc.views.requires_step_up_auth", return_value=False), less_console_noise(): - response = self.client.get(reverse("openid_login_callback")) - # assert - self.assertEqual(response.status_code, 302) - self.assertEqual(response.url, "/") + with less_console_noise(): + # setup + session = self.client.session + session.save() + # mock + mock_client.callback.side_effect = self.user_info + # test + with patch("djangooidc.views.requires_step_up_auth", return_value=False), less_console_noise(): + response = self.client.get(reverse("openid_login_callback")) + # assert + self.assertEqual(response.status_code, 302) + self.assertEqual(response.url, "/") def test_requires_step_up_auth(self, mock_client): """Invoke login_callback passing it a request when requires_step_up_auth returns True and assert that session is updated and create_authn_request (mock) is called.""" - # Configure the mock to return an expected value for get_step_up_acr_value - mock_client.return_value.get_step_up_acr_value.return_value = "step_up_acr_value" - - # Create a mock request - request = self.factory.get("/some-url") - request.session = {"acr_value": ""} - - # Ensure that the CLIENT instance used in login_callback is the mock - # patch requires_step_up_auth to return True - with patch("djangooidc.views.requires_step_up_auth", return_value=True), patch( - "djangooidc.views.CLIENT.create_authn_request", return_value=MagicMock() - ) as mock_create_authn_request: - login_callback(request) - - # create_authn_request only gets called when requires_step_up_auth is True - # and it changes this acr_value in request.session - - # Assert that acr_value is no longer empty string - self.assertNotEqual(request.session["acr_value"], "") - # And create_authn_request was called again - mock_create_authn_request.assert_called_once() + with less_console_noise(): + # Configure the mock to return an expected value for get_step_up_acr_value + mock_client.return_value.get_step_up_acr_value.return_value = "step_up_acr_value" + # Create a mock request + request = self.factory.get("/some-url") + request.session = {"acr_value": ""} + # Ensure that the CLIENT instance used in login_callback is the mock + # patch requires_step_up_auth to return True + with patch("djangooidc.views.requires_step_up_auth", return_value=True), patch( + "djangooidc.views.CLIENT.create_authn_request", return_value=MagicMock() + ) as mock_create_authn_request: + login_callback(request) + # create_authn_request only gets called when requires_step_up_auth is True + # and it changes this acr_value in request.session + # Assert that acr_value is no longer empty string + self.assertNotEqual(request.session["acr_value"], "") + # And create_authn_request was called again + mock_create_authn_request.assert_called_once() def test_does_not_requires_step_up_auth(self, mock_client): """Invoke login_callback passing it a request when requires_step_up_auth returns False and assert that session is not updated and create_authn_request (mock) is not called. Possibly redundant with test_login_callback_requires_step_up_auth""" - # Create a mock request - request = self.factory.get("/some-url") - request.session = {"acr_value": ""} - - # Ensure that the CLIENT instance used in login_callback is the mock - # patch requires_step_up_auth to return False - with patch("djangooidc.views.requires_step_up_auth", return_value=False), patch( - "djangooidc.views.CLIENT.create_authn_request", return_value=MagicMock() - ) as mock_create_authn_request: - login_callback(request) - - # create_authn_request only gets called when requires_step_up_auth is True - # and it changes this acr_value in request.session - - # Assert that acr_value is NOT updated by testing that it is still an empty string - self.assertEqual(request.session["acr_value"], "") - # Assert create_authn_request was not called - mock_create_authn_request.assert_not_called() + with less_console_noise(): + # Create a mock request + request = self.factory.get("/some-url") + request.session = {"acr_value": ""} + # Ensure that the CLIENT instance used in login_callback is the mock + # patch requires_step_up_auth to return False + with patch("djangooidc.views.requires_step_up_auth", return_value=False), patch( + "djangooidc.views.CLIENT.create_authn_request", return_value=MagicMock() + ) as mock_create_authn_request: + login_callback(request) + # create_authn_request only gets called when requires_step_up_auth is True + # and it changes this acr_value in request.session + # Assert that acr_value is NOT updated by testing that it is still an empty string + self.assertEqual(request.session["acr_value"], "") + # Assert create_authn_request was not called + mock_create_authn_request.assert_not_called() @patch("djangooidc.views.authenticate") def test_login_callback_raises(self, mock_auth, mock_client): - # mock - mock_client.callback.side_effect = self.user_info - mock_auth.return_value = None - # test - with patch("djangooidc.views.requires_step_up_auth", return_value=False), less_console_noise(): - response = self.client.get(reverse("openid_login_callback")) - # assert - self.assertEqual(response.status_code, 401) - self.assertTemplateUsed(response, "401.html") - self.assertIn("Unauthorized", response.content.decode("utf-8")) + with less_console_noise(): + # mock + mock_client.callback.side_effect = self.user_info + mock_auth.return_value = None + # test + with patch("djangooidc.views.requires_step_up_auth", return_value=False), less_console_noise(): + response = self.client.get(reverse("openid_login_callback")) + # assert + self.assertEqual(response.status_code, 401) + self.assertTemplateUsed(response, "401.html") + self.assertIn("Unauthorized", response.content.decode("utf-8")) def test_logout_redirect_url(self, mock_client): - # setup - session = self.client.session - session["state"] = "TEST" # nosec B105 - session.save() - # mock - mock_client.callback.side_effect = self.user_info - mock_client.registration_response = {"post_logout_redirect_uris": ["http://example.com/back"]} - mock_client.provider_info = {"end_session_endpoint": "http://example.com/log_me_out"} - mock_client.client_id = "TEST" - # test with less_console_noise(): - response = self.client.get(reverse("logout")) - # assert - expected = ( - "http://example.com/log_me_out?client_id=TEST&state" - "=TEST&post_logout_redirect_uri=http%3A%2F%2Fexample.com%2Fback" - ) - actual = response.url - self.assertEqual(response.status_code, 302) - self.assertEqual(actual, expected) + # setup + session = self.client.session + session["state"] = "TEST" # nosec B105 + session.save() + # mock + mock_client.callback.side_effect = self.user_info + mock_client.registration_response = {"post_logout_redirect_uris": ["http://example.com/back"]} + mock_client.provider_info = {"end_session_endpoint": "http://example.com/log_me_out"} + mock_client.client_id = "TEST" + # test + with less_console_noise(): + response = self.client.get(reverse("logout")) + # assert + expected = ( + "http://example.com/log_me_out?client_id=TEST&state" + "=TEST&post_logout_redirect_uri=http%3A%2F%2Fexample.com%2Fback" + ) + actual = response.url + self.assertEqual(response.status_code, 302) + self.assertEqual(actual, expected) @patch("djangooidc.views.auth_logout") def test_logout_always_logs_out(self, mock_logout, _): @@ -194,12 +194,13 @@ class ViewsTest(TestCase): self.assertTrue(mock_logout.called) def test_logout_callback_redirects(self, _): - # setup - session = self.client.session - session["next"] = reverse("logout") - session.save() - # test - response = self.client.get(reverse("openid_logout_callback")) - # assert - self.assertEqual(response.status_code, 302) - self.assertEqual(response.url, reverse("logout")) + with less_console_noise(): + # setup + session = self.client.session + session["next"] = reverse("logout") + session.save() + # test + response = self.client.get(reverse("openid_logout_callback")) + # assert + self.assertEqual(response.status_code, 302) + self.assertEqual(response.url, reverse("logout")) diff --git a/src/epplibwrapper/tests/common.py b/src/epplibwrapper/tests/common.py new file mode 100644 index 000000000..122965ae8 --- /dev/null +++ b/src/epplibwrapper/tests/common.py @@ -0,0 +1,51 @@ +import os +import logging + +from contextlib import contextmanager + + +def get_handlers(): + """Obtain pointers to all StreamHandlers.""" + handlers = {} + + rootlogger = logging.getLogger() + for h in rootlogger.handlers: + if isinstance(h, logging.StreamHandler): + handlers[h.name] = h + + for logger in logging.Logger.manager.loggerDict.values(): + if not isinstance(logger, logging.PlaceHolder): + for h in logger.handlers: + if isinstance(h, logging.StreamHandler): + handlers[h.name] = h + + return handlers + + +@contextmanager +def less_console_noise(): + """ + Context manager to use in tests to silence console logging. + + This is helpful on tests which trigger console messages + (such as errors) which are normal and expected. + + It can easily be removed to debug a failing test. + """ + restore = {} + handlers = get_handlers() + devnull = open(os.devnull, "w") + + # redirect all the streams + for handler in handlers.values(): + prior = handler.setStream(devnull) + restore[handler.name] = prior + try: + # run the test + yield + finally: + # restore the streams + for handler in handlers.values(): + handler.setStream(restore[handler.name]) + # close the file we opened + devnull.close() diff --git a/src/epplibwrapper/tests/test_pool.py b/src/epplibwrapper/tests/test_pool.py index 1c36d26da..c602d4a06 100644 --- a/src/epplibwrapper/tests/test_pool.py +++ b/src/epplibwrapper/tests/test_pool.py @@ -9,7 +9,7 @@ from epplibwrapper.socket import Socket from epplibwrapper.utility.pool import EPPConnectionPool from registrar.models.domain import registry from contextlib import ExitStack - +from .common import less_console_noise import logging try: @@ -135,23 +135,26 @@ class TestConnectionPool(TestCase): stack.enter_context(patch.object(EPPConnectionPool, "kill_all_connections", do_nothing)) stack.enter_context(patch.object(SocketTransport, "send", self.fake_send)) stack.enter_context(patch.object(SocketTransport, "receive", fake_receive)) - # Restart the connection pool - registry.start_connection_pool() - # Pool should be running, and be the right size - self.assertEqual(registry.pool_status.connection_success, True) - self.assertEqual(registry.pool_status.pool_running, True) + with less_console_noise(): + # Restart the connection pool + registry.start_connection_pool() + # Pool should be running, and be the right size + self.assertEqual(registry.pool_status.connection_success, True) + self.assertEqual(registry.pool_status.pool_running, True) - # Send a command - result = registry.send(commands.InfoDomain(name="test.gov"), cleaned=True) + # Send a command + result = registry.send(commands.InfoDomain(name="test.gov"), cleaned=True) - # Should this ever fail, it either means that the schema has changed, - # or the pool is broken. - # If the schema has changed: Update the associated infoDomain.xml file - self.assertEqual(result.__dict__, expected_result) + # Should this ever fail, it either means that the schema has changed, + # or the pool is broken. + # If the schema has changed: Update the associated infoDomain.xml file + self.assertEqual(result.__dict__, expected_result) - # The number of open pools should match the number of requested ones. - # If it is 0, then they failed to open - self.assertEqual(len(registry._pool.conn), self.pool_options["size"]) + # The number of open pools should match the number of requested ones. + # If it is 0, then they failed to open + self.assertEqual(len(registry._pool.conn), self.pool_options["size"]) + # Kill the connection pool + registry.kill_pool() @patch.object(EPPLibWrapper, "_test_registry_connection_success", patch_success) def test_pool_restarts_on_send(self): @@ -198,51 +201,63 @@ class TestConnectionPool(TestCase): xml = (location).read_bytes() return xml + def do_nothing(command): + pass + # Mock what happens inside the "with" with ExitStack() as stack: stack.enter_context(patch.object(EPPConnectionPool, "_create_socket", self.fake_socket)) stack.enter_context(patch.object(Socket, "connect", self.fake_client)) + stack.enter_context(patch.object(EPPConnectionPool, "kill_all_connections", do_nothing)) stack.enter_context(patch.object(SocketTransport, "send", self.fake_send)) stack.enter_context(patch.object(SocketTransport, "receive", fake_receive)) - # Kill the connection pool - registry.kill_pool() + with less_console_noise(): + # Start the connection pool + registry.start_connection_pool() + # Kill the connection pool + registry.kill_pool() - self.assertEqual(registry.pool_status.connection_success, False) - self.assertEqual(registry.pool_status.pool_running, False) + self.assertEqual(registry.pool_status.pool_running, False) - # An exception should be raised as end user will be informed - # that they cannot connect to EPP - with self.assertRaises(RegistryError): - expected = "InfoDomain failed to execute due to a connection error." + # An exception should be raised as end user will be informed + # that they cannot connect to EPP + with self.assertRaises(RegistryError): + expected = "InfoDomain failed to execute due to a connection error." + result = registry.send(commands.InfoDomain(name="test.gov"), cleaned=True) + self.assertEqual(result, expected) + + # A subsequent command should be successful, as the pool restarts result = registry.send(commands.InfoDomain(name="test.gov"), cleaned=True) - self.assertEqual(result, expected) + # Should this ever fail, it either means that the schema has changed, + # or the pool is broken. + # If the schema has changed: Update the associated infoDomain.xml file + self.assertEqual(result.__dict__, expected_result) - # A subsequent command should be successful, as the pool restarts - result = registry.send(commands.InfoDomain(name="test.gov"), cleaned=True) - # Should this ever fail, it either means that the schema has changed, - # or the pool is broken. - # If the schema has changed: Update the associated infoDomain.xml file - self.assertEqual(result.__dict__, expected_result) - - # The number of open pools should match the number of requested ones. - # If it is 0, then they failed to open - self.assertEqual(len(registry._pool.conn), self.pool_options["size"]) + # The number of open pools should match the number of requested ones. + # If it is 0, then they failed to open + self.assertEqual(len(registry._pool.conn), self.pool_options["size"]) + # Kill the connection pool + registry.kill_pool() @patch.object(EPPLibWrapper, "_test_registry_connection_success", patch_success) def test_raises_connection_error(self): """A .send is invoked on the pool, but registry connection is lost right as we send a command.""" - + with ExitStack() as stack: stack.enter_context(patch.object(EPPConnectionPool, "_create_socket", self.fake_socket)) stack.enter_context(patch.object(Socket, "connect", self.fake_client)) + with less_console_noise(): + # Start the connection pool + registry.start_connection_pool() - # Pool should be running - self.assertEqual(registry.pool_status.connection_success, True) - self.assertEqual(registry.pool_status.pool_running, True) + # Pool should be running + self.assertEqual(registry.pool_status.connection_success, True) + self.assertEqual(registry.pool_status.pool_running, True) - # Try to send a command out - should fail - with self.assertRaises(RegistryError): - expected = "InfoDomain failed to execute due to a connection error." - result = registry.send(commands.InfoDomain(name="test.gov"), cleaned=True) - self.assertEqual(result, expected) + # Try to send a command out - should fail + with self.assertRaises(RegistryError): + expected = "InfoDomain failed to execute due to a connection error." + result = registry.send(commands.InfoDomain(name="test.gov"), cleaned=True) + self.assertEqual(result, expected) + diff --git a/src/epplibwrapper/utility/pool.py b/src/epplibwrapper/utility/pool.py index 93edb2782..2c7de119f 100644 --- a/src/epplibwrapper/utility/pool.py +++ b/src/epplibwrapper/utility/pool.py @@ -85,6 +85,19 @@ class EPPConnectionPool(ConnectionPool): logger.error(message, exc_info=True) raise PoolError(code=PoolErrorCodes.KEEP_ALIVE_FAILED) from err + def _keepalive_periodic(self): + delay = float(self.keepalive) / self.size + while 1: + try: + with self.get() as c: + self._keepalive(c) + except PoolError as err: + logger.error(err.message, exc_info=True) + except self.exc_classes: + # Nothing to do, the pool will generate a new connection later + pass + gevent.sleep(delay) + def _create_socket(self, client, login) -> Socket: """Creates and returns a socket instance""" socket = Socket(client, login) diff --git a/src/registrar/tests/common.py b/src/registrar/tests/common.py index 023e5319e..2865bf5c5 100644 --- a/src/registrar/tests/common.py +++ b/src/registrar/tests/common.py @@ -12,6 +12,7 @@ from typing import List, Dict from django.contrib.sessions.middleware import SessionMiddleware from django.conf import settings from django.contrib.auth import get_user_model, login +from django.utils.timezone import make_aware from registrar.models import ( Contact, @@ -643,7 +644,7 @@ class MockEppLib(TestCase): self, id, email, - cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35), + cr_date=make_aware(datetime.datetime(2023, 5, 25, 19, 45, 35)), pw="thisisnotapassword", ): fake = info.InfoContactResultData( @@ -681,7 +682,7 @@ class MockEppLib(TestCase): mockDataInfoDomain = fakedEppObject( "fakePw", - cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35), + cr_date=make_aware(datetime.datetime(2023, 5, 25, 19, 45, 35)), contacts=[common.DomainContact(contact="123", type=PublicContact.ContactTypeChoices.SECURITY)], hosts=["fake.host.com"], statuses=[ @@ -692,7 +693,7 @@ class MockEppLib(TestCase): ) mockDataExtensionDomain = fakedEppObject( "fakePw", - cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35), + cr_date=make_aware(datetime.datetime(2023, 5, 25, 19, 45, 35)), contacts=[common.DomainContact(contact="123", type=PublicContact.ContactTypeChoices.SECURITY)], hosts=["fake.host.com"], statuses=[ @@ -706,7 +707,7 @@ class MockEppLib(TestCase): ) InfoDomainWithContacts = fakedEppObject( "fakepw", - cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35), + cr_date=make_aware(datetime.datetime(2023, 5, 25, 19, 45, 35)), contacts=[ common.DomainContact( contact="securityContact", @@ -731,7 +732,7 @@ class MockEppLib(TestCase): InfoDomainWithDefaultSecurityContact = fakedEppObject( "fakepw", - cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35), + cr_date=make_aware(datetime.datetime(2023, 5, 25, 19, 45, 35)), contacts=[ common.DomainContact( contact="defaultSec", @@ -750,7 +751,7 @@ class MockEppLib(TestCase): ) InfoDomainWithVerisignSecurityContact = fakedEppObject( "fakepw", - cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35), + cr_date=make_aware(datetime.datetime(2023, 5, 25, 19, 45, 35)), contacts=[ common.DomainContact( contact="defaultVeri", @@ -766,7 +767,7 @@ class MockEppLib(TestCase): InfoDomainWithDefaultTechnicalContact = fakedEppObject( "fakepw", - cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35), + cr_date=make_aware(datetime.datetime(2023, 5, 25, 19, 45, 35)), contacts=[ common.DomainContact( contact="defaultTech", @@ -791,14 +792,14 @@ class MockEppLib(TestCase): infoDomainNoContact = fakedEppObject( "security", - cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35), + cr_date=make_aware(datetime.datetime(2023, 5, 25, 19, 45, 35)), contacts=[], hosts=["fake.host.com"], ) infoDomainThreeHosts = fakedEppObject( "my-nameserver.gov", - cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35), + cr_date=make_aware(datetime.datetime(2023, 5, 25, 19, 45, 35)), contacts=[], hosts=[ "ns1.my-nameserver-1.com", @@ -809,25 +810,25 @@ class MockEppLib(TestCase): infoDomainNoHost = fakedEppObject( "my-nameserver.gov", - cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35), + cr_date=make_aware(datetime.datetime(2023, 5, 25, 19, 45, 35)), contacts=[], hosts=[], ) infoDomainTwoHosts = fakedEppObject( "my-nameserver.gov", - cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35), + cr_date=make_aware(datetime.datetime(2023, 5, 25, 19, 45, 35)), contacts=[], hosts=["ns1.my-nameserver-1.com", "ns1.my-nameserver-2.com"], ) mockDataInfoHosts = fakedEppObject( "lastPw", - cr_date=datetime.datetime(2023, 8, 25, 19, 45, 35), + cr_date=make_aware(datetime.datetime(2023, 8, 25, 19, 45, 35)), addrs=[common.Ip(addr="1.2.3.4"), common.Ip(addr="2.3.4.5")], ) - mockDataHostChange = fakedEppObject("lastPw", cr_date=datetime.datetime(2023, 8, 25, 19, 45, 35)) + mockDataHostChange = fakedEppObject("lastPw", cr_date=make_aware(datetime.datetime(2023, 8, 25, 19, 45, 35))) addDsData1 = { "keyTag": 1234, "alg": 3, @@ -859,7 +860,7 @@ class MockEppLib(TestCase): infoDomainHasIP = fakedEppObject( "nameserverwithip.gov", - cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35), + cr_date=make_aware(datetime.datetime(2023, 5, 25, 19, 45, 35)), contacts=[ common.DomainContact( contact="securityContact", @@ -884,7 +885,7 @@ class MockEppLib(TestCase): justNameserver = fakedEppObject( "justnameserver.com", - cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35), + cr_date=make_aware(datetime.datetime(2023, 5, 25, 19, 45, 35)), contacts=[ common.DomainContact( contact="securityContact", @@ -907,7 +908,7 @@ class MockEppLib(TestCase): infoDomainCheckHostIPCombo = fakedEppObject( "nameserversubdomain.gov", - cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35), + cr_date=make_aware(datetime.datetime(2023, 5, 25, 19, 45, 35)), contacts=[], hosts=[ "ns1.nameserversubdomain.gov", diff --git a/src/registrar/tests/test_admin.py b/src/registrar/tests/test_admin.py index ebf3dfed9..6344157d8 100644 --- a/src/registrar/tests/test_admin.py +++ b/src/registrar/tests/test_admin.py @@ -59,22 +59,22 @@ class TestDomainAdmin(MockEppLib): """ Make sure the short name is displaying in admin on the list page """ - self.client.force_login(self.superuser) - application = completed_application(status=DomainApplication.ApplicationStatus.IN_REVIEW) - mock_client = MockSESClient() - with boto3_mocking.clients.handler_for("sesv2", mock_client): - with less_console_noise(): + with less_console_noise(): + self.client.force_login(self.superuser) + application = completed_application(status=DomainApplication.ApplicationStatus.IN_REVIEW) + mock_client = MockSESClient() + with boto3_mocking.clients.handler_for("sesv2", mock_client): application.approve() - response = self.client.get("/admin/registrar/domain/") + response = self.client.get("/admin/registrar/domain/") - # There are 3 template references to Federal (3) plus one reference in the table - # for our actual application - self.assertContains(response, "Federal", count=4) - # This may be a bit more robust - self.assertContains(response, 'Federal', count=1) - # Now let's make sure the long description does not exist - self.assertNotContains(response, "Federal: an agency of the U.S. government") + # There are 3 template references to Federal (3) plus one reference in the table + # for our actual application + self.assertContains(response, "Federal", count=4) + # This may be a bit more robust + self.assertContains(response, 'Federal', count=1) + # Now let's make sure the long description does not exist + self.assertNotContains(response, "Federal: an agency of the U.S. government") @skip("Why did this test stop working, and is is a good test") def test_place_and_remove_hold(self): @@ -120,40 +120,37 @@ class TestDomainAdmin(MockEppLib): Then a user-friendly success message is returned for displaying on the web And `state` is et to `DELETED` """ - domain = create_ready_domain() - # Put in client hold - domain.place_client_hold() - p = "userpass" - self.client.login(username="staffuser", password=p) - - # Ensure everything is displaying correctly - response = self.client.get( - "/admin/registrar/domain/{}/change/".format(domain.pk), - follow=True, - ) - self.assertEqual(response.status_code, 200) - self.assertContains(response, domain.name) - self.assertContains(response, "Remove from registry") - - # Test the info dialog - request = self.factory.post( - "/admin/registrar/domain/{}/change/".format(domain.pk), - {"_delete_domain": "Remove from registry", "name": domain.name}, - follow=True, - ) - request.user = self.client - - with patch("django.contrib.messages.add_message") as mock_add_message: - self.admin.do_delete_domain(request, domain) - mock_add_message.assert_called_once_with( - request, - messages.INFO, - "Domain city.gov has been deleted. Thanks!", - extra_tags="", - fail_silently=False, + with less_console_noise(): + domain = create_ready_domain() + # Put in client hold + domain.place_client_hold() + p = "userpass" + self.client.login(username="staffuser", password=p) + # Ensure everything is displaying correctly + response = self.client.get( + "/admin/registrar/domain/{}/change/".format(domain.pk), + follow=True, ) - - self.assertEqual(domain.state, Domain.State.DELETED) + self.assertEqual(response.status_code, 200) + self.assertContains(response, domain.name) + self.assertContains(response, "Remove from registry") + # Test the info dialog + request = self.factory.post( + "/admin/registrar/domain/{}/change/".format(domain.pk), + {"_delete_domain": "Remove from registry", "name": domain.name}, + follow=True, + ) + request.user = self.client + with patch("django.contrib.messages.add_message") as mock_add_message: + self.admin.do_delete_domain(request, domain) + mock_add_message.assert_called_once_with( + request, + messages.INFO, + "Domain city.gov has been deleted. Thanks!", + extra_tags="", + fail_silently=False, + ) + self.assertEqual(domain.state, Domain.State.DELETED) def test_deletion_ready_fsm_failure(self): """ @@ -162,38 +159,36 @@ class TestDomainAdmin(MockEppLib): Then a user-friendly error message is returned for displaying on the web And `state` is not set to `DELETED` """ - domain = create_ready_domain() - p = "userpass" - self.client.login(username="staffuser", password=p) - - # Ensure everything is displaying correctly - response = self.client.get( - "/admin/registrar/domain/{}/change/".format(domain.pk), - follow=True, - ) - self.assertEqual(response.status_code, 200) - self.assertContains(response, domain.name) - self.assertContains(response, "Remove from registry") - - # Test the error - request = self.factory.post( - "/admin/registrar/domain/{}/change/".format(domain.pk), - {"_delete_domain": "Remove from registry", "name": domain.name}, - follow=True, - ) - request.user = self.client - - with patch("django.contrib.messages.add_message") as mock_add_message: - self.admin.do_delete_domain(request, domain) - mock_add_message.assert_called_once_with( - request, - messages.ERROR, - "Error deleting this Domain: " - "Can't switch from state 'ready' to 'deleted'" - ", must be either 'dns_needed' or 'on_hold'", - extra_tags="", - fail_silently=False, + with less_console_noise(): + domain = create_ready_domain() + p = "userpass" + self.client.login(username="staffuser", password=p) + # Ensure everything is displaying correctly + response = self.client.get( + "/admin/registrar/domain/{}/change/".format(domain.pk), + follow=True, ) + self.assertEqual(response.status_code, 200) + self.assertContains(response, domain.name) + self.assertContains(response, "Remove from registry") + # Test the error + request = self.factory.post( + "/admin/registrar/domain/{}/change/".format(domain.pk), + {"_delete_domain": "Remove from registry", "name": domain.name}, + follow=True, + ) + request.user = self.client + with patch("django.contrib.messages.add_message") as mock_add_message: + self.admin.do_delete_domain(request, domain) + mock_add_message.assert_called_once_with( + request, + messages.ERROR, + "Error deleting this Domain: " + "Can't switch from state 'ready' to 'deleted'" + ", must be either 'dns_needed' or 'on_hold'", + extra_tags="", + fail_silently=False, + ) self.assertEqual(domain.state, Domain.State.READY) @@ -205,62 +200,57 @@ class TestDomainAdmin(MockEppLib): Then `commands.DeleteDomain` is sent to the registry And Domain returns normally without an error dialog """ - domain = create_ready_domain() - # Put in client hold - domain.place_client_hold() - p = "userpass" - self.client.login(username="staffuser", password=p) - - # Ensure everything is displaying correctly - response = self.client.get( - "/admin/registrar/domain/{}/change/".format(domain.pk), - follow=True, - ) - self.assertEqual(response.status_code, 200) - self.assertContains(response, domain.name) - self.assertContains(response, "Remove from registry") - - # Test the info dialog - request = self.factory.post( - "/admin/registrar/domain/{}/change/".format(domain.pk), - {"_delete_domain": "Remove from registry", "name": domain.name}, - follow=True, - ) - request.user = self.client - - # Delete it once - with patch("django.contrib.messages.add_message") as mock_add_message: - self.admin.do_delete_domain(request, domain) - mock_add_message.assert_called_once_with( - request, - messages.INFO, - "Domain city.gov has been deleted. Thanks!", - extra_tags="", - fail_silently=False, + with less_console_noise(): + domain = create_ready_domain() + # Put in client hold + domain.place_client_hold() + p = "userpass" + self.client.login(username="staffuser", password=p) + # Ensure everything is displaying correctly + response = self.client.get( + "/admin/registrar/domain/{}/change/".format(domain.pk), + follow=True, ) - - self.assertEqual(domain.state, Domain.State.DELETED) - - # Try to delete it again - # Test the info dialog - request = self.factory.post( - "/admin/registrar/domain/{}/change/".format(domain.pk), - {"_delete_domain": "Remove from registry", "name": domain.name}, - follow=True, - ) - request.user = self.client - - with patch("django.contrib.messages.add_message") as mock_add_message: - self.admin.do_delete_domain(request, domain) - mock_add_message.assert_called_once_with( - request, - messages.INFO, - "This domain is already deleted", - extra_tags="", - fail_silently=False, + self.assertEqual(response.status_code, 200) + self.assertContains(response, domain.name) + self.assertContains(response, "Remove from registry") + # Test the info dialog + request = self.factory.post( + "/admin/registrar/domain/{}/change/".format(domain.pk), + {"_delete_domain": "Remove from registry", "name": domain.name}, + follow=True, ) + request.user = self.client + # Delete it once + with patch("django.contrib.messages.add_message") as mock_add_message: + self.admin.do_delete_domain(request, domain) + mock_add_message.assert_called_once_with( + request, + messages.INFO, + "Domain city.gov has been deleted. Thanks!", + extra_tags="", + fail_silently=False, + ) - self.assertEqual(domain.state, Domain.State.DELETED) + self.assertEqual(domain.state, Domain.State.DELETED) + # Try to delete it again + # Test the info dialog + request = self.factory.post( + "/admin/registrar/domain/{}/change/".format(domain.pk), + {"_delete_domain": "Remove from registry", "name": domain.name}, + follow=True, + ) + request.user = self.client + with patch("django.contrib.messages.add_message") as mock_add_message: + self.admin.do_delete_domain(request, domain) + mock_add_message.assert_called_once_with( + request, + messages.INFO, + "This domain is already deleted", + extra_tags="", + fail_silently=False, + ) + self.assertEqual(domain.state, Domain.State.DELETED) @skip("Waiting on epp lib to implement") def test_place_and_remove_hold_epp(self): @@ -1281,64 +1271,62 @@ class ListHeaderAdminTest(TestCase): self.superuser = create_superuser() def test_changelist_view(self): - # Have to get creative to get past linter - p = "adminpass" - self.client.login(username="superuser", password=p) - - # Mock a user - user = mock_user() - - # Make the request using the Client class - # which handles CSRF - # Follow=True handles the redirect - response = self.client.get( - "/admin/registrar/domainapplication/", - { - "status__exact": "started", - "investigator__id__exact": user.id, - "q": "Hello", - }, - follow=True, - ) - - # Assert that the filters and search_query are added to the extra_context - self.assertIn("filters", response.context) - self.assertIn("search_query", response.context) - # Assert the content of filters and search_query - filters = response.context["filters"] - search_query = response.context["search_query"] - self.assertEqual(search_query, "Hello") - self.assertEqual( - filters, - [ - {"parameter_name": "status", "parameter_value": "started"}, + with less_console_noise(): + # Have to get creative to get past linter + p = "adminpass" + self.client.login(username="superuser", password=p) + # Mock a user + user = mock_user() + # Make the request using the Client class + # which handles CSRF + # Follow=True handles the redirect + response = self.client.get( + "/admin/registrar/domainapplication/", { - "parameter_name": "investigator", - "parameter_value": user.first_name + " " + user.last_name, + "status__exact": "started", + "investigator__id__exact": user.id, + "q": "Hello", }, - ], - ) + follow=True, + ) + # Assert that the filters and search_query are added to the extra_context + self.assertIn("filters", response.context) + self.assertIn("search_query", response.context) + # Assert the content of filters and search_query + filters = response.context["filters"] + search_query = response.context["search_query"] + self.assertEqual(search_query, "Hello") + self.assertEqual( + filters, + [ + {"parameter_name": "status", "parameter_value": "started"}, + { + "parameter_name": "investigator", + "parameter_value": user.first_name + " " + user.last_name, + }, + ], + ) def test_get_filters(self): - # Create a mock request object - request = self.factory.get("/admin/yourmodel/") - # Set the GET parameters for testing - request.GET = { - "status": "started", - "investigator": "Jeff Lebowski", - "q": "search_value", - } - # Call the get_filters method - filters = self.admin.get_filters(request) - - # Assert the filters extracted from the request GET - self.assertEqual( - filters, - [ - {"parameter_name": "status", "parameter_value": "started"}, - {"parameter_name": "investigator", "parameter_value": "Jeff Lebowski"}, - ], - ) + with less_console_noise(): + # Create a mock request object + request = self.factory.get("/admin/yourmodel/") + # Set the GET parameters for testing + request.GET = { + "status": "started", + "investigator": "Jeff Lebowski", + "q": "search_value", + } + # Call the get_filters method + filters = self.admin.get_filters(request) + # Assert the filters extracted from the request GET + self.assertEqual( + filters, + [ + {"parameter_name": "status", "parameter_value": "started"}, + {"parameter_name": "investigator", "parameter_value": "Jeff Lebowski"}, + ], + ) def tearDown(self): # delete any applications too @@ -1777,42 +1765,38 @@ class ContactAdminTest(TestCase): def test_change_view_for_joined_contact_five_or_more(self): """Create a contact, join it to 5 domain requests. The 6th join will be a user. Assert that the warning on the contact form lists 5 joins and a '1 more' ellispsis.""" - - self.client.force_login(self.superuser) - - # Create an instance of the model - # join it to 5 domain requests. The 6th join will be a user. - contact, _ = Contact.objects.get_or_create(user=self.staffuser) - application1 = completed_application(submitter=contact, name="city1.gov") - application2 = completed_application(submitter=contact, name="city2.gov") - application3 = completed_application(submitter=contact, name="city3.gov") - application4 = completed_application(submitter=contact, name="city4.gov") - application5 = completed_application(submitter=contact, name="city5.gov") - - with patch("django.contrib.messages.warning") as mock_warning: - # Use the test client to simulate the request - response = self.client.get(reverse("admin:registrar_contact_change", args=[contact.pk])) - - logger.info(mock_warning) - - # Assert that the error message was called with the correct argument - # Note: The 6th join will be a user. - mock_warning.assert_called_once_with( - response.wsgi_request, - "" - "

And 1 more...

", - ) + with less_console_noise(): + self.client.force_login(self.superuser) + # Create an instance of the model + # join it to 5 domain requests. The 6th join will be a user. + contact, _ = Contact.objects.get_or_create(user=self.staffuser) + application1 = completed_application(submitter=contact, name="city1.gov") + application2 = completed_application(submitter=contact, name="city2.gov") + application3 = completed_application(submitter=contact, name="city3.gov") + application4 = completed_application(submitter=contact, name="city4.gov") + application5 = completed_application(submitter=contact, name="city5.gov") + with patch("django.contrib.messages.warning") as mock_warning: + # Use the test client to simulate the request + response = self.client.get(reverse("admin:registrar_contact_change", args=[contact.pk])) + logger.debug(mock_warning) + # Assert that the error message was called with the correct argument + # Note: The 6th join will be a user. + mock_warning.assert_called_once_with( + response.wsgi_request, + "" + "

And 1 more...

", + ) def tearDown(self): DomainApplication.objects.all().delete() diff --git a/src/registrar/tests/test_management_scripts.py b/src/registrar/tests/test_management_scripts.py index 06886ba66..40cdce6d2 100644 --- a/src/registrar/tests/test_management_scripts.py +++ b/src/registrar/tests/test_management_scripts.py @@ -1,5 +1,6 @@ import copy -import datetime +from datetime import date, datetime, time +from django.utils import timezone from django.test import TestCase @@ -17,7 +18,7 @@ from django.core.management import call_command from unittest.mock import patch, call from epplibwrapper import commands, common -from .common import MockEppLib +from .common import MockEppLib, less_console_noise class TestPopulateFirstReady(TestCase): @@ -33,7 +34,9 @@ class TestPopulateFirstReady(TestCase): self.unknown_domain, _ = Domain.objects.get_or_create(name="fakeunknown.gov", state=Domain.State.UNKNOWN) # Set a ready_at date for testing purposes - self.ready_at_date = datetime.date(2022, 12, 31) + self.ready_at_date = date(2022, 12, 31) + _ready_at_datetime = datetime.combine(self.ready_at_date, time.min) + self.ready_at_date_tz_aware = timezone.make_aware(_ready_at_datetime, timezone=timezone.utc) def tearDown(self): """Deletes all DB objects related to migrations""" @@ -49,122 +52,103 @@ class TestPopulateFirstReady(TestCase): The 'call_command' function from Django's management framework is then used to execute the populate_first_ready command with the specified arguments. """ - with patch( - "registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa - return_value=True, - ): - call_command("populate_first_ready") + with less_console_noise(): + with patch( + "registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa + return_value=True, + ): + call_command("populate_first_ready") def test_populate_first_ready_state_ready(self): """ Tests that the populate_first_ready works as expected for the state 'ready' """ - # Set the created at date - self.ready_domain.created_at = self.ready_at_date - self.ready_domain.save() - - desired_domain = copy.deepcopy(self.ready_domain) - - desired_domain.first_ready = self.ready_at_date - - # Run the expiration date script - self.run_populate_first_ready() - - self.assertEqual(desired_domain, self.ready_domain) - - # Explicitly test the first_ready date - first_ready = Domain.objects.filter(name="fakeready.gov").get().first_ready - self.assertEqual(first_ready, self.ready_at_date) + with less_console_noise(): + # Set the created at date + self.ready_domain.created_at = self.ready_at_date_tz_aware + self.ready_domain.save() + desired_domain = copy.deepcopy(self.ready_domain) + desired_domain.first_ready = self.ready_at_date + # Run the expiration date script + self.run_populate_first_ready() + self.assertEqual(desired_domain, self.ready_domain) + # Explicitly test the first_ready date + first_ready = Domain.objects.filter(name="fakeready.gov").get().first_ready + self.assertEqual(first_ready, self.ready_at_date) def test_populate_first_ready_state_deleted(self): """ Tests that the populate_first_ready works as expected for the state 'deleted' """ - # Set the created at date - self.deleted_domain.created_at = self.ready_at_date - self.deleted_domain.save() - - desired_domain = copy.deepcopy(self.deleted_domain) - - desired_domain.first_ready = self.ready_at_date - - # Run the expiration date script - self.run_populate_first_ready() - - self.assertEqual(desired_domain, self.deleted_domain) - - # Explicitly test the first_ready date - first_ready = Domain.objects.filter(name="fakedeleted.gov").get().first_ready - self.assertEqual(first_ready, self.ready_at_date) + with less_console_noise(): + # Set the created at date + self.deleted_domain.created_at = self.ready_at_date_tz_aware + self.deleted_domain.save() + desired_domain = copy.deepcopy(self.deleted_domain) + desired_domain.first_ready = self.ready_at_date + # Run the expiration date script + self.run_populate_first_ready() + self.assertEqual(desired_domain, self.deleted_domain) + # Explicitly test the first_ready date + first_ready = Domain.objects.filter(name="fakedeleted.gov").get().first_ready + self.assertEqual(first_ready, self.ready_at_date) def test_populate_first_ready_state_dns_needed(self): """ Tests that the populate_first_ready doesn't make changes when a domain's state is 'dns_needed' """ - # Set the created at date - self.dns_needed_domain.created_at = self.ready_at_date - self.dns_needed_domain.save() - - desired_domain = copy.deepcopy(self.dns_needed_domain) - - desired_domain.first_ready = None - - # Run the expiration date script - self.run_populate_first_ready() - - current_domain = self.dns_needed_domain - # The object should largely be unaltered (does not test first_ready) - self.assertEqual(desired_domain, current_domain) - - first_ready = Domain.objects.filter(name="fakedns.gov").get().first_ready - - # Explicitly test the first_ready date - self.assertNotEqual(first_ready, self.ready_at_date) - self.assertEqual(first_ready, None) + with less_console_noise(): + # Set the created at date + self.dns_needed_domain.created_at = self.ready_at_date_tz_aware + self.dns_needed_domain.save() + desired_domain = copy.deepcopy(self.dns_needed_domain) + desired_domain.first_ready = None + # Run the expiration date script + self.run_populate_first_ready() + current_domain = self.dns_needed_domain + # The object should largely be unaltered (does not test first_ready) + self.assertEqual(desired_domain, current_domain) + first_ready = Domain.objects.filter(name="fakedns.gov").get().first_ready + # Explicitly test the first_ready date + self.assertNotEqual(first_ready, self.ready_at_date) + self.assertEqual(first_ready, None) def test_populate_first_ready_state_on_hold(self): """ Tests that the populate_first_ready works as expected for the state 'on_hold' """ - self.hold_domain.created_at = self.ready_at_date - self.hold_domain.save() - - desired_domain = copy.deepcopy(self.hold_domain) - desired_domain.first_ready = self.ready_at_date - - # Run the update first ready_at script - self.run_populate_first_ready() - - current_domain = self.hold_domain - self.assertEqual(desired_domain, current_domain) - - # Explicitly test the first_ready date - first_ready = Domain.objects.filter(name="fakehold.gov").get().first_ready - self.assertEqual(first_ready, self.ready_at_date) + with less_console_noise(): + self.hold_domain.created_at = self.ready_at_date_tz_aware + self.hold_domain.save() + desired_domain = copy.deepcopy(self.hold_domain) + desired_domain.first_ready = self.ready_at_date + # Run the update first ready_at script + self.run_populate_first_ready() + current_domain = self.hold_domain + self.assertEqual(desired_domain, current_domain) + # Explicitly test the first_ready date + first_ready = Domain.objects.filter(name="fakehold.gov").get().first_ready + self.assertEqual(first_ready, self.ready_at_date) def test_populate_first_ready_state_unknown(self): """ Tests that the populate_first_ready works as expected for the state 'unknown' """ - # Set the created at date - self.unknown_domain.created_at = self.ready_at_date - self.unknown_domain.save() - - desired_domain = copy.deepcopy(self.unknown_domain) - desired_domain.first_ready = None - - # Run the expiration date script - self.run_populate_first_ready() - - current_domain = self.unknown_domain - - # The object should largely be unaltered (does not test first_ready) - self.assertEqual(desired_domain, current_domain) - - # Explicitly test the first_ready date - first_ready = Domain.objects.filter(name="fakeunknown.gov").get().first_ready - self.assertNotEqual(first_ready, self.ready_at_date) - self.assertEqual(first_ready, None) + with less_console_noise(): + # Set the created at date + self.unknown_domain.created_at = self.ready_at_date_tz_aware + self.unknown_domain.save() + desired_domain = copy.deepcopy(self.unknown_domain) + desired_domain.first_ready = None + # Run the expiration date script + self.run_populate_first_ready() + current_domain = self.unknown_domain + # The object should largely be unaltered (does not test first_ready) + self.assertEqual(desired_domain, current_domain) + # Explicitly test the first_ready date + first_ready = Domain.objects.filter(name="fakeunknown.gov").get().first_ready + self.assertNotEqual(first_ready, self.ready_at_date) + self.assertEqual(first_ready, None) class TestPatchAgencyInfo(TestCase): @@ -185,7 +169,8 @@ class TestPatchAgencyInfo(TestCase): @patch("registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", return_value=True) def call_patch_federal_agency_info(self, mock_prompt): """Calls the patch_federal_agency_info command and mimics a keypress""" - call_command("patch_federal_agency_info", "registrar/tests/data/fake_current_full.csv", debug=True) + with less_console_noise(): + call_command("patch_federal_agency_info", "registrar/tests/data/fake_current_full.csv", debug=True) def test_patch_agency_info(self): """ @@ -194,17 +179,14 @@ class TestPatchAgencyInfo(TestCase): of a `DomainInformation` object when the corresponding `TransitionDomain` object has a valid `federal_agency`. """ - - # Ensure that the federal_agency is None - self.assertEqual(self.domain_info.federal_agency, None) - - self.call_patch_federal_agency_info() - - # Reload the domain_info object from the database - self.domain_info.refresh_from_db() - - # Check that the federal_agency field was updated - self.assertEqual(self.domain_info.federal_agency, "test agency") + with less_console_noise(): + # Ensure that the federal_agency is None + self.assertEqual(self.domain_info.federal_agency, None) + self.call_patch_federal_agency_info() + # Reload the domain_info object from the database + self.domain_info.refresh_from_db() + # Check that the federal_agency field was updated + self.assertEqual(self.domain_info.federal_agency, "test agency") def test_patch_agency_info_skip(self): """ @@ -213,21 +195,18 @@ class TestPatchAgencyInfo(TestCase): of a `DomainInformation` object when the corresponding `TransitionDomain` object does not exist. """ - # Set federal_agency to None to simulate a skip - self.transition_domain.federal_agency = None - self.transition_domain.save() - - with self.assertLogs("registrar.management.commands.patch_federal_agency_info", level="WARNING") as context: - self.call_patch_federal_agency_info() - - # Check that the correct log message was output - self.assertIn("SOME AGENCY DATA WAS NONE", context.output[0]) - - # Reload the domain_info object from the database - self.domain_info.refresh_from_db() - - # Check that the federal_agency field was not updated - self.assertIsNone(self.domain_info.federal_agency) + with less_console_noise(): + # Set federal_agency to None to simulate a skip + self.transition_domain.federal_agency = None + self.transition_domain.save() + with self.assertLogs("registrar.management.commands.patch_federal_agency_info", level="WARNING") as context: + self.call_patch_federal_agency_info() + # Check that the correct log message was output + self.assertIn("SOME AGENCY DATA WAS NONE", context.output[0]) + # Reload the domain_info object from the database + self.domain_info.refresh_from_db() + # Check that the federal_agency field was not updated + self.assertIsNone(self.domain_info.federal_agency) def test_patch_agency_info_skip_updates_data(self): """ @@ -235,25 +214,21 @@ class TestPatchAgencyInfo(TestCase): updates the DomainInformation object, because a record exists in the provided current-full.csv file. """ - # Set federal_agency to None to simulate a skip - self.transition_domain.federal_agency = None - self.transition_domain.save() - - # Change the domain name to something parsable in the .csv - self.domain.name = "cdomain1.gov" - self.domain.save() - - with self.assertLogs("registrar.management.commands.patch_federal_agency_info", level="WARNING") as context: - self.call_patch_federal_agency_info() - - # Check that the correct log message was output - self.assertIn("SOME AGENCY DATA WAS NONE", context.output[0]) - - # Reload the domain_info object from the database - self.domain_info.refresh_from_db() - - # Check that the federal_agency field was not updated - self.assertEqual(self.domain_info.federal_agency, "World War I Centennial Commission") + with less_console_noise(): + # Set federal_agency to None to simulate a skip + self.transition_domain.federal_agency = None + self.transition_domain.save() + # Change the domain name to something parsable in the .csv + self.domain.name = "cdomain1.gov" + self.domain.save() + with self.assertLogs("registrar.management.commands.patch_federal_agency_info", level="WARNING") as context: + self.call_patch_federal_agency_info() + # Check that the correct log message was output + self.assertIn("SOME AGENCY DATA WAS NONE", context.output[0]) + # Reload the domain_info object from the database + self.domain_info.refresh_from_db() + # Check that the federal_agency field was not updated + self.assertEqual(self.domain_info.federal_agency, "World War I Centennial Commission") def test_patch_agency_info_skips_valid_domains(self): """ @@ -261,20 +236,17 @@ class TestPatchAgencyInfo(TestCase): does not update the `federal_agency` field of a `DomainInformation` object """ - self.domain_info.federal_agency = "unchanged" - self.domain_info.save() - - with self.assertLogs("registrar.management.commands.patch_federal_agency_info", level="INFO") as context: - self.call_patch_federal_agency_info() - - # Check that the correct log message was output - self.assertIn("FINISHED", context.output[1]) - - # Reload the domain_info object from the database - self.domain_info.refresh_from_db() - - # Check that the federal_agency field was not updated - self.assertEqual(self.domain_info.federal_agency, "unchanged") + with less_console_noise(): + self.domain_info.federal_agency = "unchanged" + self.domain_info.save() + with self.assertLogs("registrar.management.commands.patch_federal_agency_info", level="INFO") as context: + self.call_patch_federal_agency_info() + # Check that the correct log message was output + self.assertIn("FINISHED", context.output[1]) + # Reload the domain_info object from the database + self.domain_info.refresh_from_db() + # Check that the federal_agency field was not updated + self.assertEqual(self.domain_info.federal_agency, "unchanged") class TestExtendExpirationDates(MockEppLib): @@ -283,39 +255,39 @@ class TestExtendExpirationDates(MockEppLib): super().setUp() # Create a valid domain that is updatable Domain.objects.get_or_create( - name="waterbutpurple.gov", state=Domain.State.READY, expiration_date=datetime.date(2023, 11, 15) + name="waterbutpurple.gov", state=Domain.State.READY, expiration_date=date(2023, 11, 15) ) TransitionDomain.objects.get_or_create( username="testytester@mail.com", domain_name="waterbutpurple.gov", - epp_expiration_date=datetime.date(2023, 11, 15), + epp_expiration_date=date(2023, 11, 15), ) # Create a domain with an invalid expiration date Domain.objects.get_or_create( - name="fake.gov", state=Domain.State.READY, expiration_date=datetime.date(2022, 5, 25) + name="fake.gov", state=Domain.State.READY, expiration_date=date(2022, 5, 25) ) TransitionDomain.objects.get_or_create( username="themoonisactuallycheese@mail.com", domain_name="fake.gov", - epp_expiration_date=datetime.date(2022, 5, 25), + epp_expiration_date=date(2022, 5, 25), ) # Create a domain with an invalid state Domain.objects.get_or_create( - name="fakeneeded.gov", state=Domain.State.DNS_NEEDED, expiration_date=datetime.date(2023, 11, 15) + name="fakeneeded.gov", state=Domain.State.DNS_NEEDED, expiration_date=date(2023, 11, 15) ) TransitionDomain.objects.get_or_create( username="fakeneeded@mail.com", domain_name="fakeneeded.gov", - epp_expiration_date=datetime.date(2023, 11, 15), + epp_expiration_date=date(2023, 11, 15), ) # Create a domain with a date greater than the maximum Domain.objects.get_or_create( - name="fakemaximum.gov", state=Domain.State.READY, expiration_date=datetime.date(2024, 12, 31) + name="fakemaximum.gov", state=Domain.State.READY, expiration_date=date(2024, 12, 31) ) TransitionDomain.objects.get_or_create( username="fakemaximum@mail.com", domain_name="fakemaximum.gov", - epp_expiration_date=datetime.date(2024, 12, 31), + epp_expiration_date=date(2024, 12, 31), ) def tearDown(self): @@ -338,83 +310,82 @@ class TestExtendExpirationDates(MockEppLib): The 'call_command' function from Django's management framework is then used to execute the extend_expiration_dates command with the specified arguments. """ - with patch( - "registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa - return_value=True, - ): - call_command("extend_expiration_dates") + with less_console_noise(): + with patch( + "registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa + return_value=True, + ): + call_command("extend_expiration_dates") def test_extends_expiration_date_correctly(self): """ Tests that the extend_expiration_dates method extends dates as expected """ - desired_domain = Domain.objects.filter(name="waterbutpurple.gov").get() - desired_domain.expiration_date = datetime.date(2024, 11, 15) - - # Run the expiration date script - self.run_extend_expiration_dates() - - current_domain = Domain.objects.filter(name="waterbutpurple.gov").get() - - self.assertEqual(desired_domain, current_domain) - # Explicitly test the expiration date - self.assertEqual(current_domain.expiration_date, datetime.date(2024, 11, 15)) + with less_console_noise(): + desired_domain = Domain.objects.filter(name="waterbutpurple.gov").get() + desired_domain.expiration_date = date(2024, 11, 15) + # Run the expiration date script + self.run_extend_expiration_dates() + current_domain = Domain.objects.filter(name="waterbutpurple.gov").get() + self.assertEqual(desired_domain, current_domain) + # Explicitly test the expiration date + self.assertEqual(current_domain.expiration_date, date(2024, 11, 15)) def test_extends_expiration_date_skips_non_current(self): """ Tests that the extend_expiration_dates method correctly skips domains with an expiration date less than a certain threshold. """ - desired_domain = Domain.objects.filter(name="fake.gov").get() - desired_domain.expiration_date = datetime.date(2022, 5, 25) - - # Run the expiration date script - self.run_extend_expiration_dates() - - current_domain = Domain.objects.filter(name="fake.gov").get() - self.assertEqual(desired_domain, current_domain) - - # Explicitly test the expiration date. The extend_expiration_dates script - # will skip all dates less than date(2023, 11, 15), meaning that this domain - # should not be affected by the change. - self.assertEqual(current_domain.expiration_date, datetime.date(2022, 5, 25)) + with less_console_noise(): + desired_domain = Domain.objects.filter(name="fake.gov").get() + desired_domain.expiration_date = date(2022, 5, 25) + # Run the expiration date script + self.run_extend_expiration_dates() + current_domain = Domain.objects.filter(name="fake.gov").get() + self.assertEqual(desired_domain, current_domain) + # Explicitly test the expiration date. The extend_expiration_dates script + # will skip all dates less than date(2023, 11, 15), meaning that this domain + # should not be affected by the change. + self.assertEqual(current_domain.expiration_date, date(2022, 5, 25)) def test_extends_expiration_date_skips_maximum_date(self): """ Tests that the extend_expiration_dates method correctly skips domains with an expiration date more than a certain threshold. """ - desired_domain = Domain.objects.filter(name="fakemaximum.gov").get() - desired_domain.expiration_date = datetime.date(2024, 12, 31) + with less_console_noise(): + desired_domain = Domain.objects.filter(name="fakemaximum.gov").get() + desired_domain.expiration_date = date(2024, 12, 31) - # Run the expiration date script - self.run_extend_expiration_dates() + # Run the expiration date script + self.run_extend_expiration_dates() - current_domain = Domain.objects.filter(name="fakemaximum.gov").get() - self.assertEqual(desired_domain, current_domain) + current_domain = Domain.objects.filter(name="fakemaximum.gov").get() + self.assertEqual(desired_domain, current_domain) - # Explicitly test the expiration date. The extend_expiration_dates script - # will skip all dates less than date(2023, 11, 15), meaning that this domain - # should not be affected by the change. - self.assertEqual(current_domain.expiration_date, datetime.date(2024, 12, 31)) + # Explicitly test the expiration date. The extend_expiration_dates script + # will skip all dates less than date(2023, 11, 15), meaning that this domain + # should not be affected by the change. + self.assertEqual(current_domain.expiration_date, date(2024, 12, 31)) def test_extends_expiration_date_skips_non_ready(self): """ Tests that the extend_expiration_dates method correctly skips domains not in the state "ready" """ - desired_domain = Domain.objects.filter(name="fakeneeded.gov").get() - desired_domain.expiration_date = datetime.date(2023, 11, 15) + with less_console_noise(): + desired_domain = Domain.objects.filter(name="fakeneeded.gov").get() + desired_domain.expiration_date = date(2023, 11, 15) - # Run the expiration date script - self.run_extend_expiration_dates() + # Run the expiration date script + self.run_extend_expiration_dates() - current_domain = Domain.objects.filter(name="fakeneeded.gov").get() - self.assertEqual(desired_domain, current_domain) + current_domain = Domain.objects.filter(name="fakeneeded.gov").get() + self.assertEqual(desired_domain, current_domain) - # Explicitly test the expiration date. The extend_expiration_dates script - # will skip all dates less than date(2023, 11, 15), meaning that this domain - # should not be affected by the change. - self.assertEqual(current_domain.expiration_date, datetime.date(2023, 11, 15)) + # Explicitly test the expiration date. The extend_expiration_dates script + # will skip all dates less than date(2023, 11, 15), meaning that this domain + # should not be affected by the change. + self.assertEqual(current_domain.expiration_date, date(2023, 11, 15)) def test_extends_expiration_date_idempotent(self): """ @@ -423,26 +394,21 @@ class TestExtendExpirationDates(MockEppLib): Verifies that running the method multiple times does not change the expiration date of a domain beyond the initial extension. """ - desired_domain = Domain.objects.filter(name="waterbutpurple.gov").get() - desired_domain.expiration_date = datetime.date(2024, 11, 15) - - # Run the expiration date script - self.run_extend_expiration_dates() - - current_domain = Domain.objects.filter(name="waterbutpurple.gov").get() - self.assertEqual(desired_domain, current_domain) - - # Explicitly test the expiration date - self.assertEqual(desired_domain.expiration_date, datetime.date(2024, 11, 15)) - - # Run the expiration date script again - self.run_extend_expiration_dates() - - # The old domain shouldn't have changed - self.assertEqual(desired_domain, current_domain) - - # Explicitly test the expiration date - should be the same - self.assertEqual(desired_domain.expiration_date, datetime.date(2024, 11, 15)) + with less_console_noise(): + desired_domain = Domain.objects.filter(name="waterbutpurple.gov").get() + desired_domain.expiration_date = date(2024, 11, 15) + # Run the expiration date script + self.run_extend_expiration_dates() + current_domain = Domain.objects.filter(name="waterbutpurple.gov").get() + self.assertEqual(desired_domain, current_domain) + # Explicitly test the expiration date + self.assertEqual(desired_domain.expiration_date, date(2024, 11, 15)) + # Run the expiration date script again + self.run_extend_expiration_dates() + # The old domain shouldn't have changed + self.assertEqual(desired_domain, current_domain) + # Explicitly test the expiration date - should be the same + self.assertEqual(desired_domain.expiration_date, date(2024, 11, 15)) class TestDiscloseEmails(MockEppLib): @@ -461,39 +427,41 @@ class TestDiscloseEmails(MockEppLib): The 'call_command' function from Django's management framework is then used to execute the disclose_security_emails command. """ - with patch( - "registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa - return_value=True, - ): - call_command("disclose_security_emails") + with less_console_noise(): + with patch( + "registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa + return_value=True, + ): + call_command("disclose_security_emails") def test_disclose_security_emails(self): """ Tests that command disclose_security_emails runs successfully with appropriate EPP calll to UpdateContact. """ - domain, _ = Domain.objects.get_or_create(name="testdisclose.gov", state=Domain.State.READY) - expectedSecContact = PublicContact.get_default_security() - expectedSecContact.domain = domain - expectedSecContact.email = "123@mail.gov" - # set domain security email to 123@mail.gov instead of default email - domain.security_contact = expectedSecContact - self.run_disclose_security_emails() + with less_console_noise(): + domain, _ = Domain.objects.get_or_create(name="testdisclose.gov", state=Domain.State.READY) + expectedSecContact = PublicContact.get_default_security() + expectedSecContact.domain = domain + expectedSecContact.email = "123@mail.gov" + # set domain security email to 123@mail.gov instead of default email + domain.security_contact = expectedSecContact + self.run_disclose_security_emails() - # running disclose_security_emails sends EPP call UpdateContact with disclose - self.mockedSendFunction.assert_has_calls( - [ - call( - commands.UpdateContact( - id=domain.security_contact.registry_id, - postal_info=domain._make_epp_contact_postal_info(contact=domain.security_contact), - email=domain.security_contact.email, - voice=domain.security_contact.voice, - fax=domain.security_contact.fax, - auth_info=common.ContactAuthInfo(pw="2fooBAR123fooBaz"), - disclose=domain._disclose_fields(contact=domain.security_contact), - ), - cleaned=True, - ) - ] - ) + # running disclose_security_emails sends EPP call UpdateContact with disclose + self.mockedSendFunction.assert_has_calls( + [ + call( + commands.UpdateContact( + id=domain.security_contact.registry_id, + postal_info=domain._make_epp_contact_postal_info(contact=domain.security_contact), + email=domain.security_contact.email, + voice=domain.security_contact.voice, + fax=domain.security_contact.fax, + auth_info=common.ContactAuthInfo(pw="2fooBAR123fooBaz"), + disclose=domain._disclose_fields(contact=domain.security_contact), + ), + cleaned=True, + ) + ] + ) diff --git a/src/registrar/tests/test_models.py b/src/registrar/tests/test_models.py index ef6522747..d2210394b 100644 --- a/src/registrar/tests/test_models.py +++ b/src/registrar/tests/test_models.py @@ -60,127 +60,134 @@ class TestDomainApplication(TestCase): def assertNotRaises(self, exception_type): """Helper method for testing allowed transitions.""" - return self.assertRaises(Exception, None, exception_type) + with less_console_noise(): + return self.assertRaises(Exception, None, exception_type) def test_empty_create_fails(self): """Can't create a completely empty domain application. NOTE: something about theexception this test raises messes up with the atomic block in a custom tearDown method for the parent test class.""" - with self.assertRaisesRegex(IntegrityError, "creator"): - DomainApplication.objects.create() + with less_console_noise(): + with self.assertRaisesRegex(IntegrityError, "creator"): + DomainApplication.objects.create() def test_minimal_create(self): """Can create with just a creator.""" - user, _ = User.objects.get_or_create(username="testy") - application = DomainApplication.objects.create(creator=user) - self.assertEqual(application.status, DomainApplication.ApplicationStatus.STARTED) + with less_console_noise(): + user, _ = User.objects.get_or_create(username="testy") + application = DomainApplication.objects.create(creator=user) + self.assertEqual(application.status, DomainApplication.ApplicationStatus.STARTED) def test_full_create(self): """Can create with all fields.""" - user, _ = User.objects.get_or_create(username="testy") - contact = Contact.objects.create() - com_website, _ = Website.objects.get_or_create(website="igorville.com") - gov_website, _ = Website.objects.get_or_create(website="igorville.gov") - domain, _ = DraftDomain.objects.get_or_create(name="igorville.gov") - application = DomainApplication.objects.create( - creator=user, - investigator=user, - organization_type=DomainApplication.OrganizationChoices.FEDERAL, - federal_type=DomainApplication.BranchChoices.EXECUTIVE, - is_election_board=False, - organization_name="Test", - address_line1="100 Main St.", - address_line2="APT 1A", - state_territory="CA", - zipcode="12345-6789", - authorizing_official=contact, - requested_domain=domain, - submitter=contact, - purpose="Igorville rules!", - anything_else="All of Igorville loves the dotgov program.", - is_policy_acknowledged=True, - ) - application.current_websites.add(com_website) - application.alternative_domains.add(gov_website) - application.other_contacts.add(contact) - application.save() + with less_console_noise(): + user, _ = User.objects.get_or_create(username="testy") + contact = Contact.objects.create() + com_website, _ = Website.objects.get_or_create(website="igorville.com") + gov_website, _ = Website.objects.get_or_create(website="igorville.gov") + domain, _ = DraftDomain.objects.get_or_create(name="igorville.gov") + application = DomainApplication.objects.create( + creator=user, + investigator=user, + organization_type=DomainApplication.OrganizationChoices.FEDERAL, + federal_type=DomainApplication.BranchChoices.EXECUTIVE, + is_election_board=False, + organization_name="Test", + address_line1="100 Main St.", + address_line2="APT 1A", + state_territory="CA", + zipcode="12345-6789", + authorizing_official=contact, + requested_domain=domain, + submitter=contact, + purpose="Igorville rules!", + anything_else="All of Igorville loves the dotgov program.", + is_policy_acknowledged=True, + ) + application.current_websites.add(com_website) + application.alternative_domains.add(gov_website) + application.other_contacts.add(contact) + application.save() def test_domain_info(self): """Can create domain info with all fields.""" - user, _ = User.objects.get_or_create(username="testy") - contact = Contact.objects.create() - domain, _ = Domain.objects.get_or_create(name="igorville.gov") - information = DomainInformation.objects.create( - creator=user, - organization_type=DomainInformation.OrganizationChoices.FEDERAL, - federal_type=DomainInformation.BranchChoices.EXECUTIVE, - is_election_board=False, - organization_name="Test", - address_line1="100 Main St.", - address_line2="APT 1A", - state_territory="CA", - zipcode="12345-6789", - authorizing_official=contact, - submitter=contact, - purpose="Igorville rules!", - anything_else="All of Igorville loves the dotgov program.", - is_policy_acknowledged=True, - domain=domain, - ) - information.other_contacts.add(contact) - information.save() - self.assertEqual(information.domain.id, domain.id) - self.assertEqual(information.id, domain.domain_info.id) + with less_console_noise(): + user, _ = User.objects.get_or_create(username="testy") + contact = Contact.objects.create() + domain, _ = Domain.objects.get_or_create(name="igorville.gov") + information = DomainInformation.objects.create( + creator=user, + organization_type=DomainInformation.OrganizationChoices.FEDERAL, + federal_type=DomainInformation.BranchChoices.EXECUTIVE, + is_election_board=False, + organization_name="Test", + address_line1="100 Main St.", + address_line2="APT 1A", + state_territory="CA", + zipcode="12345-6789", + authorizing_official=contact, + submitter=contact, + purpose="Igorville rules!", + anything_else="All of Igorville loves the dotgov program.", + is_policy_acknowledged=True, + domain=domain, + ) + information.other_contacts.add(contact) + information.save() + self.assertEqual(information.domain.id, domain.id) + self.assertEqual(information.id, domain.domain_info.id) def test_status_fsm_submit_fail(self): - user, _ = User.objects.get_or_create(username="testy") - application = DomainApplication.objects.create(creator=user) + with less_console_noise(): + user, _ = User.objects.get_or_create(username="testy") + application = DomainApplication.objects.create(creator=user) - with boto3_mocking.clients.handler_for("sesv2", self.mock_client): - with less_console_noise(): - with self.assertRaises(ValueError): - # can't submit an application with a null domain name - application.submit() + with boto3_mocking.clients.handler_for("sesv2", self.mock_client): + with less_console_noise(): + with self.assertRaises(ValueError): + # can't submit an application with a null domain name + application.submit() def test_status_fsm_submit_succeed(self): - user, _ = User.objects.get_or_create(username="testy") - site = DraftDomain.objects.create(name="igorville.gov") - application = DomainApplication.objects.create(creator=user, requested_domain=site) + with less_console_noise(): + user, _ = User.objects.get_or_create(username="testy") + site = DraftDomain.objects.create(name="igorville.gov") + application = DomainApplication.objects.create(creator=user, requested_domain=site) - # no submitter email so this emits a log warning + # no submitter email so this emits a log warning - with boto3_mocking.clients.handler_for("sesv2", self.mock_client): - with less_console_noise(): - application.submit() - self.assertEqual(application.status, application.ApplicationStatus.SUBMITTED) + with boto3_mocking.clients.handler_for("sesv2", self.mock_client): + with less_console_noise(): + application.submit() + self.assertEqual(application.status, application.ApplicationStatus.SUBMITTED) def test_submit_sends_email(self): """Create an application and submit it and see if email was sent.""" - user, _ = User.objects.get_or_create(username="testy") - contact = Contact.objects.create(email="test@test.gov") - domain, _ = DraftDomain.objects.get_or_create(name="igorville.gov") - application = DomainApplication.objects.create( - creator=user, - requested_domain=domain, - submitter=contact, - ) - application.save() + with less_console_noise(): + user, _ = User.objects.get_or_create(username="testy") + contact = Contact.objects.create(email="test@test.gov") + domain, _ = DraftDomain.objects.get_or_create(name="igorville.gov") + application = DomainApplication.objects.create( + creator=user, + requested_domain=domain, + submitter=contact, + ) + application.save() - with boto3_mocking.clients.handler_for("sesv2", self.mock_client): - with less_console_noise(): + with boto3_mocking.clients.handler_for("sesv2", self.mock_client): application.submit() - # check to see if an email was sent - self.assertGreater( - len( - [ - email - for email in MockSESClient.EMAILS_SENT - if "test@test.gov" in email["kwargs"]["Destination"]["ToAddresses"] - ] - ), - 0, - ) + # check to see if an email was sent + self.assertGreater( + len( + [ + email + for email in MockSESClient.EMAILS_SENT + if "test@test.gov" in email["kwargs"]["Destination"]["ToAddresses"] + ] + ), + 0, + ) def test_submit_transition_allowed(self): """ @@ -268,13 +275,13 @@ class TestDomainApplication(TestCase): (self.rejected_application, TransitionNotAllowed), (self.ineligible_application, TransitionNotAllowed), ] - - for application, exception_type in test_cases: - with self.subTest(application=application, exception_type=exception_type): - try: - application.action_needed() - except TransitionNotAllowed: - self.fail("TransitionNotAllowed was raised, but it was not expected.") + with less_console_noise(): + for application, exception_type in test_cases: + with self.subTest(application=application, exception_type=exception_type): + try: + application.action_needed() + except TransitionNotAllowed: + self.fail("TransitionNotAllowed was raised, but it was not expected.") def test_action_needed_transition_not_allowed(self): """ @@ -286,11 +293,11 @@ class TestDomainApplication(TestCase): (self.action_needed_application, TransitionNotAllowed), (self.withdrawn_application, TransitionNotAllowed), ] - - for application, exception_type in test_cases: - with self.subTest(application=application, exception_type=exception_type): - with self.assertRaises(exception_type): - application.action_needed() + with less_console_noise(): + for application, exception_type in test_cases: + with self.subTest(application=application, exception_type=exception_type): + with self.assertRaises(exception_type): + application.action_needed() def test_approved_transition_allowed(self): """ @@ -499,25 +506,29 @@ class TestDomainApplication(TestCase): def test_has_rationale_returns_true(self): """has_rationale() returns true when an application has no_other_contacts_rationale""" - self.started_application.no_other_contacts_rationale = "You talkin' to me?" - self.started_application.save() - self.assertEquals(self.started_application.has_rationale(), True) + with less_console_noise(): + self.started_application.no_other_contacts_rationale = "You talkin' to me?" + self.started_application.save() + self.assertEquals(self.started_application.has_rationale(), True) def test_has_rationale_returns_false(self): """has_rationale() returns false when an application has no no_other_contacts_rationale""" - self.assertEquals(self.started_application.has_rationale(), False) + with less_console_noise(): + self.assertEquals(self.started_application.has_rationale(), False) def test_has_other_contacts_returns_true(self): """has_other_contacts() returns true when an application has other_contacts""" - # completed_application has other contacts by default - self.assertEquals(self.started_application.has_other_contacts(), True) + with less_console_noise(): + # completed_application has other contacts by default + self.assertEquals(self.started_application.has_other_contacts(), True) def test_has_other_contacts_returns_false(self): """has_other_contacts() returns false when an application has no other_contacts""" - application = completed_application( - status=DomainApplication.ApplicationStatus.STARTED, name="no-others.gov", has_other_contacts=False - ) - self.assertEquals(application.has_other_contacts(), False) + with less_console_noise(): + application = completed_application( + status=DomainApplication.ApplicationStatus.STARTED, name="no-others.gov", has_other_contacts=False + ) + self.assertEquals(application.has_other_contacts(), False) class TestPermissions(TestCase): diff --git a/src/registrar/tests/test_models_domain.py b/src/registrar/tests/test_models_domain.py index 9026832cd..8cedb65e9 100644 --- a/src/registrar/tests/test_models_domain.py +++ b/src/registrar/tests/test_models_domain.py @@ -7,6 +7,7 @@ from django.test import TestCase from django.db.utils import IntegrityError from unittest.mock import MagicMock, patch, call import datetime +from django.utils.timezone import make_aware from registrar.models import Domain, Host, HostIP from unittest import skip @@ -46,158 +47,162 @@ class TestDomainCache(MockEppLib): def test_cache_sets_resets(self): """Cache should be set on getter and reset on setter calls""" - domain, _ = Domain.objects.get_or_create(name="igorville.gov") - # trigger getter - _ = domain.creation_date - domain._get_property("contacts") - # getter should set the domain cache with a InfoDomain object - # (see InfoDomainResult) - self.assertEquals(domain._cache["auth_info"], self.mockDataInfoDomain.auth_info) - self.assertEquals(domain._cache["cr_date"], self.mockDataInfoDomain.cr_date) - status_list = [status.state for status in self.mockDataInfoDomain.statuses] - self.assertEquals(domain._cache["statuses"], status_list) - self.assertFalse("avail" in domain._cache.keys()) + with less_console_noise(): + domain, _ = Domain.objects.get_or_create(name="igorville.gov") + # trigger getter + _ = domain.creation_date + domain._get_property("contacts") + # getter should set the domain cache with a InfoDomain object + # (see InfoDomainResult) + self.assertEquals(domain._cache["auth_info"], self.mockDataInfoDomain.auth_info) + self.assertEquals(domain._cache["cr_date"], self.mockDataInfoDomain.cr_date) + status_list = [status.state for status in self.mockDataInfoDomain.statuses] + self.assertEquals(domain._cache["statuses"], status_list) + self.assertFalse("avail" in domain._cache.keys()) - # using a setter should clear the cache - domain.dnssecdata = [] - self.assertEquals(domain._cache, {}) + # using a setter should clear the cache + domain.dnssecdata = [] + self.assertEquals(domain._cache, {}) - # send should have been called only once - self.mockedSendFunction.assert_has_calls( - [ - call( - commands.InfoDomain(name="igorville.gov", auth_info=None), - cleaned=True, - ), - ], - any_order=False, # Ensure calls are in the specified order - ) + # send should have been called only once + self.mockedSendFunction.assert_has_calls( + [ + call( + commands.InfoDomain(name="igorville.gov", auth_info=None), + cleaned=True, + ), + ], + any_order=False, # Ensure calls are in the specified order + ) def test_cache_used_when_avail(self): """Cache is pulled from if the object has already been accessed""" - domain, _ = Domain.objects.get_or_create(name="igorville.gov") - cr_date = domain.creation_date + with less_console_noise(): + domain, _ = Domain.objects.get_or_create(name="igorville.gov") + cr_date = domain.creation_date - # repeat the getter call - cr_date = domain.creation_date + # repeat the getter call + cr_date = domain.creation_date - # value should still be set correctly - self.assertEqual(cr_date, self.mockDataInfoDomain.cr_date) - self.assertEqual(domain._cache["cr_date"], self.mockDataInfoDomain.cr_date) + # value should still be set correctly + self.assertEqual(cr_date, self.mockDataInfoDomain.cr_date) + self.assertEqual(domain._cache["cr_date"], self.mockDataInfoDomain.cr_date) - # send was only called once & not on the second getter call - expectedCalls = [ - call(commands.InfoDomain(name="igorville.gov", auth_info=None), cleaned=True), - ] + # send was only called once & not on the second getter call + expectedCalls = [ + call(commands.InfoDomain(name="igorville.gov", auth_info=None), cleaned=True), + ] - self.mockedSendFunction.assert_has_calls(expectedCalls) + self.mockedSendFunction.assert_has_calls(expectedCalls) def test_cache_nested_elements(self): """Cache works correctly with the nested objects cache and hosts""" - domain, _ = Domain.objects.get_or_create(name="igorville.gov") - # The contact list will initially contain objects of type 'DomainContact' - # this is then transformed into PublicContact, and cache should NOT - # hold onto the DomainContact object - expectedUnfurledContactsList = [ - common.DomainContact(contact="123", type="security"), - ] - expectedContactsDict = { - PublicContact.ContactTypeChoices.ADMINISTRATIVE: None, - PublicContact.ContactTypeChoices.SECURITY: "123", - PublicContact.ContactTypeChoices.TECHNICAL: None, - } - expectedHostsDict = { - "name": self.mockDataInfoDomain.hosts[0], - "addrs": [item.addr for item in self.mockDataInfoHosts.addrs], - "cr_date": self.mockDataInfoHosts.cr_date, - } + with less_console_noise(): + domain, _ = Domain.objects.get_or_create(name="igorville.gov") + # The contact list will initially contain objects of type 'DomainContact' + # this is then transformed into PublicContact, and cache should NOT + # hold onto the DomainContact object + expectedUnfurledContactsList = [ + common.DomainContact(contact="123", type="security"), + ] + expectedContactsDict = { + PublicContact.ContactTypeChoices.ADMINISTRATIVE: None, + PublicContact.ContactTypeChoices.SECURITY: "123", + PublicContact.ContactTypeChoices.TECHNICAL: None, + } + expectedHostsDict = { + "name": self.mockDataInfoDomain.hosts[0], + "addrs": [item.addr for item in self.mockDataInfoHosts.addrs], + "cr_date": self.mockDataInfoHosts.cr_date, + } - # this can be changed when the getter for contacts is implemented - domain._get_property("contacts") + # this can be changed when the getter for contacts is implemented + domain._get_property("contacts") - # check domain info is still correct and not overridden - self.assertEqual(domain._cache["auth_info"], self.mockDataInfoDomain.auth_info) - self.assertEqual(domain._cache["cr_date"], self.mockDataInfoDomain.cr_date) + # check domain info is still correct and not overridden + self.assertEqual(domain._cache["auth_info"], self.mockDataInfoDomain.auth_info) + self.assertEqual(domain._cache["cr_date"], self.mockDataInfoDomain.cr_date) - # check contacts - self.assertEqual(domain._cache["_contacts"], self.mockDataInfoDomain.contacts) - # The contact list should not contain what is sent by the registry by default, - # as _fetch_cache will transform the type to PublicContact - self.assertNotEqual(domain._cache["contacts"], expectedUnfurledContactsList) - self.assertEqual(domain._cache["contacts"], expectedContactsDict) + # check contacts + self.assertEqual(domain._cache["_contacts"], self.mockDataInfoDomain.contacts) + # The contact list should not contain what is sent by the registry by default, + # as _fetch_cache will transform the type to PublicContact + self.assertNotEqual(domain._cache["contacts"], expectedUnfurledContactsList) + self.assertEqual(domain._cache["contacts"], expectedContactsDict) - # get and check hosts is set correctly - domain._get_property("hosts") - self.assertEqual(domain._cache["hosts"], [expectedHostsDict]) - self.assertEqual(domain._cache["contacts"], expectedContactsDict) - # invalidate cache - domain._cache = {} + # get and check hosts is set correctly + domain._get_property("hosts") + self.assertEqual(domain._cache["hosts"], [expectedHostsDict]) + self.assertEqual(domain._cache["contacts"], expectedContactsDict) + # invalidate cache + domain._cache = {} - # get host - domain._get_property("hosts") - self.assertEqual(domain._cache["hosts"], [expectedHostsDict]) + # get host + domain._get_property("hosts") + self.assertEqual(domain._cache["hosts"], [expectedHostsDict]) - # get contacts - domain._get_property("contacts") - self.assertEqual(domain._cache["hosts"], [expectedHostsDict]) - self.assertEqual(domain._cache["contacts"], expectedContactsDict) + # get contacts + domain._get_property("contacts") + self.assertEqual(domain._cache["hosts"], [expectedHostsDict]) + self.assertEqual(domain._cache["contacts"], expectedContactsDict) def test_map_epp_contact_to_public_contact(self): # Tests that the mapper is working how we expect - domain, _ = Domain.objects.get_or_create(name="registry.gov") - security = PublicContact.ContactTypeChoices.SECURITY - mapped = domain.map_epp_contact_to_public_contact( - self.mockDataInfoContact, - self.mockDataInfoContact.id, - security, - ) + with less_console_noise(): + domain, _ = Domain.objects.get_or_create(name="registry.gov") + security = PublicContact.ContactTypeChoices.SECURITY + mapped = domain.map_epp_contact_to_public_contact( + self.mockDataInfoContact, + self.mockDataInfoContact.id, + security, + ) - expected_contact = PublicContact( - domain=domain, - contact_type=security, - registry_id="123", - email="123@mail.gov", - voice="+1.8882820870", - fax="+1-212-9876543", - pw="lastPw", - name="Registry Customer Service", - org="Cybersecurity and Infrastructure Security Agency", - city="Arlington", - pc="22201", - cc="US", - sp="VA", - street1="4200 Wilson Blvd.", - ) + expected_contact = PublicContact( + domain=domain, + contact_type=security, + registry_id="123", + email="123@mail.gov", + voice="+1.8882820870", + fax="+1-212-9876543", + pw="lastPw", + name="Registry Customer Service", + org="Cybersecurity and Infrastructure Security Agency", + city="Arlington", + pc="22201", + cc="US", + sp="VA", + street1="4200 Wilson Blvd.", + ) - # Test purposes only, since we're comparing - # two duplicate objects. We would expect - # these not to have the same state. - expected_contact._state = mapped._state + # Test purposes only, since we're comparing + # two duplicate objects. We would expect + # these not to have the same state. + expected_contact._state = mapped._state - # Mapped object is what we expect - self.assertEqual(mapped.__dict__, expected_contact.__dict__) + # Mapped object is what we expect + self.assertEqual(mapped.__dict__, expected_contact.__dict__) - # The mapped object should correctly translate to a DB - # object. If not, something else went wrong. - db_object = domain._get_or_create_public_contact(mapped) - in_db = PublicContact.objects.filter( - registry_id=domain.security_contact.registry_id, - contact_type=security, - ).get() - # DB Object is the same as the mapped object - self.assertEqual(db_object, in_db) + # The mapped object should correctly translate to a DB + # object. If not, something else went wrong. + db_object = domain._get_or_create_public_contact(mapped) + in_db = PublicContact.objects.filter( + registry_id=domain.security_contact.registry_id, + contact_type=security, + ).get() + # DB Object is the same as the mapped object + self.assertEqual(db_object, in_db) - domain.security_contact = in_db - # Trigger the getter - _ = domain.security_contact - # Check to see that changes made - # to DB objects persist in cache correctly - in_db.email = "123test@mail.gov" - in_db.save() + domain.security_contact = in_db + # Trigger the getter + _ = domain.security_contact + # Check to see that changes made + # to DB objects persist in cache correctly + in_db.email = "123test@mail.gov" + in_db.save() - cached_contact = domain._cache["contacts"].get(security) - self.assertEqual(cached_contact, in_db.registry_id) - self.assertEqual(domain.security_contact.email, "123test@mail.gov") + cached_contact = domain._cache["contacts"].get(security) + self.assertEqual(cached_contact, in_db.registry_id) + self.assertEqual(domain.security_contact.email, "123test@mail.gov") def test_errors_map_epp_contact_to_public_contact(self): """ @@ -206,48 +211,49 @@ class TestDomainCache(MockEppLib): gets invalid data from EPPLib Then the function throws the expected ContactErrors """ - domain, _ = Domain.objects.get_or_create(name="registry.gov") - fakedEpp = self.fakedEppObject() - invalid_length = fakedEpp.dummyInfoContactResultData( - "Cymaticsisasubsetofmodalvibrationalphenomena", "lengthInvalid@mail.gov" - ) - valid_object = fakedEpp.dummyInfoContactResultData("valid", "valid@mail.gov") - - desired_error = ContactErrorCodes.CONTACT_ID_INVALID_LENGTH - with self.assertRaises(ContactError) as context: - domain.map_epp_contact_to_public_contact( - invalid_length, - invalid_length.id, - PublicContact.ContactTypeChoices.SECURITY, + with less_console_noise(): + domain, _ = Domain.objects.get_or_create(name="registry.gov") + fakedEpp = self.fakedEppObject() + invalid_length = fakedEpp.dummyInfoContactResultData( + "Cymaticsisasubsetofmodalvibrationalphenomena", "lengthInvalid@mail.gov" ) - self.assertEqual(context.exception.code, desired_error) + valid_object = fakedEpp.dummyInfoContactResultData("valid", "valid@mail.gov") - desired_error = ContactErrorCodes.CONTACT_ID_NONE - with self.assertRaises(ContactError) as context: - domain.map_epp_contact_to_public_contact( - valid_object, - None, - PublicContact.ContactTypeChoices.SECURITY, - ) - self.assertEqual(context.exception.code, desired_error) + desired_error = ContactErrorCodes.CONTACT_ID_INVALID_LENGTH + with self.assertRaises(ContactError) as context: + domain.map_epp_contact_to_public_contact( + invalid_length, + invalid_length.id, + PublicContact.ContactTypeChoices.SECURITY, + ) + self.assertEqual(context.exception.code, desired_error) - desired_error = ContactErrorCodes.CONTACT_INVALID_TYPE - with self.assertRaises(ContactError) as context: - domain.map_epp_contact_to_public_contact( - "bad_object", - valid_object.id, - PublicContact.ContactTypeChoices.SECURITY, - ) - self.assertEqual(context.exception.code, desired_error) + desired_error = ContactErrorCodes.CONTACT_ID_NONE + with self.assertRaises(ContactError) as context: + domain.map_epp_contact_to_public_contact( + valid_object, + None, + PublicContact.ContactTypeChoices.SECURITY, + ) + self.assertEqual(context.exception.code, desired_error) - desired_error = ContactErrorCodes.CONTACT_TYPE_NONE - with self.assertRaises(ContactError) as context: - domain.map_epp_contact_to_public_contact( - valid_object, - valid_object.id, - None, - ) - self.assertEqual(context.exception.code, desired_error) + desired_error = ContactErrorCodes.CONTACT_INVALID_TYPE + with self.assertRaises(ContactError) as context: + domain.map_epp_contact_to_public_contact( + "bad_object", + valid_object.id, + PublicContact.ContactTypeChoices.SECURITY, + ) + self.assertEqual(context.exception.code, desired_error) + + desired_error = ContactErrorCodes.CONTACT_TYPE_NONE + with self.assertRaises(ContactError) as context: + domain.map_epp_contact_to_public_contact( + valid_object, + valid_object.id, + None, + ) + self.assertEqual(context.exception.code, desired_error) class TestDomainCreation(MockEppLib): @@ -346,42 +352,44 @@ class TestDomainStatuses(MockEppLib): def test_get_status(self): """Domain 'statuses' getter returns statuses by calling epp""" - domain, _ = Domain.objects.get_or_create(name="chicken-liver.gov") - # trigger getter - _ = domain.statuses - status_list = [status.state for status in self.mockDataInfoDomain.statuses] - self.assertEquals(domain._cache["statuses"], status_list) - # Called in _fetch_cache - self.mockedSendFunction.assert_has_calls( - [ - call( - commands.InfoDomain(name="chicken-liver.gov", auth_info=None), - cleaned=True, - ), - ], - any_order=False, # Ensure calls are in the specified order - ) + with less_console_noise(): + domain, _ = Domain.objects.get_or_create(name="chicken-liver.gov") + # trigger getter + _ = domain.statuses + status_list = [status.state for status in self.mockDataInfoDomain.statuses] + self.assertEquals(domain._cache["statuses"], status_list) + # Called in _fetch_cache + self.mockedSendFunction.assert_has_calls( + [ + call( + commands.InfoDomain(name="chicken-liver.gov", auth_info=None), + cleaned=True, + ), + ], + any_order=False, # Ensure calls are in the specified order + ) def test_get_status_returns_empty_list_when_value_error(self): """Domain 'statuses' getter returns an empty list when value error""" - domain, _ = Domain.objects.get_or_create(name="pig-knuckles.gov") + with less_console_noise(): + domain, _ = Domain.objects.get_or_create(name="pig-knuckles.gov") - def side_effect(self): - raise KeyError + def side_effect(self): + raise KeyError - patcher = patch("registrar.models.domain.Domain._get_property") - mocked_get = patcher.start() - mocked_get.side_effect = side_effect + patcher = patch("registrar.models.domain.Domain._get_property") + mocked_get = patcher.start() + mocked_get.side_effect = side_effect - # trigger getter - _ = domain.statuses + # trigger getter + _ = domain.statuses - with self.assertRaises(KeyError): - _ = domain._cache["statuses"] - self.assertEquals(_, []) + with self.assertRaises(KeyError): + _ = domain._cache["statuses"] + self.assertEquals(_, []) - patcher.stop() + patcher.stop() @skip("not implemented yet") def test_place_client_hold_sets_status(self): @@ -398,28 +406,23 @@ class TestDomainStatuses(MockEppLib): first_ready is set when a domain is first transitioned to READY. It does not get overwritten in case the domain gets out of and back into READY. """ - domain, _ = Domain.objects.get_or_create(name="pig-knuckles.gov", state=Domain.State.DNS_NEEDED) - self.assertEqual(domain.first_ready, None) - - domain.ready() - - # check that status is READY - self.assertTrue(domain.is_active()) - self.assertNotEqual(domain.first_ready, None) - - # Capture the value of first_ready - first_ready = domain.first_ready - - # change domain status - domain.dns_needed() - self.assertFalse(domain.is_active()) - - # change back to READY - domain.ready() - self.assertTrue(domain.is_active()) - - # assert that the value of first_ready has not changed - self.assertEqual(domain.first_ready, first_ready) + with less_console_noise(): + domain, _ = Domain.objects.get_or_create(name="pig-knuckles.gov", state=Domain.State.DNS_NEEDED) + self.assertEqual(domain.first_ready, None) + domain.ready() + # check that status is READY + self.assertTrue(domain.is_active()) + self.assertNotEqual(domain.first_ready, None) + # Capture the value of first_ready + first_ready = domain.first_ready + # change domain status + domain.dns_needed() + self.assertFalse(domain.is_active()) + # change back to READY + domain.ready() + self.assertTrue(domain.is_active()) + # assert that the value of first_ready has not changed + self.assertEqual(domain.first_ready, first_ready) def tearDown(self) -> None: PublicContact.objects.all().delete() @@ -557,37 +560,32 @@ class TestRegistrantContacts(MockEppLib): Then the domain has a valid security contact with CISA defaults And disclose flags are set to keep the email address hidden """ - - # making a domain should make it domain - expectedSecContact = PublicContact.get_default_security() - expectedSecContact.domain = self.domain - - self.domain.dns_needed_from_unknown() - - self.assertEqual(self.mockedSendFunction.call_count, 8) - self.assertEqual(PublicContact.objects.filter(domain=self.domain).count(), 4) - self.assertEqual( - PublicContact.objects.get( + with less_console_noise(): + # making a domain should make it domain + expectedSecContact = PublicContact.get_default_security() + expectedSecContact.domain = self.domain + self.domain.dns_needed_from_unknown() + self.assertEqual(self.mockedSendFunction.call_count, 8) + self.assertEqual(PublicContact.objects.filter(domain=self.domain).count(), 4) + self.assertEqual( + PublicContact.objects.get( + domain=self.domain, + contact_type=PublicContact.ContactTypeChoices.SECURITY, + ).email, + expectedSecContact.email, + ) + id = PublicContact.objects.get( domain=self.domain, contact_type=PublicContact.ContactTypeChoices.SECURITY, - ).email, - expectedSecContact.email, - ) - - id = PublicContact.objects.get( - domain=self.domain, - contact_type=PublicContact.ContactTypeChoices.SECURITY, - ).registry_id - - expectedSecContact.registry_id = id - expectedCreateCommand = self._convertPublicContactToEpp(expectedSecContact, disclose_email=False) - expectedUpdateDomain = commands.UpdateDomain( - name=self.domain.name, - add=[common.DomainContact(contact=expectedSecContact.registry_id, type="security")], - ) - - self.mockedSendFunction.assert_any_call(expectedCreateCommand, cleaned=True) - self.mockedSendFunction.assert_any_call(expectedUpdateDomain, cleaned=True) + ).registry_id + expectedSecContact.registry_id = id + expectedCreateCommand = self._convertPublicContactToEpp(expectedSecContact, disclose_email=False) + expectedUpdateDomain = commands.UpdateDomain( + name=self.domain.name, + add=[common.DomainContact(contact=expectedSecContact.registry_id, type="security")], + ) + self.mockedSendFunction.assert_any_call(expectedCreateCommand, cleaned=True) + self.mockedSendFunction.assert_any_call(expectedUpdateDomain, cleaned=True) def test_user_adds_security_email(self): """ @@ -598,35 +596,31 @@ class TestRegistrantContacts(MockEppLib): And Domain sends `commands.UpdateDomain` to the registry with the newly created contact of type 'security' """ - # make a security contact that is a PublicContact - # make sure a security email already exists - self.domain.dns_needed_from_unknown() - expectedSecContact = PublicContact.get_default_security() - expectedSecContact.domain = self.domain - expectedSecContact.email = "newEmail@fake.com" - expectedSecContact.registry_id = "456" - expectedSecContact.name = "Fakey McFakerson" - - # calls the security contact setter as if you did - # self.domain.security_contact=expectedSecContact - expectedSecContact.save() - - # no longer the default email it should be disclosed - expectedCreateCommand = self._convertPublicContactToEpp(expectedSecContact, disclose_email=True) - - expectedUpdateDomain = commands.UpdateDomain( - name=self.domain.name, - add=[common.DomainContact(contact=expectedSecContact.registry_id, type="security")], - ) - - # check that send has triggered the create command for the contact - receivedSecurityContact = PublicContact.objects.get( - domain=self.domain, contact_type=PublicContact.ContactTypeChoices.SECURITY - ) - - self.assertEqual(receivedSecurityContact, expectedSecContact) - self.mockedSendFunction.assert_any_call(expectedCreateCommand, cleaned=True) - self.mockedSendFunction.assert_any_call(expectedUpdateDomain, cleaned=True) + with less_console_noise(): + # make a security contact that is a PublicContact + # make sure a security email already exists + self.domain.dns_needed_from_unknown() + expectedSecContact = PublicContact.get_default_security() + expectedSecContact.domain = self.domain + expectedSecContact.email = "newEmail@fake.com" + expectedSecContact.registry_id = "456" + expectedSecContact.name = "Fakey McFakerson" + # calls the security contact setter as if you did + # self.domain.security_contact=expectedSecContact + expectedSecContact.save() + # no longer the default email it should be disclosed + expectedCreateCommand = self._convertPublicContactToEpp(expectedSecContact, disclose_email=True) + expectedUpdateDomain = commands.UpdateDomain( + name=self.domain.name, + add=[common.DomainContact(contact=expectedSecContact.registry_id, type="security")], + ) + # check that send has triggered the create command for the contact + receivedSecurityContact = PublicContact.objects.get( + domain=self.domain, contact_type=PublicContact.ContactTypeChoices.SECURITY + ) + self.assertEqual(receivedSecurityContact, expectedSecContact) + self.mockedSendFunction.assert_any_call(expectedCreateCommand, cleaned=True) + self.mockedSendFunction.assert_any_call(expectedUpdateDomain, cleaned=True) def test_security_email_is_idempotent(self): """ @@ -635,26 +629,23 @@ class TestRegistrantContacts(MockEppLib): to the registry twice with identical data Then no errors are raised in Domain """ - - security_contact = self.domain.get_default_security_contact() - security_contact.registry_id = "fail" - security_contact.save() - - self.domain.security_contact = security_contact - - expectedCreateCommand = self._convertPublicContactToEpp(security_contact, disclose_email=False) - - expectedUpdateDomain = commands.UpdateDomain( - name=self.domain.name, - add=[common.DomainContact(contact=security_contact.registry_id, type="security")], - ) - expected_calls = [ - call(expectedCreateCommand, cleaned=True), - call(expectedCreateCommand, cleaned=True), - call(expectedUpdateDomain, cleaned=True), - ] - self.mockedSendFunction.assert_has_calls(expected_calls, any_order=True) - self.assertEqual(PublicContact.objects.filter(domain=self.domain).count(), 1) + with less_console_noise(): + security_contact = self.domain.get_default_security_contact() + security_contact.registry_id = "fail" + security_contact.save() + self.domain.security_contact = security_contact + expectedCreateCommand = self._convertPublicContactToEpp(security_contact, disclose_email=False) + expectedUpdateDomain = commands.UpdateDomain( + name=self.domain.name, + add=[common.DomainContact(contact=security_contact.registry_id, type="security")], + ) + expected_calls = [ + call(expectedCreateCommand, cleaned=True), + call(expectedCreateCommand, cleaned=True), + call(expectedUpdateDomain, cleaned=True), + ] + self.mockedSendFunction.assert_has_calls(expected_calls, any_order=True) + self.assertEqual(PublicContact.objects.filter(domain=self.domain).count(), 1) def test_user_deletes_security_email(self): """ @@ -667,51 +658,47 @@ class TestRegistrantContacts(MockEppLib): And the domain has a valid security contact with CISA defaults And disclose flags are set to keep the email address hidden """ - old_contact = self.domain.get_default_security_contact() - - old_contact.registry_id = "fail" - old_contact.email = "user.entered@email.com" - old_contact.save() - new_contact = self.domain.get_default_security_contact() - new_contact.registry_id = "fail" - new_contact.email = "" - self.domain.security_contact = new_contact - - firstCreateContactCall = self._convertPublicContactToEpp(old_contact, disclose_email=True) - updateDomainAddCall = commands.UpdateDomain( - name=self.domain.name, - add=[common.DomainContact(contact=old_contact.registry_id, type="security")], - ) - self.assertEqual( - PublicContact.objects.filter(domain=self.domain).get().email, - PublicContact.get_default_security().email, - ) - # this one triggers the fail - secondCreateContact = self._convertPublicContactToEpp(new_contact, disclose_email=True) - updateDomainRemCall = commands.UpdateDomain( - name=self.domain.name, - rem=[common.DomainContact(contact=old_contact.registry_id, type="security")], - ) - - defaultSecID = PublicContact.objects.filter(domain=self.domain).get().registry_id - default_security = PublicContact.get_default_security() - default_security.registry_id = defaultSecID - createDefaultContact = self._convertPublicContactToEpp(default_security, disclose_email=False) - updateDomainWDefault = commands.UpdateDomain( - name=self.domain.name, - add=[common.DomainContact(contact=defaultSecID, type="security")], - ) - - expected_calls = [ - call(firstCreateContactCall, cleaned=True), - call(updateDomainAddCall, cleaned=True), - call(secondCreateContact, cleaned=True), - call(updateDomainRemCall, cleaned=True), - call(createDefaultContact, cleaned=True), - call(updateDomainWDefault, cleaned=True), - ] - - self.mockedSendFunction.assert_has_calls(expected_calls, any_order=True) + with less_console_noise(): + old_contact = self.domain.get_default_security_contact() + old_contact.registry_id = "fail" + old_contact.email = "user.entered@email.com" + old_contact.save() + new_contact = self.domain.get_default_security_contact() + new_contact.registry_id = "fail" + new_contact.email = "" + self.domain.security_contact = new_contact + firstCreateContactCall = self._convertPublicContactToEpp(old_contact, disclose_email=True) + updateDomainAddCall = commands.UpdateDomain( + name=self.domain.name, + add=[common.DomainContact(contact=old_contact.registry_id, type="security")], + ) + self.assertEqual( + PublicContact.objects.filter(domain=self.domain).get().email, + PublicContact.get_default_security().email, + ) + # this one triggers the fail + secondCreateContact = self._convertPublicContactToEpp(new_contact, disclose_email=True) + updateDomainRemCall = commands.UpdateDomain( + name=self.domain.name, + rem=[common.DomainContact(contact=old_contact.registry_id, type="security")], + ) + defaultSecID = PublicContact.objects.filter(domain=self.domain).get().registry_id + default_security = PublicContact.get_default_security() + default_security.registry_id = defaultSecID + createDefaultContact = self._convertPublicContactToEpp(default_security, disclose_email=False) + updateDomainWDefault = commands.UpdateDomain( + name=self.domain.name, + add=[common.DomainContact(contact=defaultSecID, type="security")], + ) + expected_calls = [ + call(firstCreateContactCall, cleaned=True), + call(updateDomainAddCall, cleaned=True), + call(secondCreateContact, cleaned=True), + call(updateDomainRemCall, cleaned=True), + call(createDefaultContact, cleaned=True), + call(updateDomainWDefault, cleaned=True), + ] + self.mockedSendFunction.assert_has_calls(expected_calls, any_order=True) def test_updates_security_email(self): """ @@ -721,29 +708,28 @@ class TestRegistrantContacts(MockEppLib): security contact email Then Domain sends `commands.UpdateContact` to the registry """ - security_contact = self.domain.get_default_security_contact() - security_contact.email = "originalUserEmail@gmail.com" - security_contact.registry_id = "fail" - security_contact.save() - expectedCreateCommand = self._convertPublicContactToEpp(security_contact, disclose_email=True) - - expectedUpdateDomain = commands.UpdateDomain( - name=self.domain.name, - add=[common.DomainContact(contact=security_contact.registry_id, type="security")], - ) - security_contact.email = "changedEmail@email.com" - security_contact.save() - expectedSecondCreateCommand = self._convertPublicContactToEpp(security_contact, disclose_email=True) - updateContact = self._convertPublicContactToEpp(security_contact, disclose_email=True, createContact=False) - - expected_calls = [ - call(expectedCreateCommand, cleaned=True), - call(expectedUpdateDomain, cleaned=True), - call(expectedSecondCreateCommand, cleaned=True), - call(updateContact, cleaned=True), - ] - self.mockedSendFunction.assert_has_calls(expected_calls, any_order=True) - self.assertEqual(PublicContact.objects.filter(domain=self.domain).count(), 1) + with less_console_noise(): + security_contact = self.domain.get_default_security_contact() + security_contact.email = "originalUserEmail@gmail.com" + security_contact.registry_id = "fail" + security_contact.save() + expectedCreateCommand = self._convertPublicContactToEpp(security_contact, disclose_email=True) + expectedUpdateDomain = commands.UpdateDomain( + name=self.domain.name, + add=[common.DomainContact(contact=security_contact.registry_id, type="security")], + ) + security_contact.email = "changedEmail@email.com" + security_contact.save() + expectedSecondCreateCommand = self._convertPublicContactToEpp(security_contact, disclose_email=True) + updateContact = self._convertPublicContactToEpp(security_contact, disclose_email=True, createContact=False) + expected_calls = [ + call(expectedCreateCommand, cleaned=True), + call(expectedUpdateDomain, cleaned=True), + call(expectedSecondCreateCommand, cleaned=True), + call(updateContact, cleaned=True), + ] + self.mockedSendFunction.assert_has_calls(expected_calls, any_order=True) + self.assertEqual(PublicContact.objects.filter(domain=self.domain).count(), 1) def test_security_email_returns_on_registry_error(self): """ @@ -751,28 +737,24 @@ class TestRegistrantContacts(MockEppLib): Registry is unavailable and throws exception when attempting to build cache from registry. Security email retrieved from database. """ - # Use self.domain_contact which has been initialized with existing contacts, including securityContact - - # call get_security_email to initially set the security_contact_registry_id in the domain model - self.domain_contact.get_security_email() - # invalidate the cache so the next time get_security_email is called, it has to attempt to populate cache - self.domain_contact._invalidate_cache() - - # mock that registry throws an error on the EPP send - def side_effect(_request, cleaned): - raise RegistryError(code=ErrorCode.COMMAND_FAILED) - - patcher = patch("registrar.models.domain.registry.send") - mocked_send = patcher.start() - mocked_send.side_effect = side_effect - - # when get_security_email is called, the registry error will force the security contact - # to be retrieved using the security_contact_registry_id in the domain model - security_email = self.domain_contact.get_security_email() - - # assert that the proper security contact was retrieved by testing the email matches expected value - self.assertEqual(security_email, "security@mail.gov") - patcher.stop() + with less_console_noise(): + # Use self.domain_contact which has been initialized with existing contacts, including securityContact + # call get_security_email to initially set the security_contact_registry_id in the domain model + self.domain_contact.get_security_email() + # invalidate the cache so the next time get_security_email is called, it has to attempt to populate cache + self.domain_contact._invalidate_cache() + # mock that registry throws an error on the EPP send + def side_effect(_request, cleaned): + raise RegistryError(code=ErrorCode.COMMAND_FAILED) + patcher = patch("registrar.models.domain.registry.send") + mocked_send = patcher.start() + mocked_send.side_effect = side_effect + # when get_security_email is called, the registry error will force the security contact + # to be retrieved using the security_contact_registry_id in the domain model + security_email = self.domain_contact.get_security_email() + # assert that the proper security contact was retrieved by testing the email matches expected value + self.assertEqual(security_email, "security@mail.gov") + patcher.stop() def test_security_email_stored_on_fetch_cache(self): """ @@ -781,13 +763,14 @@ class TestRegistrantContacts(MockEppLib): The mocked data for the EPP calls for the freeman.gov domain returns a security contact with registry id of securityContact when InfoContact is called """ - # Use self.domain_contact which has been initialized with existing contacts, including securityContact + with less_console_noise(): + # Use self.domain_contact which has been initialized with existing contacts, including securityContact - # force fetch_cache to be called, which will return above documented mocked hosts - self.domain_contact.get_security_email() + # force fetch_cache to be called, which will return above documented mocked hosts + self.domain_contact.get_security_email() - # assert that the security_contact_registry_id in the db matches "securityContact" - self.assertEqual(self.domain_contact.security_contact_registry_id, "securityContact") + # assert that the security_contact_registry_id in the db matches "securityContact" + self.assertEqual(self.domain_contact.security_contact_registry_id, "securityContact") def test_not_disclosed_on_other_contacts(self): """ @@ -798,113 +781,101 @@ class TestRegistrantContacts(MockEppLib): And the field `disclose` is set to false for DF.EMAIL on all fields except security """ - # Generates a domain with four existing contacts - domain, _ = Domain.objects.get_or_create(name="freeman.gov") - - # Contact setup - expected_admin = domain.get_default_administrative_contact() - expected_admin.email = self.mockAdministrativeContact.email - - expected_registrant = domain.get_default_registrant_contact() - expected_registrant.email = self.mockRegistrantContact.email - - expected_security = domain.get_default_security_contact() - expected_security.email = self.mockSecurityContact.email - - expected_tech = domain.get_default_technical_contact() - expected_tech.email = self.mockTechnicalContact.email - - domain.administrative_contact = expected_admin - domain.registrant_contact = expected_registrant - domain.security_contact = expected_security - domain.technical_contact = expected_tech - - contacts = [ - (expected_admin, domain.administrative_contact), - (expected_registrant, domain.registrant_contact), - (expected_security, domain.security_contact), - (expected_tech, domain.technical_contact), - ] - - # Test for each contact - for contact in contacts: - expected_contact = contact[0] - actual_contact = contact[1] - is_security = expected_contact.contact_type == "security" - - expectedCreateCommand = self._convertPublicContactToEpp(expected_contact, disclose_email=is_security) - - # Should only be disclosed if the type is security, as the email is valid - self.mockedSendFunction.assert_any_call(expectedCreateCommand, cleaned=True) - - # The emails should match on both items - self.assertEqual(expected_contact.email, actual_contact.email) + with less_console_noise(): + # Generates a domain with four existing contacts + domain, _ = Domain.objects.get_or_create(name="freeman.gov") + # Contact setup + expected_admin = domain.get_default_administrative_contact() + expected_admin.email = self.mockAdministrativeContact.email + expected_registrant = domain.get_default_registrant_contact() + expected_registrant.email = self.mockRegistrantContact.email + expected_security = domain.get_default_security_contact() + expected_security.email = self.mockSecurityContact.email + expected_tech = domain.get_default_technical_contact() + expected_tech.email = self.mockTechnicalContact.email + domain.administrative_contact = expected_admin + domain.registrant_contact = expected_registrant + domain.security_contact = expected_security + domain.technical_contact = expected_tech + contacts = [ + (expected_admin, domain.administrative_contact), + (expected_registrant, domain.registrant_contact), + (expected_security, domain.security_contact), + (expected_tech, domain.technical_contact), + ] + # Test for each contact + for contact in contacts: + expected_contact = contact[0] + actual_contact = contact[1] + is_security = expected_contact.contact_type == "security" + expectedCreateCommand = self._convertPublicContactToEpp(expected_contact, disclose_email=is_security) + # Should only be disclosed if the type is security, as the email is valid + self.mockedSendFunction.assert_any_call(expectedCreateCommand, cleaned=True) + # The emails should match on both items + self.assertEqual(expected_contact.email, actual_contact.email) def test_convert_public_contact_to_epp(self): - domain, _ = Domain.objects.get_or_create(name="freeman.gov") - dummy_contact = domain.get_default_security_contact() - test_disclose = self._convertPublicContactToEpp(dummy_contact, disclose_email=True).__dict__ - test_not_disclose = self._convertPublicContactToEpp(dummy_contact, disclose_email=False).__dict__ - - # Separated for linter - disclose_email_field = {common.DiscloseField.EMAIL} - expected_disclose = { - "auth_info": common.ContactAuthInfo(pw="2fooBAR123fooBaz"), - "disclose": common.Disclose(flag=True, fields=disclose_email_field, types=None), - "email": "dotgov@cisa.dhs.gov", - "extensions": [], - "fax": None, - "id": "ThIq2NcRIDN7PauO", - "ident": None, - "notify_email": None, - "postal_info": common.PostalInfo( - name="Registry Customer Service", - addr=common.ContactAddr( - street=["4200 Wilson Blvd.", None, None], - city="Arlington", - pc="22201", - cc="US", - sp="VA", + with less_console_noise(): + domain, _ = Domain.objects.get_or_create(name="freeman.gov") + dummy_contact = domain.get_default_security_contact() + test_disclose = self._convertPublicContactToEpp(dummy_contact, disclose_email=True).__dict__ + test_not_disclose = self._convertPublicContactToEpp(dummy_contact, disclose_email=False).__dict__ + # Separated for linter + disclose_email_field = {common.DiscloseField.EMAIL} + expected_disclose = { + "auth_info": common.ContactAuthInfo(pw="2fooBAR123fooBaz"), + "disclose": common.Disclose(flag=True, fields=disclose_email_field, types=None), + "email": "dotgov@cisa.dhs.gov", + "extensions": [], + "fax": None, + "id": "ThIq2NcRIDN7PauO", + "ident": None, + "notify_email": None, + "postal_info": common.PostalInfo( + name="Registry Customer Service", + addr=common.ContactAddr( + street=["4200 Wilson Blvd.", None, None], + city="Arlington", + pc="22201", + cc="US", + sp="VA", + ), + org="Cybersecurity and Infrastructure Security Agency", + type="loc", ), - org="Cybersecurity and Infrastructure Security Agency", - type="loc", - ), - "vat": None, - "voice": "+1.8882820870", - } - - # Separated for linter - expected_not_disclose = { - "auth_info": common.ContactAuthInfo(pw="2fooBAR123fooBaz"), - "disclose": common.Disclose(flag=False, fields=disclose_email_field, types=None), - "email": "dotgov@cisa.dhs.gov", - "extensions": [], - "fax": None, - "id": "ThrECENCHI76PGLh", - "ident": None, - "notify_email": None, - "postal_info": common.PostalInfo( - name="Registry Customer Service", - addr=common.ContactAddr( - street=["4200 Wilson Blvd.", None, None], - city="Arlington", - pc="22201", - cc="US", - sp="VA", + "vat": None, + "voice": "+1.8882820870", + } + # Separated for linter + expected_not_disclose = { + "auth_info": common.ContactAuthInfo(pw="2fooBAR123fooBaz"), + "disclose": common.Disclose(flag=False, fields=disclose_email_field, types=None), + "email": "dotgov@cisa.dhs.gov", + "extensions": [], + "fax": None, + "id": "ThrECENCHI76PGLh", + "ident": None, + "notify_email": None, + "postal_info": common.PostalInfo( + name="Registry Customer Service", + addr=common.ContactAddr( + street=["4200 Wilson Blvd.", None, None], + city="Arlington", + pc="22201", + cc="US", + sp="VA", + ), + org="Cybersecurity and Infrastructure Security Agency", + type="loc", ), - org="Cybersecurity and Infrastructure Security Agency", - type="loc", - ), - "vat": None, - "voice": "+1.8882820870", - } - - # Set the ids equal, since this value changes - test_disclose["id"] = expected_disclose["id"] - test_not_disclose["id"] = expected_not_disclose["id"] - - self.assertEqual(test_disclose, expected_disclose) - self.assertEqual(test_not_disclose, expected_not_disclose) + "vat": None, + "voice": "+1.8882820870", + } + # Set the ids equal, since this value changes + test_disclose["id"] = expected_disclose["id"] + test_not_disclose["id"] = expected_not_disclose["id"] + self.assertEqual(test_disclose, expected_disclose) + self.assertEqual(test_not_disclose, expected_not_disclose) def test_not_disclosed_on_default_security_contact(self): """ @@ -913,17 +884,16 @@ class TestRegistrantContacts(MockEppLib): Then Domain sends `commands.CreateContact` to the registry And the field `disclose` is set to false for DF.EMAIL """ - domain, _ = Domain.objects.get_or_create(name="defaultsecurity.gov") - expectedSecContact = PublicContact.get_default_security() - expectedSecContact.domain = domain - expectedSecContact.registry_id = "defaultSec" - domain.security_contact = expectedSecContact - - expectedCreateCommand = self._convertPublicContactToEpp(expectedSecContact, disclose_email=False) - - self.mockedSendFunction.assert_any_call(expectedCreateCommand, cleaned=True) - # Confirm that we are getting a default email - self.assertEqual(domain.security_contact.email, expectedSecContact.email) + with less_console_noise(): + domain, _ = Domain.objects.get_or_create(name="defaultsecurity.gov") + expectedSecContact = PublicContact.get_default_security() + expectedSecContact.domain = domain + expectedSecContact.registry_id = "defaultSec" + domain.security_contact = expectedSecContact + expectedCreateCommand = self._convertPublicContactToEpp(expectedSecContact, disclose_email=False) + self.mockedSendFunction.assert_any_call(expectedCreateCommand, cleaned=True) + # Confirm that we are getting a default email + self.assertEqual(domain.security_contact.email, expectedSecContact.email) def test_not_disclosed_on_default_technical_contact(self): """ @@ -932,17 +902,16 @@ class TestRegistrantContacts(MockEppLib): Then Domain sends `commands.CreateContact` to the registry And the field `disclose` is set to false for DF.EMAIL """ - domain, _ = Domain.objects.get_or_create(name="defaulttechnical.gov") - expectedTechContact = PublicContact.get_default_technical() - expectedTechContact.domain = domain - expectedTechContact.registry_id = "defaultTech" - domain.technical_contact = expectedTechContact - - expectedCreateCommand = self._convertPublicContactToEpp(expectedTechContact, disclose_email=False) - - self.mockedSendFunction.assert_any_call(expectedCreateCommand, cleaned=True) - # Confirm that we are getting a default email - self.assertEqual(domain.technical_contact.email, expectedTechContact.email) + with less_console_noise(): + domain, _ = Domain.objects.get_or_create(name="defaulttechnical.gov") + expectedTechContact = PublicContact.get_default_technical() + expectedTechContact.domain = domain + expectedTechContact.registry_id = "defaultTech" + domain.technical_contact = expectedTechContact + expectedCreateCommand = self._convertPublicContactToEpp(expectedTechContact, disclose_email=False) + self.mockedSendFunction.assert_any_call(expectedCreateCommand, cleaned=True) + # Confirm that we are getting a default email + self.assertEqual(domain.technical_contact.email, expectedTechContact.email) def test_is_disclosed_on_security_contact(self): """ @@ -952,17 +921,16 @@ class TestRegistrantContacts(MockEppLib): Then Domain sends `commands.CreateContact` to the registry And the field `disclose` is set to true for DF.EMAIL """ - domain, _ = Domain.objects.get_or_create(name="igorville.gov") - expectedSecContact = PublicContact.get_default_security() - expectedSecContact.domain = domain - expectedSecContact.email = "123@mail.gov" - domain.security_contact = expectedSecContact - - expectedCreateCommand = self._convertPublicContactToEpp(expectedSecContact, disclose_email=True) - - self.mockedSendFunction.assert_any_call(expectedCreateCommand, cleaned=True) - # Confirm that we are getting the desired email - self.assertEqual(domain.security_contact.email, expectedSecContact.email) + with less_console_noise(): + domain, _ = Domain.objects.get_or_create(name="igorville.gov") + expectedSecContact = PublicContact.get_default_security() + expectedSecContact.domain = domain + expectedSecContact.email = "123@mail.gov" + domain.security_contact = expectedSecContact + expectedCreateCommand = self._convertPublicContactToEpp(expectedSecContact, disclose_email=True) + self.mockedSendFunction.assert_any_call(expectedCreateCommand, cleaned=True) + # Confirm that we are getting the desired email + self.assertEqual(domain.security_contact.email, expectedSecContact.email) @skip("not implemented yet") def test_update_is_unsuccessful(self): @@ -974,121 +942,112 @@ class TestRegistrantContacts(MockEppLib): raise def test_contact_getter_security(self): - security = PublicContact.ContactTypeChoices.SECURITY - # Create prexisting object - expected_contact = self.domain.map_epp_contact_to_public_contact( - self.mockSecurityContact, - contact_id="securityContact", - contact_type=security, - ) - - # Checks if we grabbed the correct PublicContact - self.assertEqual(self.domain_contact.security_contact.email, expected_contact.email) - - expected_contact_db = PublicContact.objects.filter( - registry_id=self.domain_contact.security_contact.registry_id, - contact_type=security, - ).get() - - self.assertEqual(self.domain_contact.security_contact, expected_contact_db) - - self.mockedSendFunction.assert_has_calls( - [ - call( - commands.InfoContact(id="securityContact", auth_info=None), - cleaned=True, - ), - ] - ) - # Checks if we are receiving the cache we expect - cache = self.domain_contact._cache["contacts"] - self.assertEqual(cache.get(security), "securityContact") + with less_console_noise(): + security = PublicContact.ContactTypeChoices.SECURITY + # Create prexisting object + expected_contact = self.domain.map_epp_contact_to_public_contact( + self.mockSecurityContact, + contact_id="securityContact", + contact_type=security, + ) + # Checks if we grabbed the correct PublicContact + self.assertEqual(self.domain_contact.security_contact.email, expected_contact.email) + expected_contact_db = PublicContact.objects.filter( + registry_id=self.domain_contact.security_contact.registry_id, + contact_type=security, + ).get() + self.assertEqual(self.domain_contact.security_contact, expected_contact_db) + self.mockedSendFunction.assert_has_calls( + [ + call( + commands.InfoContact(id="securityContact", auth_info=None), + cleaned=True, + ), + ] + ) + # Checks if we are receiving the cache we expect + cache = self.domain_contact._cache["contacts"] + self.assertEqual(cache.get(security), "securityContact") def test_contact_getter_technical(self): - technical = PublicContact.ContactTypeChoices.TECHNICAL - expected_contact = self.domain.map_epp_contact_to_public_contact( - self.mockTechnicalContact, - contact_id="technicalContact", - contact_type=technical, - ) - - self.assertEqual(self.domain_contact.technical_contact.email, expected_contact.email) - - # Checks if we grab the correct PublicContact - expected_contact_db = PublicContact.objects.filter( - registry_id=self.domain_contact.technical_contact.registry_id, - contact_type=technical, - ).get() - - # Checks if we grab the correct PublicContact - self.assertEqual(self.domain_contact.technical_contact, expected_contact_db) - self.mockedSendFunction.assert_has_calls( - [ - call( - commands.InfoContact(id="technicalContact", auth_info=None), - cleaned=True, - ), - ] - ) - # Checks if we are receiving the cache we expect - cache = self.domain_contact._cache["contacts"] - self.assertEqual(cache.get(technical), "technicalContact") + with less_console_noise(): + technical = PublicContact.ContactTypeChoices.TECHNICAL + expected_contact = self.domain.map_epp_contact_to_public_contact( + self.mockTechnicalContact, + contact_id="technicalContact", + contact_type=technical, + ) + self.assertEqual(self.domain_contact.technical_contact.email, expected_contact.email) + # Checks if we grab the correct PublicContact + expected_contact_db = PublicContact.objects.filter( + registry_id=self.domain_contact.technical_contact.registry_id, + contact_type=technical, + ).get() + # Checks if we grab the correct PublicContact + self.assertEqual(self.domain_contact.technical_contact, expected_contact_db) + self.mockedSendFunction.assert_has_calls( + [ + call( + commands.InfoContact(id="technicalContact", auth_info=None), + cleaned=True, + ), + ] + ) + # Checks if we are receiving the cache we expect + cache = self.domain_contact._cache["contacts"] + self.assertEqual(cache.get(technical), "technicalContact") def test_contact_getter_administrative(self): - administrative = PublicContact.ContactTypeChoices.ADMINISTRATIVE - expected_contact = self.domain.map_epp_contact_to_public_contact( - self.mockAdministrativeContact, - contact_id="adminContact", - contact_type=administrative, - ) - - self.assertEqual(self.domain_contact.administrative_contact.email, expected_contact.email) - - expected_contact_db = PublicContact.objects.filter( - registry_id=self.domain_contact.administrative_contact.registry_id, - contact_type=administrative, - ).get() - - # Checks if we grab the correct PublicContact - self.assertEqual(self.domain_contact.administrative_contact, expected_contact_db) - self.mockedSendFunction.assert_has_calls( - [ - call( - commands.InfoContact(id="adminContact", auth_info=None), - cleaned=True, - ), - ] - ) - # Checks if we are receiving the cache we expect - cache = self.domain_contact._cache["contacts"] - self.assertEqual(cache.get(administrative), "adminContact") + with less_console_noise(): + administrative = PublicContact.ContactTypeChoices.ADMINISTRATIVE + expected_contact = self.domain.map_epp_contact_to_public_contact( + self.mockAdministrativeContact, + contact_id="adminContact", + contact_type=administrative, + ) + self.assertEqual(self.domain_contact.administrative_contact.email, expected_contact.email) + expected_contact_db = PublicContact.objects.filter( + registry_id=self.domain_contact.administrative_contact.registry_id, + contact_type=administrative, + ).get() + # Checks if we grab the correct PublicContact + self.assertEqual(self.domain_contact.administrative_contact, expected_contact_db) + self.mockedSendFunction.assert_has_calls( + [ + call( + commands.InfoContact(id="adminContact", auth_info=None), + cleaned=True, + ), + ] + ) + # Checks if we are receiving the cache we expect + cache = self.domain_contact._cache["contacts"] + self.assertEqual(cache.get(administrative), "adminContact") def test_contact_getter_registrant(self): - expected_contact = self.domain.map_epp_contact_to_public_contact( - self.mockRegistrantContact, - contact_id="regContact", - contact_type=PublicContact.ContactTypeChoices.REGISTRANT, - ) - - self.assertEqual(self.domain_contact.registrant_contact.email, expected_contact.email) - - expected_contact_db = PublicContact.objects.filter( - registry_id=self.domain_contact.registrant_contact.registry_id, - contact_type=PublicContact.ContactTypeChoices.REGISTRANT, - ).get() - - # Checks if we grab the correct PublicContact - self.assertEqual(self.domain_contact.registrant_contact, expected_contact_db) - self.mockedSendFunction.assert_has_calls( - [ - call( - commands.InfoContact(id="regContact", auth_info=None), - cleaned=True, - ), - ] - ) - # Checks if we are receiving the cache we expect. - self.assertEqual(self.domain_contact._cache["registrant"], expected_contact_db) + with less_console_noise(): + expected_contact = self.domain.map_epp_contact_to_public_contact( + self.mockRegistrantContact, + contact_id="regContact", + contact_type=PublicContact.ContactTypeChoices.REGISTRANT, + ) + self.assertEqual(self.domain_contact.registrant_contact.email, expected_contact.email) + expected_contact_db = PublicContact.objects.filter( + registry_id=self.domain_contact.registrant_contact.registry_id, + contact_type=PublicContact.ContactTypeChoices.REGISTRANT, + ).get() + # Checks if we grab the correct PublicContact + self.assertEqual(self.domain_contact.registrant_contact, expected_contact_db) + self.mockedSendFunction.assert_has_calls( + [ + call( + commands.InfoContact(id="regContact", auth_info=None), + cleaned=True, + ), + ] + ) + # Checks if we are receiving the cache we expect. + self.assertEqual(self.domain_contact._cache["registrant"], expected_contact_db) class TestRegistrantNameservers(MockEppLib): @@ -1112,76 +1071,78 @@ class TestRegistrantNameservers(MockEppLib): def test_get_nameserver_changes_success_deleted_vals(self): """Testing only deleting and no other changes""" - self.domain._cache["hosts"] = [ - {"name": "ns1.example.com", "addrs": None}, - {"name": "ns2.example.com", "addrs": ["1.2.3.4"]}, - ] - newChanges = [ - ("ns1.example.com",), - ] - ( - deleted_values, - updated_values, - new_values, - oldNameservers, - ) = self.domain.getNameserverChanges(newChanges) + with less_console_noise(): + self.domain._cache["hosts"] = [ + {"name": "ns1.example.com", "addrs": None}, + {"name": "ns2.example.com", "addrs": ["1.2.3.4"]}, + ] + newChanges = [ + ("ns1.example.com",), + ] + ( + deleted_values, + updated_values, + new_values, + oldNameservers, + ) = self.domain.getNameserverChanges(newChanges) - self.assertEqual(deleted_values, ["ns2.example.com"]) - self.assertEqual(updated_values, []) - self.assertEqual(new_values, {}) - self.assertEqual( - oldNameservers, - {"ns1.example.com": None, "ns2.example.com": ["1.2.3.4"]}, - ) + self.assertEqual(deleted_values, ["ns2.example.com"]) + self.assertEqual(updated_values, []) + self.assertEqual(new_values, {}) + self.assertEqual( + oldNameservers, + {"ns1.example.com": None, "ns2.example.com": ["1.2.3.4"]}, + ) def test_get_nameserver_changes_success_updated_vals(self): """Testing only updating no other changes""" - self.domain._cache["hosts"] = [ - {"name": "ns3.my-nameserver.gov", "addrs": ["1.2.3.4"]}, - ] - newChanges = [ - ("ns3.my-nameserver.gov", ["1.2.4.5"]), - ] - ( - deleted_values, - updated_values, - new_values, - oldNameservers, - ) = self.domain.getNameserverChanges(newChanges) - - self.assertEqual(deleted_values, []) - self.assertEqual(updated_values, [("ns3.my-nameserver.gov", ["1.2.4.5"])]) - self.assertEqual(new_values, {}) - self.assertEqual( - oldNameservers, - {"ns3.my-nameserver.gov": ["1.2.3.4"]}, - ) + with less_console_noise(): + self.domain._cache["hosts"] = [ + {"name": "ns3.my-nameserver.gov", "addrs": ["1.2.3.4"]}, + ] + newChanges = [ + ("ns3.my-nameserver.gov", ["1.2.4.5"]), + ] + ( + deleted_values, + updated_values, + new_values, + oldNameservers, + ) = self.domain.getNameserverChanges(newChanges) + self.assertEqual(deleted_values, []) + self.assertEqual(updated_values, [("ns3.my-nameserver.gov", ["1.2.4.5"])]) + self.assertEqual(new_values, {}) + self.assertEqual( + oldNameservers, + {"ns3.my-nameserver.gov": ["1.2.3.4"]}, + ) def test_get_nameserver_changes_success_new_vals(self): - # Testing only creating no other changes - self.domain._cache["hosts"] = [ - {"name": "ns1.example.com", "addrs": None}, - ] - newChanges = [ - ("ns1.example.com",), - ("ns4.example.com",), - ] - ( - deleted_values, - updated_values, - new_values, - oldNameservers, - ) = self.domain.getNameserverChanges(newChanges) + with less_console_noise(): + # Testing only creating no other changes + self.domain._cache["hosts"] = [ + {"name": "ns1.example.com", "addrs": None}, + ] + newChanges = [ + ("ns1.example.com",), + ("ns4.example.com",), + ] + ( + deleted_values, + updated_values, + new_values, + oldNameservers, + ) = self.domain.getNameserverChanges(newChanges) - self.assertEqual(deleted_values, []) - self.assertEqual(updated_values, []) - self.assertEqual(new_values, {"ns4.example.com": None}) - self.assertEqual( - oldNameservers, - { - "ns1.example.com": None, - }, - ) + self.assertEqual(deleted_values, []) + self.assertEqual(updated_values, []) + self.assertEqual(new_values, {"ns4.example.com": None}) + self.assertEqual( + oldNameservers, + { + "ns1.example.com": None, + }, + ) def test_user_adds_one_nameserver(self): """ @@ -1193,32 +1154,27 @@ class TestRegistrantNameservers(MockEppLib): And `domain.is_active` returns False And domain.first_ready is null """ - - # set 1 nameserver - nameserver = "ns1.my-nameserver.com" - self.domain.nameservers = [(nameserver,)] - - # when we create a host, we should've updated at the same time - created_host = commands.CreateHost(nameserver) - update_domain_with_created = commands.UpdateDomain( - name=self.domain.name, - add=[common.HostObjSet([created_host.name])], - rem=[], - ) - - # checking if commands were sent (commands have to be sent in order) - expectedCalls = [ - call(created_host, cleaned=True), - call(update_domain_with_created, cleaned=True), - ] - - self.mockedSendFunction.assert_has_calls(expectedCalls) - - # check that status is still NOT READY - # as you have less than 2 nameservers - self.assertFalse(self.domain.is_active()) - - self.assertEqual(self.domain.first_ready, None) + with less_console_noise(): + # set 1 nameserver + nameserver = "ns1.my-nameserver.com" + self.domain.nameservers = [(nameserver,)] + # when we create a host, we should've updated at the same time + created_host = commands.CreateHost(nameserver) + update_domain_with_created = commands.UpdateDomain( + name=self.domain.name, + add=[common.HostObjSet([created_host.name])], + rem=[], + ) + # checking if commands were sent (commands have to be sent in order) + expectedCalls = [ + call(created_host, cleaned=True), + call(update_domain_with_created, cleaned=True), + ] + self.mockedSendFunction.assert_has_calls(expectedCalls) + # check that status is still NOT READY + # as you have less than 2 nameservers + self.assertFalse(self.domain.is_active()) + self.assertEqual(self.domain.first_ready, None) def test_user_adds_two_nameservers(self): """ @@ -1230,36 +1186,32 @@ class TestRegistrantNameservers(MockEppLib): And `domain.is_active` returns True And domain.first_ready is not null """ - - # set 2 nameservers - self.domain.nameservers = [(self.nameserver1,), (self.nameserver2,)] - - # when you create a host, you also have to update at same time - created_host1 = commands.CreateHost(self.nameserver1) - created_host2 = commands.CreateHost(self.nameserver2) - - update_domain_with_created = commands.UpdateDomain( - name=self.domain.name, - add=[ - common.HostObjSet([created_host1.name, created_host2.name]), - ], - rem=[], - ) - - infoDomain = commands.InfoDomain(name="my-nameserver.gov", auth_info=None) - # checking if commands were sent (commands have to be sent in order) - expectedCalls = [ - call(infoDomain, cleaned=True), - call(created_host1, cleaned=True), - call(created_host2, cleaned=True), - call(update_domain_with_created, cleaned=True), - ] - - self.mockedSendFunction.assert_has_calls(expectedCalls, any_order=True) - self.assertEqual(4, self.mockedSendFunction.call_count) - # check that status is READY - self.assertTrue(self.domain.is_active()) - self.assertNotEqual(self.domain.first_ready, None) + with less_console_noise(): + # set 2 nameservers + self.domain.nameservers = [(self.nameserver1,), (self.nameserver2,)] + # when you create a host, you also have to update at same time + created_host1 = commands.CreateHost(self.nameserver1) + created_host2 = commands.CreateHost(self.nameserver2) + update_domain_with_created = commands.UpdateDomain( + name=self.domain.name, + add=[ + common.HostObjSet([created_host1.name, created_host2.name]), + ], + rem=[], + ) + infoDomain = commands.InfoDomain(name="my-nameserver.gov", auth_info=None) + # checking if commands were sent (commands have to be sent in order) + expectedCalls = [ + call(infoDomain, cleaned=True), + call(created_host1, cleaned=True), + call(created_host2, cleaned=True), + call(update_domain_with_created, cleaned=True), + ] + self.mockedSendFunction.assert_has_calls(expectedCalls, any_order=True) + self.assertEqual(4, self.mockedSendFunction.call_count) + # check that status is READY + self.assertTrue(self.domain.is_active()) + self.assertNotEqual(self.domain.first_ready, None) def test_user_adds_too_many_nameservers(self): """ @@ -1268,43 +1220,41 @@ class TestRegistrantNameservers(MockEppLib): When `domain.nameservers` is set to an array of length 14 Then Domain raises a user-friendly error """ - - # set 13+ nameservers - nameserver1 = "ns1.cats-are-superior1.com" - nameserver2 = "ns1.cats-are-superior2.com" - nameserver3 = "ns1.cats-are-superior3.com" - nameserver4 = "ns1.cats-are-superior4.com" - nameserver5 = "ns1.cats-are-superior5.com" - nameserver6 = "ns1.cats-are-superior6.com" - nameserver7 = "ns1.cats-are-superior7.com" - nameserver8 = "ns1.cats-are-superior8.com" - nameserver9 = "ns1.cats-are-superior9.com" - nameserver10 = "ns1.cats-are-superior10.com" - nameserver11 = "ns1.cats-are-superior11.com" - nameserver12 = "ns1.cats-are-superior12.com" - nameserver13 = "ns1.cats-are-superior13.com" - nameserver14 = "ns1.cats-are-superior14.com" - - def _get_14_nameservers(): - self.domain.nameservers = [ - (nameserver1,), - (nameserver2,), - (nameserver3,), - (nameserver4,), - (nameserver5,), - (nameserver6,), - (nameserver7,), - (nameserver8,), - (nameserver9), - (nameserver10,), - (nameserver11,), - (nameserver12,), - (nameserver13,), - (nameserver14,), - ] - - self.assertRaises(NameserverError, _get_14_nameservers) - self.assertEqual(self.mockedSendFunction.call_count, 0) + with less_console_noise(): + # set 13+ nameservers + nameserver1 = "ns1.cats-are-superior1.com" + nameserver2 = "ns1.cats-are-superior2.com" + nameserver3 = "ns1.cats-are-superior3.com" + nameserver4 = "ns1.cats-are-superior4.com" + nameserver5 = "ns1.cats-are-superior5.com" + nameserver6 = "ns1.cats-are-superior6.com" + nameserver7 = "ns1.cats-are-superior7.com" + nameserver8 = "ns1.cats-are-superior8.com" + nameserver9 = "ns1.cats-are-superior9.com" + nameserver10 = "ns1.cats-are-superior10.com" + nameserver11 = "ns1.cats-are-superior11.com" + nameserver12 = "ns1.cats-are-superior12.com" + nameserver13 = "ns1.cats-are-superior13.com" + nameserver14 = "ns1.cats-are-superior14.com" + def _get_14_nameservers(): + self.domain.nameservers = [ + (nameserver1,), + (nameserver2,), + (nameserver3,), + (nameserver4,), + (nameserver5,), + (nameserver6,), + (nameserver7,), + (nameserver8,), + (nameserver9), + (nameserver10,), + (nameserver11,), + (nameserver12,), + (nameserver13,), + (nameserver14,), + ] + self.assertRaises(NameserverError, _get_14_nameservers) + self.assertEqual(self.mockedSendFunction.call_count, 0) def test_user_removes_some_nameservers(self): """ @@ -1315,37 +1265,36 @@ class TestRegistrantNameservers(MockEppLib): to the registry And `domain.is_active` returns True """ - - # Mock is set to return 3 nameservers on infodomain - self.domainWithThreeNS.nameservers = [(self.nameserver1,), (self.nameserver2,)] - expectedCalls = [ - # calls info domain, and info on all hosts - # to get past values - # then removes the single host and updates domain - call( - commands.InfoDomain(name=self.domainWithThreeNS.name, auth_info=None), - cleaned=True, - ), - call(commands.InfoHost(name="ns1.my-nameserver-1.com"), cleaned=True), - call(commands.InfoHost(name="ns1.my-nameserver-2.com"), cleaned=True), - call(commands.InfoHost(name="ns1.cats-are-superior3.com"), cleaned=True), - call( - commands.UpdateDomain( - name=self.domainWithThreeNS.name, - add=[], - rem=[common.HostObjSet(hosts=["ns1.cats-are-superior3.com"])], - nsset=None, - keyset=None, - registrant=None, - auth_info=None, + with less_console_noise(): + # Mock is set to return 3 nameservers on infodomain + self.domainWithThreeNS.nameservers = [(self.nameserver1,), (self.nameserver2,)] + expectedCalls = [ + # calls info domain, and info on all hosts + # to get past values + # then removes the single host and updates domain + call( + commands.InfoDomain(name=self.domainWithThreeNS.name, auth_info=None), + cleaned=True, ), - cleaned=True, - ), - call(commands.DeleteHost(name="ns1.cats-are-superior3.com"), cleaned=True), - ] - - self.mockedSendFunction.assert_has_calls(expectedCalls, any_order=True) - self.assertTrue(self.domainWithThreeNS.is_active()) + call(commands.InfoHost(name="ns1.my-nameserver-1.com"), cleaned=True), + call(commands.InfoHost(name="ns1.my-nameserver-2.com"), cleaned=True), + call(commands.InfoHost(name="ns1.cats-are-superior3.com"), cleaned=True), + call( + commands.UpdateDomain( + name=self.domainWithThreeNS.name, + add=[], + rem=[common.HostObjSet(hosts=["ns1.cats-are-superior3.com"])], + nsset=None, + keyset=None, + registrant=None, + auth_info=None, + ), + cleaned=True, + ), + call(commands.DeleteHost(name="ns1.cats-are-superior3.com"), cleaned=True), + ] + self.mockedSendFunction.assert_has_calls(expectedCalls, any_order=True) + self.assertTrue(self.domainWithThreeNS.is_active()) def test_user_removes_too_many_nameservers(self): """ @@ -1357,41 +1306,40 @@ class TestRegistrantNameservers(MockEppLib): And `domain.is_active` returns False """ - - self.domainWithThreeNS.nameservers = [(self.nameserver1,)] - expectedCalls = [ - call( - commands.InfoDomain(name=self.domainWithThreeNS.name, auth_info=None), - cleaned=True, - ), - call(commands.InfoHost(name="ns1.my-nameserver-1.com"), cleaned=True), - call(commands.InfoHost(name="ns1.my-nameserver-2.com"), cleaned=True), - call(commands.InfoHost(name="ns1.cats-are-superior3.com"), cleaned=True), - call(commands.DeleteHost(name="ns1.my-nameserver-2.com"), cleaned=True), - call( - commands.UpdateDomain( - name=self.domainWithThreeNS.name, - add=[], - rem=[ - common.HostObjSet( - hosts=[ - "ns1.my-nameserver-2.com", - "ns1.cats-are-superior3.com", - ] - ), - ], - nsset=None, - keyset=None, - registrant=None, - auth_info=None, + with less_console_noise(): + self.domainWithThreeNS.nameservers = [(self.nameserver1,)] + expectedCalls = [ + call( + commands.InfoDomain(name=self.domainWithThreeNS.name, auth_info=None), + cleaned=True, ), - cleaned=True, - ), - call(commands.DeleteHost(name="ns1.cats-are-superior3.com"), cleaned=True), - ] - - self.mockedSendFunction.assert_has_calls(expectedCalls, any_order=True) - self.assertFalse(self.domainWithThreeNS.is_active()) + call(commands.InfoHost(name="ns1.my-nameserver-1.com"), cleaned=True), + call(commands.InfoHost(name="ns1.my-nameserver-2.com"), cleaned=True), + call(commands.InfoHost(name="ns1.cats-are-superior3.com"), cleaned=True), + call(commands.DeleteHost(name="ns1.my-nameserver-2.com"), cleaned=True), + call( + commands.UpdateDomain( + name=self.domainWithThreeNS.name, + add=[], + rem=[ + common.HostObjSet( + hosts=[ + "ns1.my-nameserver-2.com", + "ns1.cats-are-superior3.com", + ] + ), + ], + nsset=None, + keyset=None, + registrant=None, + auth_info=None, + ), + cleaned=True, + ), + call(commands.DeleteHost(name="ns1.cats-are-superior3.com"), cleaned=True), + ] + self.mockedSendFunction.assert_has_calls(expectedCalls, any_order=True) + self.assertFalse(self.domainWithThreeNS.is_active()) def test_user_replaces_nameservers(self): """ @@ -1403,59 +1351,58 @@ class TestRegistrantNameservers(MockEppLib): And `commands.UpdateDomain` is sent to add #4 and #5 plus remove #2 and #3 And `commands.DeleteHost` is sent to delete #2 and #3 """ - self.domainWithThreeNS.nameservers = [ - (self.nameserver1,), - ("ns1.cats-are-superior1.com",), - ("ns1.cats-are-superior2.com",), - ] - - expectedCalls = [ - call( - commands.InfoDomain(name=self.domainWithThreeNS.name, auth_info=None), - cleaned=True, - ), - call(commands.InfoHost(name="ns1.my-nameserver-1.com"), cleaned=True), - call(commands.InfoHost(name="ns1.my-nameserver-2.com"), cleaned=True), - call(commands.InfoHost(name="ns1.cats-are-superior3.com"), cleaned=True), - call(commands.DeleteHost(name="ns1.my-nameserver-2.com"), cleaned=True), - call( - commands.CreateHost(name="ns1.cats-are-superior1.com", addrs=[]), - cleaned=True, - ), - call( - commands.CreateHost(name="ns1.cats-are-superior2.com", addrs=[]), - cleaned=True, - ), - call( - commands.UpdateDomain( - name=self.domainWithThreeNS.name, - add=[ - common.HostObjSet( - hosts=[ - "ns1.cats-are-superior1.com", - "ns1.cats-are-superior2.com", - ] - ), - ], - rem=[ - common.HostObjSet( - hosts=[ - "ns1.my-nameserver-2.com", - "ns1.cats-are-superior3.com", - ] - ), - ], - nsset=None, - keyset=None, - registrant=None, - auth_info=None, + with less_console_noise(): + self.domainWithThreeNS.nameservers = [ + (self.nameserver1,), + ("ns1.cats-are-superior1.com",), + ("ns1.cats-are-superior2.com",), + ] + expectedCalls = [ + call( + commands.InfoDomain(name=self.domainWithThreeNS.name, auth_info=None), + cleaned=True, ), - cleaned=True, - ), - ] - - self.mockedSendFunction.assert_has_calls(expectedCalls, any_order=True) - self.assertTrue(self.domainWithThreeNS.is_active()) + call(commands.InfoHost(name="ns1.my-nameserver-1.com"), cleaned=True), + call(commands.InfoHost(name="ns1.my-nameserver-2.com"), cleaned=True), + call(commands.InfoHost(name="ns1.cats-are-superior3.com"), cleaned=True), + call(commands.DeleteHost(name="ns1.my-nameserver-2.com"), cleaned=True), + call( + commands.CreateHost(name="ns1.cats-are-superior1.com", addrs=[]), + cleaned=True, + ), + call( + commands.CreateHost(name="ns1.cats-are-superior2.com", addrs=[]), + cleaned=True, + ), + call( + commands.UpdateDomain( + name=self.domainWithThreeNS.name, + add=[ + common.HostObjSet( + hosts=[ + "ns1.cats-are-superior1.com", + "ns1.cats-are-superior2.com", + ] + ), + ], + rem=[ + common.HostObjSet( + hosts=[ + "ns1.my-nameserver-2.com", + "ns1.cats-are-superior3.com", + ] + ), + ], + nsset=None, + keyset=None, + registrant=None, + auth_info=None, + ), + cleaned=True, + ), + ] + self.mockedSendFunction.assert_has_calls(expectedCalls, any_order=True) + self.assertTrue(self.domainWithThreeNS.is_active()) def test_user_cannot_add_subordinate_without_ip(self): """ @@ -1465,11 +1412,10 @@ class TestRegistrantNameservers(MockEppLib): with a subdomain of the domain and no IP addresses Then Domain raises a user-friendly error """ - - dotgovnameserver = "my-nameserver.gov" - - with self.assertRaises(NameserverError): - self.domain.nameservers = [(dotgovnameserver,)] + with less_console_noise(): + dotgovnameserver = "my-nameserver.gov" + with self.assertRaises(NameserverError): + self.domain.nameservers = [(dotgovnameserver,)] def test_user_updates_ips(self): """ @@ -1480,46 +1426,45 @@ class TestRegistrantNameservers(MockEppLib): with a different IP address(es) Then `commands.UpdateHost` is sent to the registry """ - domain, _ = Domain.objects.get_or_create(name="nameserverwithip.gov", state=Domain.State.READY) - domain.nameservers = [ - ("ns1.nameserverwithip.gov", ["2.3.4.5", "1.2.3.4"]), - ( - "ns2.nameserverwithip.gov", - ["1.2.3.4", "2.3.4.5", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"], - ), - ("ns3.nameserverwithip.gov", ["2.3.4.5"]), - ] - - expectedCalls = [ - call( - commands.InfoDomain(name="nameserverwithip.gov", auth_info=None), - cleaned=True, - ), - call(commands.InfoHost(name="ns1.nameserverwithip.gov"), cleaned=True), - call(commands.InfoHost(name="ns2.nameserverwithip.gov"), cleaned=True), - call(commands.InfoHost(name="ns3.nameserverwithip.gov"), cleaned=True), - call( - commands.UpdateHost( - name="ns2.nameserverwithip.gov", - add=[common.Ip(addr="2001:0db8:85a3:0000:0000:8a2e:0370:7334", ip="v6")], - rem=[], - chg=None, + with less_console_noise(): + domain, _ = Domain.objects.get_or_create(name="nameserverwithip.gov", state=Domain.State.READY) + domain.nameservers = [ + ("ns1.nameserverwithip.gov", ["2.3.4.5", "1.2.3.4"]), + ( + "ns2.nameserverwithip.gov", + ["1.2.3.4", "2.3.4.5", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"], ), - cleaned=True, - ), - call( - commands.UpdateHost( - name="ns3.nameserverwithip.gov", - add=[], - rem=[common.Ip(addr="1.2.3.4", ip=None)], - chg=None, + ("ns3.nameserverwithip.gov", ["2.3.4.5"]), + ] + expectedCalls = [ + call( + commands.InfoDomain(name="nameserverwithip.gov", auth_info=None), + cleaned=True, ), - cleaned=True, - ), - ] - - self.mockedSendFunction.assert_has_calls(expectedCalls, any_order=True) - self.assertTrue(domain.is_active()) + call(commands.InfoHost(name="ns1.nameserverwithip.gov"), cleaned=True), + call(commands.InfoHost(name="ns2.nameserverwithip.gov"), cleaned=True), + call(commands.InfoHost(name="ns3.nameserverwithip.gov"), cleaned=True), + call( + commands.UpdateHost( + name="ns2.nameserverwithip.gov", + add=[common.Ip(addr="2001:0db8:85a3:0000:0000:8a2e:0370:7334", ip="v6")], + rem=[], + chg=None, + ), + cleaned=True, + ), + call( + commands.UpdateHost( + name="ns3.nameserverwithip.gov", + add=[], + rem=[common.Ip(addr="1.2.3.4", ip=None)], + chg=None, + ), + cleaned=True, + ), + ] + self.mockedSendFunction.assert_has_calls(expectedCalls, any_order=True) + self.assertTrue(domain.is_active()) def test_user_cannot_add_non_subordinate_with_ip(self): """ @@ -1529,10 +1474,10 @@ class TestRegistrantNameservers(MockEppLib): which is not a subdomain of the domain and has IP addresses Then Domain raises a user-friendly error """ - dotgovnameserver = "mynameserverdotgov.gov" - - with self.assertRaises(NameserverError): - self.domain.nameservers = [(dotgovnameserver, ["1.2.3"])] + with less_console_noise(): + dotgovnameserver = "mynameserverdotgov.gov" + with self.assertRaises(NameserverError): + self.domain.nameservers = [(dotgovnameserver, ["1.2.3"])] def test_nameservers_are_idempotent(self): """ @@ -1541,60 +1486,60 @@ class TestRegistrantNameservers(MockEppLib): to the registry twice with identical data Then no errors are raised in Domain """ - - # Checking that it doesn't create or update even if out of order - self.domainWithThreeNS.nameservers = [ - (self.nameserver3,), - (self.nameserver1,), - (self.nameserver2,), - ] - - expectedCalls = [ - call( - commands.InfoDomain(name=self.domainWithThreeNS.name, auth_info=None), - cleaned=True, - ), - call(commands.InfoHost(name="ns1.my-nameserver-1.com"), cleaned=True), - call(commands.InfoHost(name="ns1.my-nameserver-2.com"), cleaned=True), - call(commands.InfoHost(name="ns1.cats-are-superior3.com"), cleaned=True), - ] - - self.mockedSendFunction.assert_has_calls(expectedCalls, any_order=True) - self.assertEqual(self.mockedSendFunction.call_count, 4) + with less_console_noise(): + # Checking that it doesn't create or update even if out of order + self.domainWithThreeNS.nameservers = [ + (self.nameserver3,), + (self.nameserver1,), + (self.nameserver2,), + ] + expectedCalls = [ + call( + commands.InfoDomain(name=self.domainWithThreeNS.name, auth_info=None), + cleaned=True, + ), + call(commands.InfoHost(name="ns1.my-nameserver-1.com"), cleaned=True), + call(commands.InfoHost(name="ns1.my-nameserver-2.com"), cleaned=True), + call(commands.InfoHost(name="ns1.cats-are-superior3.com"), cleaned=True), + ] + self.mockedSendFunction.assert_has_calls(expectedCalls, any_order=True) + self.assertEqual(self.mockedSendFunction.call_count, 4) def test_is_subdomain_with_no_ip(self): - domain, _ = Domain.objects.get_or_create(name="nameserversubdomain.gov", state=Domain.State.READY) - - with self.assertRaises(NameserverError): - domain.nameservers = [ - ("ns1.nameserversubdomain.gov",), - ("ns2.nameserversubdomain.gov",), - ] + with less_console_noise(): + domain, _ = Domain.objects.get_or_create(name="nameserversubdomain.gov", state=Domain.State.READY) + with self.assertRaises(NameserverError): + domain.nameservers = [ + ("ns1.nameserversubdomain.gov",), + ("ns2.nameserversubdomain.gov",), + ] def test_not_subdomain_but_has_ip(self): - domain, _ = Domain.objects.get_or_create(name="nameserversubdomain.gov", state=Domain.State.READY) - - with self.assertRaises(NameserverError): - domain.nameservers = [ - ("ns1.cats-da-best.gov", ["1.2.3.4"]), - ("ns2.cats-da-best.gov", ["2.3.4.5"]), - ] + with less_console_noise(): + domain, _ = Domain.objects.get_or_create(name="nameserversubdomain.gov", state=Domain.State.READY) + with self.assertRaises(NameserverError): + domain.nameservers = [ + ("ns1.cats-da-best.gov", ["1.2.3.4"]), + ("ns2.cats-da-best.gov", ["2.3.4.5"]), + ] def test_is_subdomain_but_ip_addr_not_valid(self): - domain, _ = Domain.objects.get_or_create(name="nameserversubdomain.gov", state=Domain.State.READY) + with less_console_noise(): + domain, _ = Domain.objects.get_or_create(name="nameserversubdomain.gov", state=Domain.State.READY) - with self.assertRaises(NameserverError): - domain.nameservers = [ - ("ns1.nameserversubdomain.gov", ["1.2.3"]), - ("ns2.nameserversubdomain.gov", ["2.3.4"]), - ] + with self.assertRaises(NameserverError): + domain.nameservers = [ + ("ns1.nameserversubdomain.gov", ["1.2.3"]), + ("ns2.nameserversubdomain.gov", ["2.3.4"]), + ] def test_setting_not_allowed(self): """Scenario: A domain state is not Ready or DNS needed then setting nameservers is not allowed""" - domain, _ = Domain.objects.get_or_create(name="onholdDomain.gov", state=Domain.State.ON_HOLD) - with self.assertRaises(ActionNotAllowed): - domain.nameservers = [self.nameserver1, self.nameserver2] + with less_console_noise(): + domain, _ = Domain.objects.get_or_create(name="onholdDomain.gov", state=Domain.State.ON_HOLD) + with self.assertRaises(ActionNotAllowed): + domain.nameservers = [self.nameserver1, self.nameserver2] def test_nameserver_returns_on_registry_error(self): """ @@ -1602,28 +1547,23 @@ class TestRegistrantNameservers(MockEppLib): Registry is unavailable and throws exception when attempting to build cache from registry. Nameservers retrieved from database. """ - domain, _ = Domain.objects.get_or_create(name="fake.gov", state=Domain.State.READY) - # set the host and host_ips directly in the database; this is normally handled through - # fetch_cache - host, _ = Host.objects.get_or_create(domain=domain, name="ns1.fake.gov") - host_ip, _ = HostIP.objects.get_or_create(host=host, address="1.1.1.1") - - # mock that registry throws an error on the InfoHost send - - def side_effect(_request, cleaned): - raise RegistryError(code=ErrorCode.COMMAND_FAILED) - - patcher = patch("registrar.models.domain.registry.send") - mocked_send = patcher.start() - mocked_send.side_effect = side_effect - - nameservers = domain.nameservers - - self.assertEqual(len(nameservers), 1) - self.assertEqual(nameservers[0][0], "ns1.fake.gov") - self.assertEqual(nameservers[0][1], ["1.1.1.1"]) - - patcher.stop() + with less_console_noise(): + domain, _ = Domain.objects.get_or_create(name="fake.gov", state=Domain.State.READY) + # set the host and host_ips directly in the database; this is normally handled through + # fetch_cache + host, _ = Host.objects.get_or_create(domain=domain, name="ns1.fake.gov") + host_ip, _ = HostIP.objects.get_or_create(host=host, address="1.1.1.1") + # mock that registry throws an error on the InfoHost send + def side_effect(_request, cleaned): + raise RegistryError(code=ErrorCode.COMMAND_FAILED) + patcher = patch("registrar.models.domain.registry.send") + mocked_send = patcher.start() + mocked_send.side_effect = side_effect + nameservers = domain.nameservers + self.assertEqual(len(nameservers), 1) + self.assertEqual(nameservers[0][0], "ns1.fake.gov") + self.assertEqual(nameservers[0][1], ["1.1.1.1"]) + patcher.stop() def test_nameservers_stored_on_fetch_cache(self): """ @@ -1633,24 +1573,23 @@ class TestRegistrantNameservers(MockEppLib): of 'fake.host.com' from InfoDomain and an array of 2 IPs: 1.2.3.4 and 2.3.4.5 from InfoHost """ - domain, _ = Domain.objects.get_or_create(name="fake.gov", state=Domain.State.READY) - - # mock the get_or_create methods for Host and HostIP - with patch.object(Host.objects, "get_or_create") as mock_host_get_or_create, patch.object( - HostIP.objects, "get_or_create" - ) as mock_host_ip_get_or_create: - # Set the return value for the mocks - mock_host_get_or_create.return_value = (Host(), True) - mock_host_ip_get_or_create.return_value = (HostIP(), True) - - # force fetch_cache to be called, which will return above documented mocked hosts - domain.nameservers - # assert that the mocks are called - mock_host_get_or_create.assert_called_once_with(domain=domain, name="fake.host.com") - # Retrieve the mocked_host from the return value of the mock - actual_mocked_host, _ = mock_host_get_or_create.return_value - mock_host_ip_get_or_create.assert_called_with(address="2.3.4.5", host=actual_mocked_host) - self.assertEqual(mock_host_ip_get_or_create.call_count, 2) + with less_console_noise(): + domain, _ = Domain.objects.get_or_create(name="fake.gov", state=Domain.State.READY) + # mock the get_or_create methods for Host and HostIP + with patch.object(Host.objects, "get_or_create") as mock_host_get_or_create, patch.object( + HostIP.objects, "get_or_create" + ) as mock_host_ip_get_or_create: + # Set the return value for the mocks + mock_host_get_or_create.return_value = (Host(), True) + mock_host_ip_get_or_create.return_value = (HostIP(), True) + # force fetch_cache to be called, which will return above documented mocked hosts + domain.nameservers + # assert that the mocks are called + mock_host_get_or_create.assert_called_once_with(domain=domain, name="fake.host.com") + # Retrieve the mocked_host from the return value of the mock + actual_mocked_host, _ = mock_host_get_or_create.return_value + mock_host_ip_get_or_create.assert_called_with(address="2.3.4.5", host=actual_mocked_host) + self.assertEqual(mock_host_ip_get_or_create.call_count, 2) @skip("not implemented yet") def test_update_is_unsuccessful(self): @@ -1790,55 +1729,51 @@ class TestRegistrantDNSSEC(MockEppLib): ) else: return MagicMock(res_data=[self.mockDataInfoHosts]) - - patcher = patch("registrar.models.domain.registry.send") - mocked_send = patcher.start() - mocked_send.side_effect = side_effect - - domain, _ = Domain.objects.get_or_create(name="dnssec-dsdata.gov") - domain.dnssecdata = self.dnssecExtensionWithDsData - - # get the DNS SEC extension added to the UpdateDomain command and - # verify that it is properly sent - # args[0] is the _request sent to registry - args, _ = mocked_send.call_args - # assert that the extension on the update matches - self.assertEquals( - args[0].extensions[0], - self.createUpdateExtension(self.dnssecExtensionWithDsData), - ) - # test that the dnssecdata getter is functioning properly - dnssecdata_get = domain.dnssecdata - mocked_send.assert_has_calls( - [ - call( - commands.InfoDomain( - name="dnssec-dsdata.gov", + with less_console_noise(): + patcher = patch("registrar.models.domain.registry.send") + mocked_send = patcher.start() + mocked_send.side_effect = side_effect + domain, _ = Domain.objects.get_or_create(name="dnssec-dsdata.gov") + domain.dnssecdata = self.dnssecExtensionWithDsData + # get the DNS SEC extension added to the UpdateDomain command and + # verify that it is properly sent + # args[0] is the _request sent to registry + args, _ = mocked_send.call_args + # assert that the extension on the update matches + self.assertEquals( + args[0].extensions[0], + self.createUpdateExtension(self.dnssecExtensionWithDsData), + ) + # test that the dnssecdata getter is functioning properly + dnssecdata_get = domain.dnssecdata + mocked_send.assert_has_calls( + [ + call( + commands.InfoDomain( + name="dnssec-dsdata.gov", + ), + cleaned=True, ), - cleaned=True, - ), - call( - commands.UpdateDomain( - name="dnssec-dsdata.gov", - nsset=None, - keyset=None, - registrant=None, - auth_info=None, + call( + commands.UpdateDomain( + name="dnssec-dsdata.gov", + nsset=None, + keyset=None, + registrant=None, + auth_info=None, + ), + cleaned=True, ), - cleaned=True, - ), - call( - commands.InfoDomain( - name="dnssec-dsdata.gov", + call( + commands.InfoDomain( + name="dnssec-dsdata.gov", + ), + cleaned=True, ), - cleaned=True, - ), - ] - ) - - self.assertEquals(dnssecdata_get.dsData, self.dnssecExtensionWithDsData.dsData) - - patcher.stop() + ] + ) + self.assertEquals(dnssecdata_get.dsData, self.dnssecExtensionWithDsData.dsData) + patcher.stop() def test_dnssec_is_idempotent(self): """ @@ -1871,55 +1806,51 @@ class TestRegistrantDNSSEC(MockEppLib): ) else: return MagicMock(res_data=[self.mockDataInfoHosts]) - - patcher = patch("registrar.models.domain.registry.send") - mocked_send = patcher.start() - mocked_send.side_effect = side_effect - - domain, _ = Domain.objects.get_or_create(name="dnssec-dsdata.gov") - - # set the dnssecdata once - domain.dnssecdata = self.dnssecExtensionWithDsData - # set the dnssecdata again - domain.dnssecdata = self.dnssecExtensionWithDsData - # test that the dnssecdata getter is functioning properly - dnssecdata_get = domain.dnssecdata - mocked_send.assert_has_calls( - [ - call( - commands.InfoDomain( - name="dnssec-dsdata.gov", + with less_console_noise(): + patcher = patch("registrar.models.domain.registry.send") + mocked_send = patcher.start() + mocked_send.side_effect = side_effect + domain, _ = Domain.objects.get_or_create(name="dnssec-dsdata.gov") + # set the dnssecdata once + domain.dnssecdata = self.dnssecExtensionWithDsData + # set the dnssecdata again + domain.dnssecdata = self.dnssecExtensionWithDsData + # test that the dnssecdata getter is functioning properly + dnssecdata_get = domain.dnssecdata + mocked_send.assert_has_calls( + [ + call( + commands.InfoDomain( + name="dnssec-dsdata.gov", + ), + cleaned=True, ), - cleaned=True, - ), - call( - commands.UpdateDomain( - name="dnssec-dsdata.gov", - nsset=None, - keyset=None, - registrant=None, - auth_info=None, + call( + commands.UpdateDomain( + name="dnssec-dsdata.gov", + nsset=None, + keyset=None, + registrant=None, + auth_info=None, + ), + cleaned=True, ), - cleaned=True, - ), - call( - commands.InfoDomain( - name="dnssec-dsdata.gov", + call( + commands.InfoDomain( + name="dnssec-dsdata.gov", + ), + cleaned=True, ), - cleaned=True, - ), - call( - commands.InfoDomain( - name="dnssec-dsdata.gov", + call( + commands.InfoDomain( + name="dnssec-dsdata.gov", + ), + cleaned=True, ), - cleaned=True, - ), - ] - ) - - self.assertEquals(dnssecdata_get.dsData, self.dnssecExtensionWithDsData.dsData) - - patcher.stop() + ] + ) + self.assertEquals(dnssecdata_get.dsData, self.dnssecExtensionWithDsData.dsData) + patcher.stop() def test_user_adds_dnssec_data_multiple_dsdata(self): """ @@ -1948,49 +1879,45 @@ class TestRegistrantDNSSEC(MockEppLib): ) else: return MagicMock(res_data=[self.mockDataInfoHosts]) - - patcher = patch("registrar.models.domain.registry.send") - mocked_send = patcher.start() - mocked_send.side_effect = side_effect - - domain, _ = Domain.objects.get_or_create(name="dnssec-multdsdata.gov") - - domain.dnssecdata = self.dnssecExtensionWithMultDsData - # get the DNS SEC extension added to the UpdateDomain command - # and verify that it is properly sent - # args[0] is the _request sent to registry - args, _ = mocked_send.call_args - # assert that the extension matches - self.assertEquals( - args[0].extensions[0], - self.createUpdateExtension(self.dnssecExtensionWithMultDsData), - ) - # test that the dnssecdata getter is functioning properly - dnssecdata_get = domain.dnssecdata - mocked_send.assert_has_calls( - [ - call( - commands.UpdateDomain( - name="dnssec-multdsdata.gov", - nsset=None, - keyset=None, - registrant=None, - auth_info=None, + with less_console_noise(): + patcher = patch("registrar.models.domain.registry.send") + mocked_send = patcher.start() + mocked_send.side_effect = side_effect + domain, _ = Domain.objects.get_or_create(name="dnssec-multdsdata.gov") + domain.dnssecdata = self.dnssecExtensionWithMultDsData + # get the DNS SEC extension added to the UpdateDomain command + # and verify that it is properly sent + # args[0] is the _request sent to registry + args, _ = mocked_send.call_args + # assert that the extension matches + self.assertEquals( + args[0].extensions[0], + self.createUpdateExtension(self.dnssecExtensionWithMultDsData), + ) + # test that the dnssecdata getter is functioning properly + dnssecdata_get = domain.dnssecdata + mocked_send.assert_has_calls( + [ + call( + commands.UpdateDomain( + name="dnssec-multdsdata.gov", + nsset=None, + keyset=None, + registrant=None, + auth_info=None, + ), + cleaned=True, ), - cleaned=True, - ), - call( - commands.InfoDomain( - name="dnssec-multdsdata.gov", + call( + commands.InfoDomain( + name="dnssec-multdsdata.gov", + ), + cleaned=True, ), - cleaned=True, - ), - ] - ) - - self.assertEquals(dnssecdata_get.dsData, self.dnssecExtensionWithMultDsData.dsData) - - patcher.stop() + ] + ) + self.assertEquals(dnssecdata_get.dsData, self.dnssecExtensionWithMultDsData.dsData) + patcher.stop() def test_user_removes_dnssec_data(self): """ @@ -2020,66 +1947,64 @@ class TestRegistrantDNSSEC(MockEppLib): ) else: return MagicMock(res_data=[self.mockDataInfoHosts]) - - patcher = patch("registrar.models.domain.registry.send") - mocked_send = patcher.start() - mocked_send.side_effect = side_effect - - domain, _ = Domain.objects.get_or_create(name="dnssec-dsdata.gov") - # dnssecdata_get_initial = domain.dnssecdata # call to force initial mock - # domain._invalidate_cache() - domain.dnssecdata = self.dnssecExtensionWithDsData - domain.dnssecdata = self.dnssecExtensionRemovingDsData - # get the DNS SEC extension added to the UpdateDomain command and - # verify that it is properly sent - # args[0] is the _request sent to registry - args, _ = mocked_send.call_args - # assert that the extension on the update matches - self.assertEquals( - args[0].extensions[0], - self.createUpdateExtension( - self.dnssecExtensionWithDsData, - remove=True, - ), - ) - mocked_send.assert_has_calls( - [ - call( - commands.InfoDomain( - name="dnssec-dsdata.gov", - ), - cleaned=True, + with less_console_noise(): + patcher = patch("registrar.models.domain.registry.send") + mocked_send = patcher.start() + mocked_send.side_effect = side_effect + domain, _ = Domain.objects.get_or_create(name="dnssec-dsdata.gov") + # dnssecdata_get_initial = domain.dnssecdata # call to force initial mock + # domain._invalidate_cache() + domain.dnssecdata = self.dnssecExtensionWithDsData + domain.dnssecdata = self.dnssecExtensionRemovingDsData + # get the DNS SEC extension added to the UpdateDomain command and + # verify that it is properly sent + # args[0] is the _request sent to registry + args, _ = mocked_send.call_args + # assert that the extension on the update matches + self.assertEquals( + args[0].extensions[0], + self.createUpdateExtension( + self.dnssecExtensionWithDsData, + remove=True, ), - call( - commands.UpdateDomain( - name="dnssec-dsdata.gov", - nsset=None, - keyset=None, - registrant=None, - auth_info=None, + ) + mocked_send.assert_has_calls( + [ + call( + commands.InfoDomain( + name="dnssec-dsdata.gov", + ), + cleaned=True, ), - cleaned=True, - ), - call( - commands.InfoDomain( - name="dnssec-dsdata.gov", + call( + commands.UpdateDomain( + name="dnssec-dsdata.gov", + nsset=None, + keyset=None, + registrant=None, + auth_info=None, + ), + cleaned=True, ), - cleaned=True, - ), - call( - commands.UpdateDomain( - name="dnssec-dsdata.gov", - nsset=None, - keyset=None, - registrant=None, - auth_info=None, + call( + commands.InfoDomain( + name="dnssec-dsdata.gov", + ), + cleaned=True, ), - cleaned=True, - ), - ] - ) - - patcher.stop() + call( + commands.UpdateDomain( + name="dnssec-dsdata.gov", + nsset=None, + keyset=None, + registrant=None, + auth_info=None, + ), + cleaned=True, + ), + ] + ) + patcher.stop() def test_update_is_unsuccessful(self): """ @@ -2087,12 +2012,11 @@ class TestRegistrantDNSSEC(MockEppLib): When an error is returned from epplibwrapper Then a user-friendly error message is returned for displaying on the web """ - - domain, _ = Domain.objects.get_or_create(name="dnssec-invalid.gov") - - with self.assertRaises(RegistryError) as err: - domain.dnssecdata = self.dnssecExtensionWithDsData - self.assertTrue(err.is_client_error() or err.is_session_error() or err.is_server_error()) + with less_console_noise(): + domain, _ = Domain.objects.get_or_create(name="dnssec-invalid.gov") + with self.assertRaises(RegistryError) as err: + domain.dnssecdata = self.dnssecExtensionWithDsData + self.assertTrue(err.is_client_error() or err.is_session_error() or err.is_server_error()) class TestExpirationDate(MockEppLib): @@ -2117,44 +2041,49 @@ class TestExpirationDate(MockEppLib): def test_expiration_date_setter_not_implemented(self): """assert that the setter for expiration date is not implemented and will raise error""" - with self.assertRaises(NotImplementedError): - self.domain.registry_expiration_date = datetime.date.today() + with less_console_noise(): + with self.assertRaises(NotImplementedError): + self.domain.registry_expiration_date = datetime.date.today() def test_renew_domain(self): """assert that the renew_domain sets new expiration date in cache and saves to registrar""" - self.domain.renew_domain() - test_date = datetime.date(2023, 5, 25) - self.assertEquals(self.domain._cache["ex_date"], test_date) - self.assertEquals(self.domain.expiration_date, test_date) + with less_console_noise(): + self.domain.renew_domain() + test_date = datetime.date(2023, 5, 25) + self.assertEquals(self.domain._cache["ex_date"], test_date) + self.assertEquals(self.domain.expiration_date, test_date) def test_renew_domain_error(self): """assert that the renew_domain raises an exception when registry raises error""" - with self.assertRaises(RegistryError): - self.domain_w_error.renew_domain() + with less_console_noise(): + with self.assertRaises(RegistryError): + self.domain_w_error.renew_domain() def test_is_expired(self): """assert that is_expired returns true for expiration_date in past""" - # force fetch_cache to be called - self.domain.statuses - self.assertTrue(self.domain.is_expired) + with less_console_noise(): + # force fetch_cache to be called + self.domain.statuses + self.assertTrue(self.domain.is_expired) def test_is_not_expired(self): """assert that is_expired returns false for expiration in future""" - # to do this, need to mock value returned from timezone.now - # set now to 2023-01-01 - mocked_datetime = datetime.datetime(2023, 1, 1, 12, 0, 0) - # force fetch_cache which sets the expiration date to 2023-05-25 - self.domain.statuses - - with patch("registrar.models.domain.timezone.now", return_value=mocked_datetime): - self.assertFalse(self.domain.is_expired()) + with less_console_noise(): + # to do this, need to mock value returned from timezone.now + # set now to 2023-01-01 + mocked_datetime = datetime.datetime(2023, 1, 1, 12, 0, 0) + # force fetch_cache which sets the expiration date to 2023-05-25 + self.domain.statuses + with patch("registrar.models.domain.timezone.now", return_value=mocked_datetime): + self.assertFalse(self.domain.is_expired()) def test_expiration_date_updated_on_info_domain_call(self): """assert that expiration date in db is updated on info domain call""" - # force fetch_cache to be called - self.domain.statuses - test_date = datetime.date(2023, 5, 25) - self.assertEquals(self.domain.expiration_date, test_date) + with less_console_noise(): + # force fetch_cache to be called + self.domain.statuses + test_date = datetime.date(2023, 5, 25) + self.assertEquals(self.domain.expiration_date, test_date) class TestCreationDate(MockEppLib): @@ -2169,7 +2098,7 @@ class TestCreationDate(MockEppLib): self.domain, _ = Domain.objects.get_or_create(name="fake.gov", state=Domain.State.READY) # creation_date returned from mockDataInfoDomain with creation date: # cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35) - self.creation_date = datetime.datetime(2023, 5, 25, 19, 45, 35) + self.creation_date = make_aware(datetime.datetime(2023, 5, 25, 19, 45, 35)) def tearDown(self): Domain.objects.all().delete() @@ -2212,29 +2141,30 @@ class TestAnalystClientHold(MockEppLib): When `domain.place_client_hold()` is called Then `CLIENT_HOLD` is added to the domain's statuses """ - self.domain.place_client_hold() - self.mockedSendFunction.assert_has_calls( - [ - call( - commands.UpdateDomain( - name="fake.gov", - add=[ - common.Status( - state=Domain.Status.CLIENT_HOLD, - description="", - lang="en", - ) - ], - nsset=None, - keyset=None, - registrant=None, - auth_info=None, - ), - cleaned=True, - ) - ] - ) - self.assertEquals(self.domain.state, Domain.State.ON_HOLD) + with less_console_noise(): + self.domain.place_client_hold() + self.mockedSendFunction.assert_has_calls( + [ + call( + commands.UpdateDomain( + name="fake.gov", + add=[ + common.Status( + state=Domain.Status.CLIENT_HOLD, + description="", + lang="en", + ) + ], + nsset=None, + keyset=None, + registrant=None, + auth_info=None, + ), + cleaned=True, + ) + ] + ) + self.assertEquals(self.domain.state, Domain.State.ON_HOLD) def test_analyst_places_client_hold_idempotent(self): """ @@ -2243,29 +2173,30 @@ class TestAnalystClientHold(MockEppLib): When `domain.place_client_hold()` is called Then Domain returns normally (without error) """ - self.domain_on_hold.place_client_hold() - self.mockedSendFunction.assert_has_calls( - [ - call( - commands.UpdateDomain( - name="fake-on-hold.gov", - add=[ - common.Status( - state=Domain.Status.CLIENT_HOLD, - description="", - lang="en", - ) - ], - nsset=None, - keyset=None, - registrant=None, - auth_info=None, - ), - cleaned=True, - ) - ] - ) - self.assertEquals(self.domain_on_hold.state, Domain.State.ON_HOLD) + with less_console_noise(): + self.domain_on_hold.place_client_hold() + self.mockedSendFunction.assert_has_calls( + [ + call( + commands.UpdateDomain( + name="fake-on-hold.gov", + add=[ + common.Status( + state=Domain.Status.CLIENT_HOLD, + description="", + lang="en", + ) + ], + nsset=None, + keyset=None, + registrant=None, + auth_info=None, + ), + cleaned=True, + ) + ] + ) + self.assertEquals(self.domain_on_hold.state, Domain.State.ON_HOLD) def test_analyst_removes_client_hold(self): """ @@ -2274,29 +2205,30 @@ class TestAnalystClientHold(MockEppLib): When `domain.remove_client_hold()` is called Then `CLIENT_HOLD` is no longer in the domain's statuses """ - self.domain_on_hold.revert_client_hold() - self.mockedSendFunction.assert_has_calls( - [ - call( - commands.UpdateDomain( - name="fake-on-hold.gov", - rem=[ - common.Status( - state=Domain.Status.CLIENT_HOLD, - description="", - lang="en", - ) - ], - nsset=None, - keyset=None, - registrant=None, - auth_info=None, - ), - cleaned=True, - ) - ] - ) - self.assertEquals(self.domain_on_hold.state, Domain.State.READY) + with less_console_noise(): + self.domain_on_hold.revert_client_hold() + self.mockedSendFunction.assert_has_calls( + [ + call( + commands.UpdateDomain( + name="fake-on-hold.gov", + rem=[ + common.Status( + state=Domain.Status.CLIENT_HOLD, + description="", + lang="en", + ) + ], + nsset=None, + keyset=None, + registrant=None, + auth_info=None, + ), + cleaned=True, + ) + ] + ) + self.assertEquals(self.domain_on_hold.state, Domain.State.READY) def test_analyst_removes_client_hold_idempotent(self): """ @@ -2305,29 +2237,30 @@ class TestAnalystClientHold(MockEppLib): When `domain.remove_client_hold()` is called Then Domain returns normally (without error) """ - self.domain.revert_client_hold() - self.mockedSendFunction.assert_has_calls( - [ - call( - commands.UpdateDomain( - name="fake.gov", - rem=[ - common.Status( - state=Domain.Status.CLIENT_HOLD, - description="", - lang="en", - ) - ], - nsset=None, - keyset=None, - registrant=None, - auth_info=None, - ), - cleaned=True, - ) - ] - ) - self.assertEquals(self.domain.state, Domain.State.READY) + with less_console_noise(): + self.domain.revert_client_hold() + self.mockedSendFunction.assert_has_calls( + [ + call( + commands.UpdateDomain( + name="fake.gov", + rem=[ + common.Status( + state=Domain.Status.CLIENT_HOLD, + description="", + lang="en", + ) + ], + nsset=None, + keyset=None, + registrant=None, + auth_info=None, + ), + cleaned=True, + ) + ] + ) + self.assertEquals(self.domain.state, Domain.State.READY) def test_update_is_unsuccessful(self): """ @@ -2338,19 +2271,17 @@ class TestAnalystClientHold(MockEppLib): def side_effect(_request, cleaned): raise RegistryError(code=ErrorCode.OBJECT_STATUS_PROHIBITS_OPERATION) - - patcher = patch("registrar.models.domain.registry.send") - mocked_send = patcher.start() - mocked_send.side_effect = side_effect - - # if RegistryError is raised, admin formats user-friendly - # error message if error is_client_error, is_session_error, or - # is_server_error; so test for those conditions - with self.assertRaises(RegistryError) as err: - self.domain.place_client_hold() - self.assertTrue(err.is_client_error() or err.is_session_error() or err.is_server_error()) - - patcher.stop() + with less_console_noise(): + patcher = patch("registrar.models.domain.registry.send") + mocked_send = patcher.start() + mocked_send.side_effect = side_effect + # if RegistryError is raised, admin formats user-friendly + # error message if error is_client_error, is_session_error, or + # is_server_error; so test for those conditions + with self.assertRaises(RegistryError) as err: + self.domain.place_client_hold() + self.assertTrue(err.is_client_error() or err.is_session_error() or err.is_server_error()) + patcher.stop() class TestAnalystLock(TestCase): @@ -2443,31 +2374,28 @@ class TestAnalystDelete(MockEppLib): The deleted date is set. """ - # Put the domain in client hold - self.domain.place_client_hold() - # Delete it... - self.domain.deletedInEpp() - self.domain.save() - self.mockedSendFunction.assert_has_calls( - [ - call( - commands.DeleteDomain(name="fake.gov"), - cleaned=True, - ) - ] - ) - - # Domain itself should not be deleted - self.assertNotEqual(self.domain, None) - - # Domain should have the right state - self.assertEqual(self.domain.state, Domain.State.DELETED) - - # Domain should have a deleted - self.assertNotEqual(self.domain.deleted, None) - - # Cache should be invalidated - self.assertEqual(self.domain._cache, {}) + with less_console_noise(): + # Put the domain in client hold + self.domain.place_client_hold() + # Delete it... + self.domain.deletedInEpp() + self.domain.save() + self.mockedSendFunction.assert_has_calls( + [ + call( + commands.DeleteDomain(name="fake.gov"), + cleaned=True, + ) + ] + ) + # Domain itself should not be deleted + self.assertNotEqual(self.domain, None) + # Domain should have the right state + self.assertEqual(self.domain.state, Domain.State.DELETED) + # Domain should have a deleted + self.assertNotEqual(self.domain.deleted, None) + # Cache should be invalidated + self.assertEqual(self.domain._cache, {}) def test_deletion_is_unsuccessful(self): """ @@ -2476,29 +2404,28 @@ class TestAnalystDelete(MockEppLib): Then a client error is returned of code 2305 And `state` is not set to `DELETED` """ - # Desired domain - domain, _ = Domain.objects.get_or_create(name="failDelete.gov", state=Domain.State.ON_HOLD) - # Put the domain in client hold - domain.place_client_hold() - - # Delete it - with self.assertRaises(RegistryError) as err: - domain.deletedInEpp() - domain.save() - self.assertTrue(err.is_client_error() and err.code == ErrorCode.OBJECT_ASSOCIATION_PROHIBITS_OPERATION) - self.mockedSendFunction.assert_has_calls( - [ - call( - commands.DeleteDomain(name="failDelete.gov"), - cleaned=True, - ) - ] - ) - - # Domain itself should not be deleted - self.assertNotEqual(domain, None) - # State should not have changed - self.assertEqual(domain.state, Domain.State.ON_HOLD) + with less_console_noise(): + # Desired domain + domain, _ = Domain.objects.get_or_create(name="failDelete.gov", state=Domain.State.ON_HOLD) + # Put the domain in client hold + domain.place_client_hold() + # Delete it + with self.assertRaises(RegistryError) as err: + domain.deletedInEpp() + domain.save() + self.assertTrue(err.is_client_error() and err.code == ErrorCode.OBJECT_ASSOCIATION_PROHIBITS_OPERATION) + self.mockedSendFunction.assert_has_calls( + [ + call( + commands.DeleteDomain(name="failDelete.gov"), + cleaned=True, + ) + ] + ) + # Domain itself should not be deleted + self.assertNotEqual(domain, None) + # State should not have changed + self.assertEqual(domain.state, Domain.State.ON_HOLD) def test_deletion_ready_fsm_failure(self): """ @@ -2511,15 +2438,15 @@ class TestAnalystDelete(MockEppLib): The deleted date is still null. """ - self.assertEqual(self.domain.state, Domain.State.READY) - with self.assertRaises(TransitionNotAllowed) as err: - self.domain.deletedInEpp() - self.domain.save() - self.assertTrue(err.is_client_error() and err.code == ErrorCode.OBJECT_STATUS_PROHIBITS_OPERATION) - # Domain should not be deleted - self.assertNotEqual(self.domain, None) - # Domain should have the right state - self.assertEqual(self.domain.state, Domain.State.READY) - - # deleted should be null - self.assertEqual(self.domain.deleted, None) + with less_console_noise(): + self.assertEqual(self.domain.state, Domain.State.READY) + with self.assertRaises(TransitionNotAllowed) as err: + self.domain.deletedInEpp() + self.domain.save() + self.assertTrue(err.is_client_error() and err.code == ErrorCode.OBJECT_STATUS_PROHIBITS_OPERATION) + # Domain should not be deleted + self.assertNotEqual(self.domain, None) + # Domain should have the right state + self.assertEqual(self.domain.state, Domain.State.READY) + # deleted should be null + self.assertEqual(self.domain.deleted, None) diff --git a/src/registrar/tests/test_reports.py b/src/registrar/tests/test_reports.py index a85fb5849..d74ebaffd 100644 --- a/src/registrar/tests/test_reports.py +++ b/src/registrar/tests/test_reports.py @@ -23,7 +23,7 @@ import boto3_mocking from registrar.utility.s3_bucket import S3ClientError, S3ClientErrorCodes # type: ignore from datetime import date, datetime, timedelta from django.utils import timezone - +from .common import less_console_noise class CsvReportsTest(TestCase): """Tests to determine if we are uploading our reports correctly""" @@ -80,41 +80,43 @@ class CsvReportsTest(TestCase): @boto3_mocking.patching def test_generate_federal_report(self): """Ensures that we correctly generate current-federal.csv""" - mock_client = MagicMock() - fake_open = mock_open() - expected_file_content = [ - call("Domain name,Domain type,Agency,Organization name,City,State,Security contact email\r\n"), - call("cdomain1.gov,Federal - Executive,World War I Centennial Commission,,,, \r\n"), - call("ddomain3.gov,Federal,Armed Forces Retirement Home,,,, \r\n"), - ] - # We don't actually want to write anything for a test case, - # we just want to verify what is being written. - with boto3_mocking.clients.handler_for("s3", mock_client): - with patch("builtins.open", fake_open): - call_command("generate_current_federal_report", checkpath=False) - content = fake_open() + with less_console_noise(): + mock_client = MagicMock() + fake_open = mock_open() + expected_file_content = [ + call("Domain name,Domain type,Agency,Organization name,City,State,Security contact email\r\n"), + call("cdomain1.gov,Federal - Executive,World War I Centennial Commission,,,, \r\n"), + call("ddomain3.gov,Federal,Armed Forces Retirement Home,,,, \r\n"), + ] + # We don't actually want to write anything for a test case, + # we just want to verify what is being written. + with boto3_mocking.clients.handler_for("s3", mock_client): + with patch("builtins.open", fake_open): + call_command("generate_current_federal_report", checkpath=False) + content = fake_open() - content.write.assert_has_calls(expected_file_content) + content.write.assert_has_calls(expected_file_content) @boto3_mocking.patching def test_generate_full_report(self): """Ensures that we correctly generate current-full.csv""" - mock_client = MagicMock() - fake_open = mock_open() - expected_file_content = [ - call("Domain name,Domain type,Agency,Organization name,City,State,Security contact email\r\n"), - call("cdomain1.gov,Federal - Executive,World War I Centennial Commission,,,, \r\n"), - call("ddomain3.gov,Federal,Armed Forces Retirement Home,,,, \r\n"), - call("adomain2.gov,Interstate,,,,, \r\n"), - ] - # We don't actually want to write anything for a test case, - # we just want to verify what is being written. - with boto3_mocking.clients.handler_for("s3", mock_client): - with patch("builtins.open", fake_open): - call_command("generate_current_full_report", checkpath=False) - content = fake_open() + with less_console_noise(): + mock_client = MagicMock() + fake_open = mock_open() + expected_file_content = [ + call("Domain name,Domain type,Agency,Organization name,City,State,Security contact email\r\n"), + call("cdomain1.gov,Federal - Executive,World War I Centennial Commission,,,, \r\n"), + call("ddomain3.gov,Federal,Armed Forces Retirement Home,,,, \r\n"), + call("adomain2.gov,Interstate,,,,, \r\n"), + ] + # We don't actually want to write anything for a test case, + # we just want to verify what is being written. + with boto3_mocking.clients.handler_for("s3", mock_client): + with patch("builtins.open", fake_open): + call_command("generate_current_full_report", checkpath=False) + content = fake_open() - content.write.assert_has_calls(expected_file_content) + content.write.assert_has_calls(expected_file_content) @boto3_mocking.patching def test_not_found_full_report(self): @@ -122,20 +124,20 @@ class CsvReportsTest(TestCase): def side_effect(Bucket, Key): raise ClientError({"Error": {"Code": "NoSuchKey", "Message": "No such key"}}, "get_object") + with less_console_noise(): + mock_client = MagicMock() + mock_client.get_object.side_effect = side_effect - mock_client = MagicMock() - mock_client.get_object.side_effect = side_effect + response = None + with boto3_mocking.clients.handler_for("s3", mock_client): + with patch("boto3.client", return_value=mock_client): + with self.assertRaises(S3ClientError) as context: + response = self.client.get("/api/v1/get-report/current-full") + # Check that the response has status code 500 + self.assertEqual(response.status_code, 500) - response = None - with boto3_mocking.clients.handler_for("s3", mock_client): - with patch("boto3.client", return_value=mock_client): - with self.assertRaises(S3ClientError) as context: - response = self.client.get("/api/v1/get-report/current-full") - # Check that the response has status code 500 - self.assertEqual(response.status_code, 500) - - # Check that we get the right error back from the page - self.assertEqual(context.exception.code, S3ClientErrorCodes.FILE_NOT_FOUND_ERROR) + # Check that we get the right error back from the page + self.assertEqual(context.exception.code, S3ClientErrorCodes.FILE_NOT_FOUND_ERROR) @boto3_mocking.patching def test_not_found_federal_report(self): @@ -143,84 +145,86 @@ class CsvReportsTest(TestCase): def side_effect(Bucket, Key): raise ClientError({"Error": {"Code": "NoSuchKey", "Message": "No such key"}}, "get_object") + with less_console_noise(): + mock_client = MagicMock() + mock_client.get_object.side_effect = side_effect - mock_client = MagicMock() - mock_client.get_object.side_effect = side_effect + with boto3_mocking.clients.handler_for("s3", mock_client): + with patch("boto3.client", return_value=mock_client): + with self.assertRaises(S3ClientError) as context: + response = self.client.get("/api/v1/get-report/current-federal") + # Check that the response has status code 500 + self.assertEqual(response.status_code, 500) - with boto3_mocking.clients.handler_for("s3", mock_client): - with patch("boto3.client", return_value=mock_client): - with self.assertRaises(S3ClientError) as context: - response = self.client.get("/api/v1/get-report/current-federal") - # Check that the response has status code 500 - self.assertEqual(response.status_code, 500) - - # Check that we get the right error back from the page - self.assertEqual(context.exception.code, S3ClientErrorCodes.FILE_NOT_FOUND_ERROR) + # Check that we get the right error back from the page + self.assertEqual(context.exception.code, S3ClientErrorCodes.FILE_NOT_FOUND_ERROR) @boto3_mocking.patching def test_load_federal_report(self): """Tests the get_current_federal api endpoint""" - mock_client = MagicMock() - mock_client_instance = mock_client.return_value + with less_console_noise(): + mock_client = MagicMock() + mock_client_instance = mock_client.return_value - with open("registrar/tests/data/fake_current_federal.csv", "r") as file: - file_content = file.read() + with open("registrar/tests/data/fake_current_federal.csv", "r") as file: + file_content = file.read() - # Mock a recieved file - mock_client_instance.get_object.return_value = {"Body": io.BytesIO(file_content.encode())} - with boto3_mocking.clients.handler_for("s3", mock_client): - request = self.factory.get("/fake-path") - response = get_current_federal(request) + # Mock a recieved file + mock_client_instance.get_object.return_value = {"Body": io.BytesIO(file_content.encode())} + with boto3_mocking.clients.handler_for("s3", mock_client): + request = self.factory.get("/fake-path") + response = get_current_federal(request) - # Check that we are sending the correct calls. - # Ensures that we are decoding the file content recieved from AWS. - expected_call = [call.get_object(Bucket=settings.AWS_S3_BUCKET_NAME, Key="current-federal.csv")] - mock_client_instance.assert_has_calls(expected_call) + # Check that we are sending the correct calls. + # Ensures that we are decoding the file content recieved from AWS. + expected_call = [call.get_object(Bucket=settings.AWS_S3_BUCKET_NAME, Key="current-federal.csv")] + mock_client_instance.assert_has_calls(expected_call) - # Check that the response has status code 200 - self.assertEqual(response.status_code, 200) + # Check that the response has status code 200 + self.assertEqual(response.status_code, 200) - # Check that the response contains what we expect - expected_file_content = ( - "Domain name,Domain type,Agency,Organization name,City,State,Security contact email\n" - "cdomain1.gov,Federal - Executive,World War I Centennial Commission,,,,\n" - "ddomain3.gov,Federal,Armed Forces Retirement Home,,,," - ).encode() + # Check that the response contains what we expect + expected_file_content = ( + "Domain name,Domain type,Agency,Organization name,City,State,Security contact email\n" + "cdomain1.gov,Federal - Executive,World War I Centennial Commission,,,,\n" + "ddomain3.gov,Federal,Armed Forces Retirement Home,,,," + ).encode() - self.assertEqual(expected_file_content, response.content) + self.assertEqual(expected_file_content, response.content) @boto3_mocking.patching def test_load_full_report(self): """Tests the current-federal api link""" - mock_client = MagicMock() - mock_client_instance = mock_client.return_value + with less_console_noise(): + mock_client = MagicMock() + mock_client_instance = mock_client.return_value - with open("registrar/tests/data/fake_current_full.csv", "r") as file: - file_content = file.read() + with open("registrar/tests/data/fake_current_full.csv", "r") as file: + file_content = file.read() - # Mock a recieved file - mock_client_instance.get_object.return_value = {"Body": io.BytesIO(file_content.encode())} - with boto3_mocking.clients.handler_for("s3", mock_client): - request = self.factory.get("/fake-path") - response = get_current_full(request) + # Mock a recieved file + mock_client_instance.get_object.return_value = {"Body": io.BytesIO(file_content.encode())} + with boto3_mocking.clients.handler_for("s3", mock_client): + request = self.factory.get("/fake-path") + response = get_current_full(request) - # Check that we are sending the correct calls. - # Ensures that we are decoding the file content recieved from AWS. - expected_call = [call.get_object(Bucket=settings.AWS_S3_BUCKET_NAME, Key="current-full.csv")] - mock_client_instance.assert_has_calls(expected_call) + # Check that we are sending the correct calls. + # Ensures that we are decoding the file content recieved from AWS. + expected_call = [call.get_object(Bucket=settings.AWS_S3_BUCKET_NAME, Key="current-full.csv")] + mock_client_instance.assert_has_calls(expected_call) - # Check that the response has status code 200 - self.assertEqual(response.status_code, 200) + # Check that the response has status code 200 + self.assertEqual(response.status_code, 200) - # Check that the response contains what we expect - expected_file_content = ( - "Domain name,Domain type,Agency,Organization name,City,State,Security contact email\n" - "cdomain1.gov,Federal - Executive,World War I Centennial Commission,,,,\n" - "ddomain3.gov,Federal,Armed Forces Retirement Home,,,,\n" - "adomain2.gov,Interstate,,,,," - ).encode() + # Check that the response contains what we expect + expected_file_content = ( + "Domain name,Domain type,Agency,Organization name,City,State,Security contact email\n" + "cdomain1.gov,Federal - Executive,World War I Centennial Commission,,,,\n" + "ddomain3.gov,Federal,Armed Forces Retirement Home,,,,\n" + "adomain2.gov,Interstate,,,,," + ).encode() - self.assertEqual(expected_file_content, response.content) + self.assertEqual(expected_file_content, response.content) class ExportDataTest(MockEppLib): @@ -339,192 +343,170 @@ class ExportDataTest(MockEppLib): def test_export_domains_to_writer_security_emails(self): """Test that export_domains_to_writer returns the expected security email""" - - # Add security email information - self.domain_1.name = "defaultsecurity.gov" - self.domain_1.save() - - # Invoke setter - self.domain_1.security_contact - - # Invoke setter - self.domain_2.security_contact - - # Invoke setter - self.domain_3.security_contact - - # Create a CSV file in memory - csv_file = StringIO() - writer = csv.writer(csv_file) - - # Define columns, sort fields, and filter condition - columns = [ - "Domain name", - "Domain type", - "Agency", - "Organization name", - "City", - "State", - "AO", - "AO email", - "Security contact email", - "Status", - "Expiration date", - ] - sort_fields = ["domain__name"] - filter_condition = { - "domain__state__in": [ - Domain.State.READY, - Domain.State.DNS_NEEDED, - Domain.State.ON_HOLD, - ], - } - - self.maxDiff = None - # Call the export functions - write_header(writer, columns) - write_body(writer, columns, sort_fields, filter_condition) - - # Reset the CSV file's position to the beginning - csv_file.seek(0) - - # Read the content into a variable - csv_content = csv_file.read() - - # We expect READY domains, - # sorted alphabetially by domain name - expected_content = ( - "Domain name,Domain type,Agency,Organization name,City,State,AO," - "AO email,Security contact email,Status,Expiration date\n" - "adomain10.gov,Federal,Armed Forces Retirement Home,Ready\n" - "adomain2.gov,Interstate,(blank),Dns needed\n" - "ddomain3.gov,Federal,Armed Forces Retirement Home,123@mail.gov,On hold,2023-05-25\n" - "defaultsecurity.gov,Federal - Executive,World War I Centennial Commission,(blank),Ready" - ) - - # Normalize line endings and remove commas, - # spaces and leading/trailing whitespace - csv_content = csv_content.replace(",,", "").replace(",", "").replace(" ", "").replace("\r\n", "\n").strip() - expected_content = expected_content.replace(",,", "").replace(",", "").replace(" ", "").strip() - - self.assertEqual(csv_content, expected_content) + with less_console_noise(): + # Add security email information + self.domain_1.name = "defaultsecurity.gov" + self.domain_1.save() + # Invoke setter + self.domain_1.security_contact + # Invoke setter + self.domain_2.security_contact + # Invoke setter + self.domain_3.security_contact + # Create a CSV file in memory + csv_file = StringIO() + writer = csv.writer(csv_file) + # Define columns, sort fields, and filter condition + columns = [ + "Domain name", + "Domain type", + "Agency", + "Organization name", + "City", + "State", + "AO", + "AO email", + "Security contact email", + "Status", + "Expiration date", + ] + sort_fields = ["domain__name"] + filter_condition = { + "domain__state__in": [ + Domain.State.READY, + Domain.State.DNS_NEEDED, + Domain.State.ON_HOLD, + ], + } + self.maxDiff = None + # Call the export functions + write_header(writer, columns) + write_body(writer, columns, sort_fields, filter_condition) + # Reset the CSV file's position to the beginning + csv_file.seek(0) + # Read the content into a variable + csv_content = csv_file.read() + # We expect READY domains, + # sorted alphabetially by domain name + expected_content = ( + "Domain name,Domain type,Agency,Organization name,City,State,AO," + "AO email,Security contact email,Status,Expiration date\n" + "adomain10.gov,Federal,Armed Forces Retirement Home,Ready\n" + "adomain2.gov,Interstate,(blank),Dns needed\n" + "ddomain3.gov,Federal,Armed Forces Retirement Home,123@mail.gov,On hold,2023-05-25\n" + "defaultsecurity.gov,Federal - Executive,World War I Centennial Commission,(blank),Ready" + ) + # Normalize line endings and remove commas, + # spaces and leading/trailing whitespace + csv_content = csv_content.replace(",,", "").replace(",", "").replace(" ", "").replace("\r\n", "\n").strip() + expected_content = expected_content.replace(",,", "").replace(",", "").replace(" ", "").strip() + self.assertEqual(csv_content, expected_content) def test_write_body(self): """Test that write_body returns the existing domain, test that sort by domain name works, test that filter works""" - # Create a CSV file in memory - csv_file = StringIO() - writer = csv.writer(csv_file) + with less_console_noise(): + # Create a CSV file in memory + csv_file = StringIO() + writer = csv.writer(csv_file) - # Define columns, sort fields, and filter condition - columns = [ - "Domain name", - "Domain type", - "Agency", - "Organization name", - "City", - "State", - "AO", - "AO email", - "Submitter", - "Submitter title", - "Submitter email", - "Submitter phone", - "Security contact email", - "Status", - ] - sort_fields = ["domain__name"] - filter_condition = { - "domain__state__in": [ - Domain.State.READY, - Domain.State.DNS_NEEDED, - Domain.State.ON_HOLD, - ], - } - - # Call the export functions - write_header(writer, columns) - write_body(writer, columns, sort_fields, filter_condition) - - # Reset the CSV file's position to the beginning - csv_file.seek(0) - - # Read the content into a variable - csv_content = csv_file.read() - - # We expect READY domains, - # sorted alphabetially by domain name - expected_content = ( - "Domain name,Domain type,Agency,Organization name,City,State,AO," - "AO email,Submitter,Submitter title,Submitter email,Submitter phone," - "Security contact email,Status\n" - "adomain10.gov,Federal,Armed Forces Retirement Home,Ready\n" - "adomain2.gov,Interstate,Dns needed\n" - "cdomain1.gov,Federal - Executive,World War I Centennial Commission,Ready\n" - "ddomain3.gov,Federal,Armed Forces Retirement Home,On hold\n" - ) - - # Normalize line endings and remove commas, - # spaces and leading/trailing whitespace - csv_content = csv_content.replace(",,", "").replace(",", "").replace(" ", "").replace("\r\n", "\n").strip() - expected_content = expected_content.replace(",,", "").replace(",", "").replace(" ", "").strip() - - self.assertEqual(csv_content, expected_content) + # Define columns, sort fields, and filter condition + columns = [ + "Domain name", + "Domain type", + "Agency", + "Organization name", + "City", + "State", + "AO", + "AO email", + "Submitter", + "Submitter title", + "Submitter email", + "Submitter phone", + "Security contact email", + "Status", + ] + sort_fields = ["domain__name"] + filter_condition = { + "domain__state__in": [ + Domain.State.READY, + Domain.State.DNS_NEEDED, + Domain.State.ON_HOLD, + ], + } + # Call the export functions + write_header(writer, columns) + write_body(writer, columns, sort_fields, filter_condition) + # Reset the CSV file's position to the beginning + csv_file.seek(0) + # Read the content into a variable + csv_content = csv_file.read() + # We expect READY domains, + # sorted alphabetially by domain name + expected_content = ( + "Domain name,Domain type,Agency,Organization name,City,State,AO," + "AO email,Submitter,Submitter title,Submitter email,Submitter phone," + "Security contact email,Status\n" + "adomain10.gov,Federal,Armed Forces Retirement Home,Ready\n" + "adomain2.gov,Interstate,Dns needed\n" + "cdomain1.gov,Federal - Executive,World War I Centennial Commission,Ready\n" + "ddomain3.gov,Federal,Armed Forces Retirement Home,On hold\n" + ) + # Normalize line endings and remove commas, + # spaces and leading/trailing whitespace + csv_content = csv_content.replace(",,", "").replace(",", "").replace(" ", "").replace("\r\n", "\n").strip() + expected_content = expected_content.replace(",,", "").replace(",", "").replace(" ", "").strip() + self.assertEqual(csv_content, expected_content) def test_write_body_additional(self): """An additional test for filters and multi-column sort""" - # Create a CSV file in memory - csv_file = StringIO() - writer = csv.writer(csv_file) - - # Define columns, sort fields, and filter condition - columns = [ - "Domain name", - "Domain type", - "Agency", - "Organization name", - "City", - "State", - "Security contact email", - ] - sort_fields = ["domain__name", "federal_agency", "organization_type"] - filter_condition = { - "organization_type__icontains": "federal", - "domain__state__in": [ - Domain.State.READY, - Domain.State.DNS_NEEDED, - Domain.State.ON_HOLD, - ], - } - - # Call the export functions - write_header(writer, columns) - write_body(writer, columns, sort_fields, filter_condition) - - # Reset the CSV file's position to the beginning - csv_file.seek(0) - - # Read the content into a variable - csv_content = csv_file.read() - - # We expect READY domains, - # federal only - # sorted alphabetially by domain name - expected_content = ( - "Domain name,Domain type,Agency,Organization name,City," - "State,Security contact email\n" - "adomain10.gov,Federal,Armed Forces Retirement Home\n" - "cdomain1.gov,Federal - Executive,World War I Centennial Commission\n" - "ddomain3.gov,Federal,Armed Forces Retirement Home\n" - ) - - # Normalize line endings and remove commas, - # spaces and leading/trailing whitespace - csv_content = csv_content.replace(",,", "").replace(",", "").replace(" ", "").replace("\r\n", "\n").strip() - expected_content = expected_content.replace(",,", "").replace(",", "").replace(" ", "").strip() - - self.assertEqual(csv_content, expected_content) + with less_console_noise(): + # Create a CSV file in memory + csv_file = StringIO() + writer = csv.writer(csv_file) + # Define columns, sort fields, and filter condition + columns = [ + "Domain name", + "Domain type", + "Agency", + "Organization name", + "City", + "State", + "Security contact email", + ] + sort_fields = ["domain__name", "federal_agency", "organization_type"] + filter_condition = { + "organization_type__icontains": "federal", + "domain__state__in": [ + Domain.State.READY, + Domain.State.DNS_NEEDED, + Domain.State.ON_HOLD, + ], + } + # Call the export functions + write_header(writer, columns) + write_body(writer, columns, sort_fields, filter_condition) + # Reset the CSV file's position to the beginning + csv_file.seek(0) + # Read the content into a variable + csv_content = csv_file.read() + # We expect READY domains, + # federal only + # sorted alphabetially by domain name + expected_content = ( + "Domain name,Domain type,Agency,Organization name,City," + "State,Security contact email\n" + "adomain10.gov,Federal,Armed Forces Retirement Home\n" + "cdomain1.gov,Federal - Executive,World War I Centennial Commission\n" + "ddomain3.gov,Federal,Armed Forces Retirement Home\n" + ) + # Normalize line endings and remove commas, + # spaces and leading/trailing whitespace + csv_content = csv_content.replace(",,", "").replace(",", "").replace(" ", "").replace("\r\n", "\n").strip() + expected_content = expected_content.replace(",,", "").replace(",", "").replace(" ", "").strip() + self.assertEqual(csv_content, expected_content) def test_write_body_with_date_filter_pulls_domains_in_range(self): """Test that domains that are @@ -538,88 +520,88 @@ class ExportDataTest(MockEppLib): which are hard to mock. TODO: Simplify is created_at is not needed for the report.""" + with less_console_noise(): + # Create a CSV file in memory + csv_file = StringIO() + writer = csv.writer(csv_file) + # We use timezone.make_aware to sync to server time a datetime object with the current date (using date.today()) + # and a specific time (using datetime.min.time()). + end_date = timezone.make_aware(datetime.combine(date.today() + timedelta(days=2), datetime.min.time())) + start_date = timezone.make_aware(datetime.combine(date.today() - timedelta(days=2), datetime.min.time())) - # Create a CSV file in memory - csv_file = StringIO() - writer = csv.writer(csv_file) - # We use timezone.make_aware to sync to server time a datetime object with the current date (using date.today()) - # and a specific time (using datetime.min.time()). - end_date = timezone.make_aware(datetime.combine(date.today() + timedelta(days=2), datetime.min.time())) - start_date = timezone.make_aware(datetime.combine(date.today() - timedelta(days=2), datetime.min.time())) + # Define columns, sort fields, and filter condition + columns = [ + "Domain name", + "Domain type", + "Agency", + "Organization name", + "City", + "State", + "Status", + "Expiration date", + ] + sort_fields = [ + "created_at", + "domain__name", + ] + sort_fields_for_deleted_domains = [ + "domain__deleted", + "domain__name", + ] + filter_condition = { + "domain__state__in": [ + Domain.State.READY, + ], + "domain__first_ready__lte": end_date, + "domain__first_ready__gte": start_date, + } + filter_conditions_for_deleted_domains = { + "domain__state__in": [ + Domain.State.DELETED, + ], + "domain__deleted__lte": end_date, + "domain__deleted__gte": start_date, + } - # Define columns, sort fields, and filter condition - columns = [ - "Domain name", - "Domain type", - "Agency", - "Organization name", - "City", - "State", - "Status", - "Expiration date", - ] - sort_fields = [ - "created_at", - "domain__name", - ] - sort_fields_for_deleted_domains = [ - "domain__deleted", - "domain__name", - ] - filter_condition = { - "domain__state__in": [ - Domain.State.READY, - ], - "domain__first_ready__lte": end_date, - "domain__first_ready__gte": start_date, - } - filter_conditions_for_deleted_domains = { - "domain__state__in": [ - Domain.State.DELETED, - ], - "domain__deleted__lte": end_date, - "domain__deleted__gte": start_date, - } + # Call the export functions + write_header(writer, columns) + write_body( + writer, + columns, + sort_fields, + filter_condition, + ) + write_body( + writer, + columns, + sort_fields_for_deleted_domains, + filter_conditions_for_deleted_domains, + ) - # Call the export functions - write_header(writer, columns) - write_body( - writer, - columns, - sort_fields, - filter_condition, - ) - write_body( - writer, - columns, - sort_fields_for_deleted_domains, - filter_conditions_for_deleted_domains, - ) + # Reset the CSV file's position to the beginning + csv_file.seek(0) - # Reset the CSV file's position to the beginning - csv_file.seek(0) + # Read the content into a variable + csv_content = csv_file.read() - # Read the content into a variable - csv_content = csv_file.read() + # We expect READY domains first, created between today-2 and today+2, sorted by created_at then name + # and DELETED domains deleted between today-2 and today+2, sorted by deleted then name + expected_content = ( + "Domain name,Domain type,Agency,Organization name,City," + "State,Status,Expiration date\n" + "cdomain1.gov,Federal-Executive,World War I Centennial Commission,,,,Ready,\n" + "adomain10.gov,Federal,Armed Forces Retirement Home,,,,Ready,\n" + "zdomain9.gov,Federal,Armed Forces Retirement Home,,,,Deleted,\n" + "sdomain8.gov,Federal,Armed Forces Retirement Home,,,,Deleted,\n" + "xdomain7.gov,Federal,Armed Forces Retirement Home,,,,Deleted,\n" + ) - # We expect READY domains first, created between today-2 and today+2, sorted by created_at then name - # and DELETED domains deleted between today-2 and today+2, sorted by deleted then name - expected_content = ( - "Domain name,Domain type,Agency,Organization name,City," - "State,Status,Expiration date\n" - "cdomain1.gov,Federal-Executive,World War I Centennial Commission,,,,Ready,\n" - "adomain10.gov,Federal,Armed Forces Retirement Home,,,,Ready,\n" - "zdomain9.gov,Federal,Armed Forces Retirement Home,,,,Deleted,\n" - "sdomain8.gov,Federal,Armed Forces Retirement Home,,,,Deleted,\n" - "xdomain7.gov,Federal,Armed Forces Retirement Home,,,,Deleted,\n" - ) + # Normalize line endings and remove commas, + # spaces and leading/trailing whitespace + csv_content = csv_content.replace(",,", "").replace(",", "").replace(" ", "").replace("\r\n", "\n").strip() + expected_content = expected_content.replace(",,", "").replace(",", "").replace(" ", "").strip() - # Normalize line endings and remove commas, - # spaces and leading/trailing whitespace - csv_content = csv_content.replace(",,", "").replace(",", "").replace(" ", "").replace("\r\n", "\n").strip() - expected_content = expected_content.replace(",,", "").replace(",", "").replace(" ", "").strip() - - self.assertEqual(csv_content, expected_content) + self.assertEqual(csv_content, expected_content) class HelperFunctions(TestCase): diff --git a/src/registrar/tests/test_transition_domain_migrations.py b/src/registrar/tests/test_transition_domain_migrations.py index be4619e0b..d419e6fcd 100644 --- a/src/registrar/tests/test_transition_domain_migrations.py +++ b/src/registrar/tests/test_transition_domain_migrations.py @@ -20,7 +20,9 @@ from registrar.models.contact import Contact from .common import MockSESClient, less_console_noise import boto3_mocking # type: ignore +import logging +logger = logging.getLogger(__name__) class TestProcessedMigrations(TestCase): """This test case class is designed to verify the idempotency of migrations @@ -55,17 +57,18 @@ class TestProcessedMigrations(TestCase): The 'call_command' function from Django's management framework is then used to execute the load_transition_domain command with the specified arguments. """ - # noqa here because splitting this up makes it confusing. - # ES501 - with patch( - "registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa - return_value=True, - ): - call_command( - "load_transition_domain", - self.migration_json_filename, - directory=self.test_data_file_location, - ) + with less_console_noise(): + # noqa here because splitting this up makes it confusing. + # ES501 + with patch( + "registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa + return_value=True, + ): + call_command( + "load_transition_domain", + self.migration_json_filename, + directory=self.test_data_file_location, + ) def run_transfer_domains(self): """ @@ -74,101 +77,104 @@ class TestProcessedMigrations(TestCase): The 'call_command' function from Django's management framework is then used to execute the load_transition_domain command with the specified arguments. """ - call_command("transfer_transition_domains_to_domains") + with less_console_noise(): + call_command("transfer_transition_domains_to_domains") def test_domain_idempotent(self): """ This test ensures that the domain transfer process is idempotent on Domain and DomainInformation. """ - unchanged_domain, _ = Domain.objects.get_or_create( - name="testdomain.gov", - state=Domain.State.READY, - expiration_date=datetime.date(2000, 1, 1), - ) - unchanged_domain_information, _ = DomainInformation.objects.get_or_create( - domain=unchanged_domain, organization_name="test org name", creator=self.user - ) - self.run_load_domains() + with less_console_noise(): + unchanged_domain, _ = Domain.objects.get_or_create( + name="testdomain.gov", + state=Domain.State.READY, + expiration_date=datetime.date(2000, 1, 1), + ) + unchanged_domain_information, _ = DomainInformation.objects.get_or_create( + domain=unchanged_domain, organization_name="test org name", creator=self.user + ) + self.run_load_domains() - # Test that a given TransitionDomain isn't set to "processed" - transition_domain_object = TransitionDomain.objects.get(domain_name="fakewebsite3.gov") - self.assertFalse(transition_domain_object.processed) + # Test that a given TransitionDomain isn't set to "processed" + transition_domain_object = TransitionDomain.objects.get(domain_name="fakewebsite3.gov") + self.assertFalse(transition_domain_object.processed) - self.run_transfer_domains() + self.run_transfer_domains() - # Test that old data isn't corrupted - actual_unchanged = Domain.objects.filter(name="testdomain.gov").get() - actual_unchanged_information = DomainInformation.objects.filter(domain=actual_unchanged).get() - self.assertEqual(unchanged_domain, actual_unchanged) - self.assertEqual(unchanged_domain_information, actual_unchanged_information) + # Test that old data isn't corrupted + actual_unchanged = Domain.objects.filter(name="testdomain.gov").get() + actual_unchanged_information = DomainInformation.objects.filter(domain=actual_unchanged).get() + self.assertEqual(unchanged_domain, actual_unchanged) + self.assertEqual(unchanged_domain_information, actual_unchanged_information) - # Test that a given TransitionDomain is set to "processed" after we transfer domains - transition_domain_object = TransitionDomain.objects.get(domain_name="fakewebsite3.gov") - self.assertTrue(transition_domain_object.processed) + # Test that a given TransitionDomain is set to "processed" after we transfer domains + transition_domain_object = TransitionDomain.objects.get(domain_name="fakewebsite3.gov") + self.assertTrue(transition_domain_object.processed) - # Manually change Domain/DomainInformation objects - changed_domain = Domain.objects.filter(name="fakewebsite3.gov").get() - changed_domain.expiration_date = datetime.date(1999, 1, 1) + # Manually change Domain/DomainInformation objects + changed_domain = Domain.objects.filter(name="fakewebsite3.gov").get() + changed_domain.expiration_date = datetime.date(1999, 1, 1) - changed_domain.save() + changed_domain.save() - changed_domain_information = DomainInformation.objects.filter(domain=changed_domain).get() - changed_domain_information.organization_name = "changed" + changed_domain_information = DomainInformation.objects.filter(domain=changed_domain).get() + changed_domain_information.organization_name = "changed" - changed_domain_information.save() + changed_domain_information.save() - # Rerun transfer domains - self.run_transfer_domains() + # Rerun transfer domains + self.run_transfer_domains() - # Test that old data isn't corrupted after running this twice - actual_unchanged = Domain.objects.filter(name="testdomain.gov").get() - actual_unchanged_information = DomainInformation.objects.filter(domain=actual_unchanged).get() - self.assertEqual(unchanged_domain, actual_unchanged) - self.assertEqual(unchanged_domain_information, actual_unchanged_information) + # Test that old data isn't corrupted after running this twice + actual_unchanged = Domain.objects.filter(name="testdomain.gov").get() + actual_unchanged_information = DomainInformation.objects.filter(domain=actual_unchanged).get() + self.assertEqual(unchanged_domain, actual_unchanged) + self.assertEqual(unchanged_domain_information, actual_unchanged_information) - # Ensure that domain hasn't changed - actual_domain = Domain.objects.filter(name="fakewebsite3.gov").get() - self.assertEqual(changed_domain, actual_domain) + # Ensure that domain hasn't changed + actual_domain = Domain.objects.filter(name="fakewebsite3.gov").get() + self.assertEqual(changed_domain, actual_domain) - # Ensure that DomainInformation hasn't changed - actual_domain_information = DomainInformation.objects.filter(domain=changed_domain).get() - self.assertEqual(changed_domain_information, actual_domain_information) + # Ensure that DomainInformation hasn't changed + actual_domain_information = DomainInformation.objects.filter(domain=changed_domain).get() + self.assertEqual(changed_domain_information, actual_domain_information) def test_transition_domain_is_processed(self): """ This test checks if a domain is correctly marked as processed in the transition. """ - old_transition_domain, _ = TransitionDomain.objects.get_or_create(domain_name="testdomain.gov") - # Asser that old records default to 'True' - self.assertTrue(old_transition_domain.processed) + with less_console_noise(): + old_transition_domain, _ = TransitionDomain.objects.get_or_create(domain_name="testdomain.gov") + # Asser that old records default to 'True' + self.assertTrue(old_transition_domain.processed) - unchanged_domain, _ = Domain.objects.get_or_create( - name="testdomain.gov", - state=Domain.State.READY, - expiration_date=datetime.date(2000, 1, 1), - ) - unchanged_domain_information, _ = DomainInformation.objects.get_or_create( - domain=unchanged_domain, organization_name="test org name", creator=self.user - ) - self.run_load_domains() + unchanged_domain, _ = Domain.objects.get_or_create( + name="testdomain.gov", + state=Domain.State.READY, + expiration_date=datetime.date(2000, 1, 1), + ) + unchanged_domain_information, _ = DomainInformation.objects.get_or_create( + domain=unchanged_domain, organization_name="test org name", creator=self.user + ) + self.run_load_domains() - # Test that a given TransitionDomain isn't set to "processed" - transition_domain_object = TransitionDomain.objects.get(domain_name="fakewebsite3.gov") - self.assertFalse(transition_domain_object.processed) + # Test that a given TransitionDomain isn't set to "processed" + transition_domain_object = TransitionDomain.objects.get(domain_name="fakewebsite3.gov") + self.assertFalse(transition_domain_object.processed) - self.run_transfer_domains() + self.run_transfer_domains() - # Test that old data isn't corrupted - actual_unchanged = Domain.objects.filter(name="testdomain.gov").get() - actual_unchanged_information = DomainInformation.objects.filter(domain=actual_unchanged).get() - self.assertEqual(unchanged_domain, actual_unchanged) - self.assertTrue(old_transition_domain.processed) - self.assertEqual(unchanged_domain_information, actual_unchanged_information) + # Test that old data isn't corrupted + actual_unchanged = Domain.objects.filter(name="testdomain.gov").get() + actual_unchanged_information = DomainInformation.objects.filter(domain=actual_unchanged).get() + self.assertEqual(unchanged_domain, actual_unchanged) + self.assertTrue(old_transition_domain.processed) + self.assertEqual(unchanged_domain_information, actual_unchanged_information) - # Test that a given TransitionDomain is set to "processed" after we transfer domains - transition_domain_object = TransitionDomain.objects.get(domain_name="fakewebsite3.gov") - self.assertTrue(transition_domain_object.processed) + # Test that a given TransitionDomain is set to "processed" after we transfer domains + transition_domain_object = TransitionDomain.objects.get(domain_name="fakewebsite3.gov") + self.assertTrue(transition_domain_object.processed) class TestOrganizationMigration(TestCase): @@ -200,17 +206,18 @@ class TestOrganizationMigration(TestCase): The 'call_command' function from Django's management framework is then used to execute the load_transition_domain command with the specified arguments. """ - # noqa here because splitting this up makes it confusing. - # ES501 - with patch( - "registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa - return_value=True, - ): - call_command( - "load_transition_domain", - self.migration_json_filename, - directory=self.test_data_file_location, - ) + with less_console_noise(): + # noqa here because splitting this up makes it confusing. + # ES501 + with patch( + "registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa + return_value=True, + ): + call_command( + "load_transition_domain", + self.migration_json_filename, + directory=self.test_data_file_location, + ) def run_transfer_domains(self): """ @@ -219,7 +226,8 @@ class TestOrganizationMigration(TestCase): The 'call_command' function from Django's management framework is then used to execute the load_transition_domain command with the specified arguments. """ - call_command("transfer_transition_domains_to_domains") + with less_console_noise(): + call_command("transfer_transition_domains_to_domains") def run_load_organization_data(self): """ @@ -232,17 +240,18 @@ class TestOrganizationMigration(TestCase): The 'call_command' function from Django's management framework is then used to execute the load_organization_data command with the specified arguments. """ + with less_console_noise(): # noqa here (E501) because splitting this up makes it # confusing to read. - with patch( - "registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa - return_value=True, - ): - call_command( - "load_organization_data", - self.migration_json_filename, - directory=self.test_data_file_location, - ) + with patch( + "registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa + return_value=True, + ): + call_command( + "load_organization_data", + self.migration_json_filename, + directory=self.test_data_file_location, + ) def compare_tables( self, @@ -256,7 +265,6 @@ class TestOrganizationMigration(TestCase): """Does a diff between the transition_domain and the following tables: domain, domain_information and the domain_invitation. Verifies that the data loaded correctly.""" - missing_domains = [] duplicate_domains = [] missing_domain_informations = [] @@ -301,58 +309,62 @@ class TestOrganizationMigration(TestCase): The expected result is a set of TransitionDomain objects with specific attributes. The test fetches the actual TransitionDomain objects from the database and compares them with the expected objects. - """ # noqa - E501 (harder to read) - # == First, parse all existing data == # - self.run_load_domains() - self.run_transfer_domains() + """ + with less_console_noise(): + # noqa - E501 (harder to read) + # == First, parse all existing data == # + self.run_load_domains() + self.run_transfer_domains() - # == Second, try adding org data to it == # - self.run_load_organization_data() + # == Second, try adding org data to it == # + self.run_load_organization_data() - # == Third, test that we've loaded data as we expect == # - transition_domains = TransitionDomain.objects.filter(domain_name="fakewebsite2.gov") + # == Third, test that we've loaded data as we expect == # + transition_domains = TransitionDomain.objects.filter(domain_name="fakewebsite2.gov") - # Should return three objects (three unique emails) - self.assertEqual(transition_domains.count(), 3) + # Should return three objects (three unique emails) + self.assertEqual(transition_domains.count(), 3) - # Lets test the first one - transition = transition_domains.first() - expected_transition_domain = TransitionDomain( - username="alexandra.bobbitt5@test.com", - domain_name="fakewebsite2.gov", - status="on hold", - email_sent=True, - organization_type="Federal", - organization_name="Fanoodle", - federal_type="Executive", - federal_agency="Department of Commerce", - epp_creation_date=datetime.date(2004, 5, 7), - epp_expiration_date=datetime.date(2023, 9, 30), - first_name="Seline", - middle_name="testmiddle2", - last_name="Tower", - title=None, - email="stower3@answers.com", - phone="151-539-6028", - address_line="93001 Arizona Drive", - city="Columbus", - state_territory="Oh", - zipcode="43268", - ) - expected_transition_domain.id = transition.id + # Lets test the first one + transition = transition_domains.first() + expected_transition_domain = TransitionDomain( + username="alexandra.bobbitt5@test.com", + domain_name="fakewebsite2.gov", + status="on hold", + email_sent=True, + organization_type="Federal", + organization_name="Fanoodle", + federal_type="Executive", + federal_agency="Department of Commerce", + epp_creation_date=datetime.date(2004, 5, 7), + epp_expiration_date=datetime.date(2023, 9, 30), + first_name="Seline", + middle_name="testmiddle2", + last_name="Tower", + title=None, + email="stower3@answers.com", + phone="151-539-6028", + address_line="93001 Arizona Drive", + city="Columbus", + state_territory="Oh", + zipcode="43268", + ) + expected_transition_domain.id = transition.id - self.assertEqual(transition, expected_transition_domain) + self.assertEqual(transition, expected_transition_domain) def test_transition_domain_status_unknown(self): """ Test that a domain in unknown status can be loaded - """ # noqa - E501 (harder to read) - # == First, parse all existing data == # - self.run_load_domains() - self.run_transfer_domains() + """ + with less_console_noise(): + # noqa - E501 (harder to read) + # == First, parse all existing data == # + self.run_load_domains() + self.run_transfer_domains() - domain_object = Domain.objects.get(name="fakewebsite3.gov") - self.assertEqual(domain_object.state, Domain.State.UNKNOWN) + domain_object = Domain.objects.get(name="fakewebsite3.gov") + self.assertEqual(domain_object.state, Domain.State.UNKNOWN) def test_load_organization_data_domain_information(self): """ @@ -367,35 +379,36 @@ class TestOrganizationMigration(TestCase): The test fetches the actual DomainInformation object from the database and compares it with the expected object. """ - # == First, parse all existing data == # - self.run_load_domains() - self.run_transfer_domains() + with less_console_noise(): + # == First, parse all existing data == # + self.run_load_domains() + self.run_transfer_domains() - # == Second, try adding org data to it == # - self.run_load_organization_data() + # == Second, try adding org data to it == # + self.run_load_organization_data() - # == Third, test that we've loaded data as we expect == # - _domain = Domain.objects.filter(name="fakewebsite2.gov").get() - domain_information = DomainInformation.objects.filter(domain=_domain).get() + # == Third, test that we've loaded data as we expect == # + _domain = Domain.objects.filter(name="fakewebsite2.gov").get() + domain_information = DomainInformation.objects.filter(domain=_domain).get() - expected_creator = User.objects.filter(username="System").get() - expected_ao = Contact.objects.filter(first_name="Seline", middle_name="testmiddle2", last_name="Tower").get() - expected_domain_information = DomainInformation( - creator=expected_creator, - organization_type="federal", - federal_agency="Department of Commerce", - federal_type="executive", - organization_name="Fanoodle", - address_line1="93001 Arizona Drive", - city="Columbus", - state_territory="Oh", - zipcode="43268", - authorizing_official=expected_ao, - domain=_domain, - ) - # Given that these are different objects, this needs to be set - expected_domain_information.id = domain_information.id - self.assertEqual(domain_information, expected_domain_information) + expected_creator = User.objects.filter(username="System").get() + expected_ao = Contact.objects.filter(first_name="Seline", middle_name="testmiddle2", last_name="Tower").get() + expected_domain_information = DomainInformation( + creator=expected_creator, + organization_type="federal", + federal_agency="Department of Commerce", + federal_type="executive", + organization_name="Fanoodle", + address_line1="93001 Arizona Drive", + city="Columbus", + state_territory="Oh", + zipcode="43268", + authorizing_official=expected_ao, + domain=_domain, + ) + # Given that these are different objects, this needs to be set + expected_domain_information.id = domain_information.id + self.assertEqual(domain_information, expected_domain_information) def test_load_organization_data_preserves_existing_data(self): """ @@ -410,44 +423,45 @@ class TestOrganizationMigration(TestCase): The expected result is that the DomainInformation object retains its pre-existing data after the load_organization_data method is run. """ - # == First, parse all existing data == # - self.run_load_domains() - self.run_transfer_domains() + with less_console_noise(): + # == First, parse all existing data == # + self.run_load_domains() + self.run_transfer_domains() - # == Second, try add prexisting fake data == # - _domain_old = Domain.objects.filter(name="fakewebsite2.gov").get() - domain_information_old = DomainInformation.objects.filter(domain=_domain_old).get() - domain_information_old.address_line1 = "93001 Galactic Way" - domain_information_old.city = "Olympus" - domain_information_old.state_territory = "MA" - domain_information_old.zipcode = "12345" - domain_information_old.save() + # == Second, try add prexisting fake data == # + _domain_old = Domain.objects.filter(name="fakewebsite2.gov").get() + domain_information_old = DomainInformation.objects.filter(domain=_domain_old).get() + domain_information_old.address_line1 = "93001 Galactic Way" + domain_information_old.city = "Olympus" + domain_information_old.state_territory = "MA" + domain_information_old.zipcode = "12345" + domain_information_old.save() - # == Third, try running the script == # - self.run_load_organization_data() + # == Third, try running the script == # + self.run_load_organization_data() - # == Fourth, test that no data is overwritten as we expect == # - _domain = Domain.objects.filter(name="fakewebsite2.gov").get() - domain_information = DomainInformation.objects.filter(domain=_domain).get() + # == Fourth, test that no data is overwritten as we expect == # + _domain = Domain.objects.filter(name="fakewebsite2.gov").get() + domain_information = DomainInformation.objects.filter(domain=_domain).get() - expected_creator = User.objects.filter(username="System").get() - expected_ao = Contact.objects.filter(first_name="Seline", middle_name="testmiddle2", last_name="Tower").get() - expected_domain_information = DomainInformation( - creator=expected_creator, - organization_type="federal", - federal_agency="Department of Commerce", - federal_type="executive", - organization_name="Fanoodle", - address_line1="93001 Galactic Way", - city="Olympus", - state_territory="MA", - zipcode="12345", - authorizing_official=expected_ao, - domain=_domain, - ) - # Given that these are different objects, this needs to be set - expected_domain_information.id = domain_information.id - self.assertEqual(domain_information, expected_domain_information) + expected_creator = User.objects.filter(username="System").get() + expected_ao = Contact.objects.filter(first_name="Seline", middle_name="testmiddle2", last_name="Tower").get() + expected_domain_information = DomainInformation( + creator=expected_creator, + organization_type="federal", + federal_agency="Department of Commerce", + federal_type="executive", + organization_name="Fanoodle", + address_line1="93001 Galactic Way", + city="Olympus", + state_territory="MA", + zipcode="12345", + authorizing_official=expected_ao, + domain=_domain, + ) + # Given that these are different objects, this needs to be set + expected_domain_information.id = domain_information.id + self.assertEqual(domain_information, expected_domain_information) def test_load_organization_data_integrity(self): """ @@ -462,29 +476,30 @@ class TestOrganizationMigration(TestCase): The expected result is that the counts of objects in the database match the expected counts, indicating that the data has not been corrupted. """ - # First, parse all existing data - self.run_load_domains() - self.run_transfer_domains() + with less_console_noise(): + # First, parse all existing data + self.run_load_domains() + self.run_transfer_domains() - # Second, try adding org data to it - self.run_load_organization_data() + # Second, try adding org data to it + self.run_load_organization_data() - # Third, test that we didn't corrupt any data - expected_total_transition_domains = 9 - expected_total_domains = 5 - expected_total_domain_informations = 5 + # Third, test that we didn't corrupt any data + expected_total_transition_domains = 9 + expected_total_domains = 5 + expected_total_domain_informations = 5 - expected_missing_domains = 0 - expected_duplicate_domains = 0 - expected_missing_domain_informations = 0 - self.compare_tables( - expected_total_transition_domains, - expected_total_domains, - expected_total_domain_informations, - expected_missing_domains, - expected_duplicate_domains, - expected_missing_domain_informations, - ) + expected_missing_domains = 0 + expected_duplicate_domains = 0 + expected_missing_domain_informations = 0 + self.compare_tables( + expected_total_transition_domains, + expected_total_domains, + expected_total_domain_informations, + expected_missing_domains, + expected_duplicate_domains, + expected_missing_domain_informations, + ) class TestMigrations(TestCase): @@ -521,39 +536,42 @@ class TestMigrations(TestCase): UserDomainRole.objects.all().delete() def run_load_domains(self): - # noqa here because splitting this up makes it confusing. - # ES501 - with patch( - "registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa - return_value=True, - ): - call_command( - "load_transition_domain", - self.migration_json_filename, - directory=self.test_data_file_location, - ) - - def run_transfer_domains(self): - call_command("transfer_transition_domains_to_domains") - - def run_master_script(self): - # noqa here (E501) because splitting this up makes it - # confusing to read. - mock_client = MockSESClient() - with boto3_mocking.clients.handler_for("sesv2", mock_client): + with less_console_noise(): + # noqa here because splitting this up makes it confusing. + # ES501 with patch( "registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa return_value=True, ): - with patch("registrar.utility.email.send_templated_email", return_value=None): - call_command( - "master_domain_migrations", - runMigrations=True, - migrationDirectory=self.test_data_file_location, - migrationJSON=self.migration_json_filename, - disablePrompts=True, - ) - print(f"here: {mock_client.EMAILS_SENT}") + call_command( + "load_transition_domain", + self.migration_json_filename, + directory=self.test_data_file_location, + ) + + def run_transfer_domains(self): + with less_console_noise(): + call_command("transfer_transition_domains_to_domains") + + def run_master_script(self): + with less_console_noise(): + # noqa here (E501) because splitting this up makes it + # confusing to read. + mock_client = MockSESClient() + with boto3_mocking.clients.handler_for("sesv2", mock_client): + with patch( + "registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa + return_value=True, + ): + with patch("registrar.utility.email.send_templated_email", return_value=None): + call_command( + "master_domain_migrations", + runMigrations=True, + migrationDirectory=self.test_data_file_location, + migrationJSON=self.migration_json_filename, + disablePrompts=True, + ) + logger.debug(f"here: {mock_client.EMAILS_SENT}") def compare_tables( self, @@ -607,7 +625,7 @@ class TestMigrations(TestCase): total_domain_informations = len(DomainInformation.objects.all()) total_domain_invitations = len(DomainInvitation.objects.all()) - print( + logger.debug( f""" total_missing_domains = {len(missing_domains)} total_duplicate_domains = {len(duplicate_domains)} @@ -636,225 +654,230 @@ class TestMigrations(TestCase): follow best practice of limiting the number of assertions per test. But for now, this will double-check that the script works as intended.""" + with less_console_noise(): + self.run_master_script() - self.run_master_script() + # STEP 2: (analyze the tables just like the + # migration script does, but add assert statements) + expected_total_transition_domains = 9 + expected_total_domains = 5 + expected_total_domain_informations = 5 + expected_total_domain_invitations = 8 - # STEP 2: (analyze the tables just like the - # migration script does, but add assert statements) - expected_total_transition_domains = 9 - expected_total_domains = 5 - expected_total_domain_informations = 5 - expected_total_domain_invitations = 8 - - expected_missing_domains = 0 - expected_duplicate_domains = 0 - expected_missing_domain_informations = 0 - # we expect 1 missing invite from anomaly.gov (an injected error) - expected_missing_domain_invitations = 1 - self.compare_tables( - expected_total_transition_domains, - expected_total_domains, - expected_total_domain_informations, - expected_total_domain_invitations, - expected_missing_domains, - expected_duplicate_domains, - expected_missing_domain_informations, - expected_missing_domain_invitations, - ) + expected_missing_domains = 0 + expected_duplicate_domains = 0 + expected_missing_domain_informations = 0 + # we expect 1 missing invite from anomaly.gov (an injected error) + expected_missing_domain_invitations = 1 + self.compare_tables( + expected_total_transition_domains, + expected_total_domains, + expected_total_domain_informations, + expected_total_domain_invitations, + expected_missing_domains, + expected_duplicate_domains, + expected_missing_domain_informations, + expected_missing_domain_invitations, + ) def test_load_empty_transition_domain(self): """Loads TransitionDomains without additional data""" - self.run_load_domains() + with less_console_noise(): + self.run_load_domains() - # STEP 2: (analyze the tables just like the migration - # script does, but add assert statements) - expected_total_transition_domains = 9 - expected_total_domains = 0 - expected_total_domain_informations = 0 - expected_total_domain_invitations = 0 + # STEP 2: (analyze the tables just like the migration + # script does, but add assert statements) + expected_total_transition_domains = 9 + expected_total_domains = 0 + expected_total_domain_informations = 0 + expected_total_domain_invitations = 0 - expected_missing_domains = 9 - expected_duplicate_domains = 0 - expected_missing_domain_informations = 9 - expected_missing_domain_invitations = 9 - self.compare_tables( - expected_total_transition_domains, - expected_total_domains, - expected_total_domain_informations, - expected_total_domain_invitations, - expected_missing_domains, - expected_duplicate_domains, - expected_missing_domain_informations, - expected_missing_domain_invitations, - ) + expected_missing_domains = 9 + expected_duplicate_domains = 0 + expected_missing_domain_informations = 9 + expected_missing_domain_invitations = 9 + self.compare_tables( + expected_total_transition_domains, + expected_total_domains, + expected_total_domain_informations, + expected_total_domain_invitations, + expected_missing_domains, + expected_duplicate_domains, + expected_missing_domain_informations, + expected_missing_domain_invitations, + ) def test_load_full_domain(self): - self.run_load_domains() - self.run_transfer_domains() + with less_console_noise(): + self.run_load_domains() + self.run_transfer_domains() - # Analyze the tables - expected_total_transition_domains = 9 - expected_total_domains = 5 - expected_total_domain_informations = 5 - expected_total_domain_invitations = 8 + # Analyze the tables + expected_total_transition_domains = 9 + expected_total_domains = 5 + expected_total_domain_informations = 5 + expected_total_domain_invitations = 8 - expected_missing_domains = 0 - expected_duplicate_domains = 0 - expected_missing_domain_informations = 0 - expected_missing_domain_invitations = 1 - self.compare_tables( - expected_total_transition_domains, - expected_total_domains, - expected_total_domain_informations, - expected_total_domain_invitations, - expected_missing_domains, - expected_duplicate_domains, - expected_missing_domain_informations, - expected_missing_domain_invitations, - ) + expected_missing_domains = 0 + expected_duplicate_domains = 0 + expected_missing_domain_informations = 0 + expected_missing_domain_invitations = 1 + self.compare_tables( + expected_total_transition_domains, + expected_total_domains, + expected_total_domain_informations, + expected_total_domain_invitations, + expected_missing_domains, + expected_duplicate_domains, + expected_missing_domain_informations, + expected_missing_domain_invitations, + ) - # Test created domains - anomaly_domains = Domain.objects.filter(name="anomaly.gov") - self.assertEqual(anomaly_domains.count(), 1) - anomaly = anomaly_domains.get() + # Test created domains + anomaly_domains = Domain.objects.filter(name="anomaly.gov") + self.assertEqual(anomaly_domains.count(), 1) + anomaly = anomaly_domains.get() - self.assertEqual(anomaly.expiration_date, datetime.date(2023, 3, 9)) + self.assertEqual(anomaly.expiration_date, datetime.date(2023, 3, 9)) - self.assertEqual(anomaly.name, "anomaly.gov") - self.assertEqual(anomaly.state, "ready") + self.assertEqual(anomaly.name, "anomaly.gov") + self.assertEqual(anomaly.state, "ready") - testdomain_domains = Domain.objects.filter(name="fakewebsite2.gov") - self.assertEqual(testdomain_domains.count(), 1) + testdomain_domains = Domain.objects.filter(name="fakewebsite2.gov") + self.assertEqual(testdomain_domains.count(), 1) - testdomain = testdomain_domains.get() + testdomain = testdomain_domains.get() - self.assertEqual(testdomain.expiration_date, datetime.date(2023, 9, 30)) - self.assertEqual(testdomain.name, "fakewebsite2.gov") - self.assertEqual(testdomain.state, "on hold") + self.assertEqual(testdomain.expiration_date, datetime.date(2023, 9, 30)) + self.assertEqual(testdomain.name, "fakewebsite2.gov") + self.assertEqual(testdomain.state, "on hold") def test_load_full_domain_information(self): - self.run_load_domains() - self.run_transfer_domains() + with less_console_noise(): + self.run_load_domains() + self.run_transfer_domains() - # Analyze the tables - expected_total_transition_domains = 9 - expected_total_domains = 5 - expected_total_domain_informations = 5 - expected_total_domain_invitations = 8 + # Analyze the tables + expected_total_transition_domains = 9 + expected_total_domains = 5 + expected_total_domain_informations = 5 + expected_total_domain_invitations = 8 - expected_missing_domains = 0 - expected_duplicate_domains = 0 - expected_missing_domain_informations = 0 - expected_missing_domain_invitations = 1 - self.compare_tables( - expected_total_transition_domains, - expected_total_domains, - expected_total_domain_informations, - expected_total_domain_invitations, - expected_missing_domains, - expected_duplicate_domains, - expected_missing_domain_informations, - expected_missing_domain_invitations, - ) + expected_missing_domains = 0 + expected_duplicate_domains = 0 + expected_missing_domain_informations = 0 + expected_missing_domain_invitations = 1 + self.compare_tables( + expected_total_transition_domains, + expected_total_domains, + expected_total_domain_informations, + expected_total_domain_invitations, + expected_missing_domains, + expected_duplicate_domains, + expected_missing_domain_informations, + expected_missing_domain_invitations, + ) - # Test created Domain Information objects - domain = Domain.objects.filter(name="anomaly.gov").get() - anomaly_domain_infos = DomainInformation.objects.filter(domain=domain) + # Test created Domain Information objects + domain = Domain.objects.filter(name="anomaly.gov").get() + anomaly_domain_infos = DomainInformation.objects.filter(domain=domain) - self.assertEqual(anomaly_domain_infos.count(), 1) + self.assertEqual(anomaly_domain_infos.count(), 1) - # This domain should be pretty barebones. Something isnt - # parsing right if we get a lot of data. - anomaly = anomaly_domain_infos.get() - self.assertEqual(anomaly.organization_name, "Flashdog") - self.assertEqual(anomaly.organization_type, None) - self.assertEqual(anomaly.federal_agency, None) - self.assertEqual(anomaly.federal_type, None) + # This domain should be pretty barebones. Something isnt + # parsing right if we get a lot of data. + anomaly = anomaly_domain_infos.get() + self.assertEqual(anomaly.organization_name, "Flashdog") + self.assertEqual(anomaly.organization_type, None) + self.assertEqual(anomaly.federal_agency, None) + self.assertEqual(anomaly.federal_type, None) - # Check for the "system" creator user - Users = User.objects.filter(username="System") - self.assertEqual(Users.count(), 1) - self.assertEqual(anomaly.creator, Users.get()) + # Check for the "system" creator user + Users = User.objects.filter(username="System") + self.assertEqual(Users.count(), 1) + self.assertEqual(anomaly.creator, Users.get()) - domain = Domain.objects.filter(name="fakewebsite2.gov").get() - fakewebsite_domain_infos = DomainInformation.objects.filter(domain=domain) - self.assertEqual(fakewebsite_domain_infos.count(), 1) + domain = Domain.objects.filter(name="fakewebsite2.gov").get() + fakewebsite_domain_infos = DomainInformation.objects.filter(domain=domain) + self.assertEqual(fakewebsite_domain_infos.count(), 1) - fakewebsite = fakewebsite_domain_infos.get() - self.assertEqual(fakewebsite.organization_name, "Fanoodle") - self.assertEqual(fakewebsite.organization_type, "federal") - self.assertEqual(fakewebsite.federal_agency, "Department of Commerce") - self.assertEqual(fakewebsite.federal_type, "executive") + fakewebsite = fakewebsite_domain_infos.get() + self.assertEqual(fakewebsite.organization_name, "Fanoodle") + self.assertEqual(fakewebsite.organization_type, "federal") + self.assertEqual(fakewebsite.federal_agency, "Department of Commerce") + self.assertEqual(fakewebsite.federal_type, "executive") - ao = fakewebsite.authorizing_official + ao = fakewebsite.authorizing_official - self.assertEqual(ao.first_name, "Seline") - self.assertEqual(ao.middle_name, "testmiddle2") - self.assertEqual(ao.last_name, "Tower") - self.assertEqual(ao.email, "stower3@answers.com") - self.assertEqual(ao.phone, "151-539-6028") + self.assertEqual(ao.first_name, "Seline") + self.assertEqual(ao.middle_name, "testmiddle2") + self.assertEqual(ao.last_name, "Tower") + self.assertEqual(ao.email, "stower3@answers.com") + self.assertEqual(ao.phone, "151-539-6028") - # Check for the "system" creator user - Users = User.objects.filter(username="System") - self.assertEqual(Users.count(), 1) - self.assertEqual(anomaly.creator, Users.get()) + # Check for the "system" creator user + Users = User.objects.filter(username="System") + self.assertEqual(Users.count(), 1) + self.assertEqual(anomaly.creator, Users.get()) def test_transfer_transition_domains_to_domains(self): - self.run_load_domains() - self.run_transfer_domains() + with less_console_noise(): + self.run_load_domains() + self.run_transfer_domains() - # Analyze the tables - expected_total_transition_domains = 9 - expected_total_domains = 5 - expected_total_domain_informations = 5 - expected_total_domain_invitations = 8 + # Analyze the tables + expected_total_transition_domains = 9 + expected_total_domains = 5 + expected_total_domain_informations = 5 + expected_total_domain_invitations = 8 - expected_missing_domains = 0 - expected_duplicate_domains = 0 - expected_missing_domain_informations = 0 - expected_missing_domain_invitations = 1 - self.compare_tables( - expected_total_transition_domains, - expected_total_domains, - expected_total_domain_informations, - expected_total_domain_invitations, - expected_missing_domains, - expected_duplicate_domains, - expected_missing_domain_informations, - expected_missing_domain_invitations, - ) + expected_missing_domains = 0 + expected_duplicate_domains = 0 + expected_missing_domain_informations = 0 + expected_missing_domain_invitations = 1 + self.compare_tables( + expected_total_transition_domains, + expected_total_domains, + expected_total_domain_informations, + expected_total_domain_invitations, + expected_missing_domains, + expected_duplicate_domains, + expected_missing_domain_informations, + expected_missing_domain_invitations, + ) def test_logins(self): - # TODO: setup manually instead of calling other scripts - self.run_load_domains() - self.run_transfer_domains() + with less_console_noise(): + # TODO: setup manually instead of calling other scripts + self.run_load_domains() + self.run_transfer_domains() - # Simluate Logins - for invite in DomainInvitation.objects.all(): - # get a user with this email address - user, user_created = User.objects.get_or_create(email=invite.email, username=invite.email) - user.on_each_login() + # Simluate Logins + for invite in DomainInvitation.objects.all(): + # get a user with this email address + user, user_created = User.objects.get_or_create(email=invite.email, username=invite.email) + user.on_each_login() - # Analyze the tables - expected_total_transition_domains = 9 - expected_total_domains = 5 - expected_total_domain_informations = 5 - expected_total_domain_invitations = 8 + # Analyze the tables + expected_total_transition_domains = 9 + expected_total_domains = 5 + expected_total_domain_informations = 5 + expected_total_domain_invitations = 8 - expected_missing_domains = 0 - expected_duplicate_domains = 0 - expected_missing_domain_informations = 0 - expected_missing_domain_invitations = 1 - self.compare_tables( - expected_total_transition_domains, - expected_total_domains, - expected_total_domain_informations, - expected_total_domain_invitations, - expected_missing_domains, - expected_duplicate_domains, - expected_missing_domain_informations, - expected_missing_domain_invitations, - ) + expected_missing_domains = 0 + expected_duplicate_domains = 0 + expected_missing_domain_informations = 0 + expected_missing_domain_invitations = 1 + self.compare_tables( + expected_total_transition_domains, + expected_total_domains, + expected_total_domain_informations, + expected_total_domain_invitations, + expected_missing_domains, + expected_duplicate_domains, + expected_missing_domain_informations, + expected_missing_domain_invitations, + ) @boto3_mocking.patching def test_send_domain_invitations_email(self): diff --git a/src/registrar/tests/test_views.py b/src/registrar/tests/test_views.py index f8373710c..6ab84eb4c 100644 --- a/src/registrar/tests/test_views.py +++ b/src/registrar/tests/test_views.py @@ -159,32 +159,33 @@ class LoggedInTests(TestWithUser): # Given that we are including a subset of items that can be deleted while excluding the rest, # subTest is appropriate here as otherwise we would need many duplicate tests for the same reason. - draft_domain = DraftDomain.objects.create(name="igorville.gov") - for status in DomainApplication.ApplicationStatus: - if status not in [ - DomainApplication.ApplicationStatus.STARTED, - DomainApplication.ApplicationStatus.WITHDRAWN, - ]: - with self.subTest(status=status): - application = DomainApplication.objects.create( - creator=self.user, requested_domain=draft_domain, status=status - ) + with less_console_noise(): + draft_domain = DraftDomain.objects.create(name="igorville.gov") + for status in DomainApplication.ApplicationStatus: + if status not in [ + DomainApplication.ApplicationStatus.STARTED, + DomainApplication.ApplicationStatus.WITHDRAWN, + ]: + with self.subTest(status=status): + application = DomainApplication.objects.create( + creator=self.user, requested_domain=draft_domain, status=status + ) - # Trigger the delete logic - response = self.client.post( - reverse("application-delete", kwargs={"pk": application.pk}), follow=True - ) + # Trigger the delete logic + response = self.client.post( + reverse("application-delete", kwargs={"pk": application.pk}), follow=True + ) - # Check for a 403 error - the end user should not be allowed to do this - self.assertEqual(response.status_code, 403) + # Check for a 403 error - the end user should not be allowed to do this + self.assertEqual(response.status_code, 403) - desired_application = DomainApplication.objects.filter(requested_domain=draft_domain) + desired_application = DomainApplication.objects.filter(requested_domain=draft_domain) - # Make sure the DomainApplication wasn't deleted - self.assertEqual(desired_application.count(), 1) + # Make sure the DomainApplication wasn't deleted + self.assertEqual(desired_application.count(), 1) - # clean up - application.delete() + # clean up + application.delete() def test_home_deletes_domain_application_and_orphans(self): """Tests if delete for DomainApplication deletes orphaned Contact objects""" @@ -329,7 +330,6 @@ class LoggedInTests(TestWithUser): with less_console_noise(): response = self.client.get("/request/", follow=True) - print(response.status_code) self.assertEqual(response.status_code, 403) @@ -2548,112 +2548,118 @@ class TestDomainDetail(TestDomainOverview): It shows as 'DNS needed'""" # At the time of this test's writing, there are 6 UNKNOWN domains inherited # from constructors. Let's reset. - Domain.objects.all().delete() - UserDomainRole.objects.all().delete() - self.domain, _ = Domain.objects.get_or_create(name="igorville.gov") - home_page = self.app.get("/") - self.assertNotContains(home_page, "igorville.gov") - self.role, _ = UserDomainRole.objects.get_or_create( - user=self.user, domain=self.domain, role=UserDomainRole.Roles.MANAGER - ) - home_page = self.app.get("/") - self.assertContains(home_page, "igorville.gov") - igorville = Domain.objects.get(name="igorville.gov") - self.assertEquals(igorville.state, Domain.State.UNKNOWN) - self.assertNotContains(home_page, "Expired") - self.assertContains(home_page, "DNS needed") + with less_console_noise(): + Domain.objects.all().delete() + UserDomainRole.objects.all().delete() + self.domain, _ = Domain.objects.get_or_create(name="igorville.gov") + home_page = self.app.get("/") + self.assertNotContains(home_page, "igorville.gov") + self.role, _ = UserDomainRole.objects.get_or_create( + user=self.user, domain=self.domain, role=UserDomainRole.Roles.MANAGER + ) + home_page = self.app.get("/") + self.assertContains(home_page, "igorville.gov") + igorville = Domain.objects.get(name="igorville.gov") + self.assertEquals(igorville.state, Domain.State.UNKNOWN) + self.assertNotContains(home_page, "Expired") + self.assertContains(home_page, "DNS needed") def test_unknown_domain_does_not_show_as_expired_on_detail_page(self): """An UNKNOWN domain does not show as expired on the detail page. It shows as 'DNS needed'""" # At the time of this test's writing, there are 6 UNKNOWN domains inherited # from constructors. Let's reset. - Domain.objects.all().delete() - UserDomainRole.objects.all().delete() + with less_console_noise(): + Domain.objects.all().delete() + UserDomainRole.objects.all().delete() - self.domain, _ = Domain.objects.get_or_create(name="igorville.gov") - self.domain_information, _ = DomainInformation.objects.get_or_create(creator=self.user, domain=self.domain) - self.role, _ = UserDomainRole.objects.get_or_create( - user=self.user, domain=self.domain, role=UserDomainRole.Roles.MANAGER - ) + self.domain, _ = Domain.objects.get_or_create(name="igorville.gov") + self.domain_information, _ = DomainInformation.objects.get_or_create(creator=self.user, domain=self.domain) + self.role, _ = UserDomainRole.objects.get_or_create( + user=self.user, domain=self.domain, role=UserDomainRole.Roles.MANAGER + ) - home_page = self.app.get("/") - self.assertContains(home_page, "igorville.gov") - igorville = Domain.objects.get(name="igorville.gov") - self.assertEquals(igorville.state, Domain.State.UNKNOWN) - detail_page = home_page.click("Manage", index=0) - self.assertNotContains(detail_page, "Expired") + home_page = self.app.get("/") + self.assertContains(home_page, "igorville.gov") + igorville = Domain.objects.get(name="igorville.gov") + self.assertEquals(igorville.state, Domain.State.UNKNOWN) + detail_page = home_page.click("Manage", index=0) + self.assertNotContains(detail_page, "Expired") - self.assertContains(detail_page, "DNS needed") + self.assertContains(detail_page, "DNS needed") def test_domain_detail_blocked_for_ineligible_user(self): """We could easily duplicate this test for all domain management views, but a single url test should be solid enough since all domain management pages share the same permissions class""" - self.user.status = User.RESTRICTED - self.user.save() - home_page = self.app.get("/") - self.assertContains(home_page, "igorville.gov") with less_console_noise(): + self.user.status = User.RESTRICTED + self.user.save() + home_page = self.app.get("/") + self.assertContains(home_page, "igorville.gov") response = self.client.get(reverse("domain", kwargs={"pk": self.domain.id})) self.assertEqual(response.status_code, 403) def test_domain_detail_allowed_for_on_hold(self): """Test that the domain overview page displays for on hold domain""" - home_page = self.app.get("/") - self.assertContains(home_page, "on-hold.gov") + with less_console_noise(): + home_page = self.app.get("/") + self.assertContains(home_page, "on-hold.gov") - # View domain overview page - detail_page = self.client.get(reverse("domain", kwargs={"pk": self.domain_on_hold.id})) - self.assertNotContains(detail_page, "Edit") + # View domain overview page + detail_page = self.client.get(reverse("domain", kwargs={"pk": self.domain_on_hold.id})) + self.assertNotContains(detail_page, "Edit") def test_domain_detail_see_just_nameserver(self): - home_page = self.app.get("/") - self.assertContains(home_page, "justnameserver.com") + with less_console_noise(): + home_page = self.app.get("/") + self.assertContains(home_page, "justnameserver.com") - # View nameserver on Domain Overview page - detail_page = self.app.get(reverse("domain", kwargs={"pk": self.domain_just_nameserver.id})) + # View nameserver on Domain Overview page + detail_page = self.app.get(reverse("domain", kwargs={"pk": self.domain_just_nameserver.id})) - self.assertContains(detail_page, "justnameserver.com") - self.assertContains(detail_page, "ns1.justnameserver.com") - self.assertContains(detail_page, "ns2.justnameserver.com") + self.assertContains(detail_page, "justnameserver.com") + self.assertContains(detail_page, "ns1.justnameserver.com") + self.assertContains(detail_page, "ns2.justnameserver.com") def test_domain_detail_see_nameserver_and_ip(self): - home_page = self.app.get("/") - self.assertContains(home_page, "nameserverwithip.gov") + with less_console_noise(): + home_page = self.app.get("/") + self.assertContains(home_page, "nameserverwithip.gov") - # View nameserver on Domain Overview page - detail_page = self.app.get(reverse("domain", kwargs={"pk": self.domain_with_ip.id})) + # View nameserver on Domain Overview page + detail_page = self.app.get(reverse("domain", kwargs={"pk": self.domain_with_ip.id})) - self.assertContains(detail_page, "nameserverwithip.gov") + self.assertContains(detail_page, "nameserverwithip.gov") - self.assertContains(detail_page, "ns1.nameserverwithip.gov") - self.assertContains(detail_page, "ns2.nameserverwithip.gov") - self.assertContains(detail_page, "ns3.nameserverwithip.gov") - # Splitting IP addresses bc there is odd whitespace and can't strip text - self.assertContains(detail_page, "(1.2.3.4,") - self.assertContains(detail_page, "2.3.4.5)") + self.assertContains(detail_page, "ns1.nameserverwithip.gov") + self.assertContains(detail_page, "ns2.nameserverwithip.gov") + self.assertContains(detail_page, "ns3.nameserverwithip.gov") + # Splitting IP addresses bc there is odd whitespace and can't strip text + self.assertContains(detail_page, "(1.2.3.4,") + self.assertContains(detail_page, "2.3.4.5)") def test_domain_detail_with_no_information_or_application(self): """Test that domain management page returns 200 and displays error when no domain information or domain application exist""" - # have to use staff user for this test - staff_user = create_user() - # staff_user.save() - self.client.force_login(staff_user) + with less_console_noise(): + # have to use staff user for this test + staff_user = create_user() + # staff_user.save() + self.client.force_login(staff_user) - # need to set the analyst_action and analyst_action_location - # in the session to emulate user clicking Manage Domain - # in the admin interface - session = self.client.session - session["analyst_action"] = "foo" - session["analyst_action_location"] = self.domain_no_information.id - session.save() + # need to set the analyst_action and analyst_action_location + # in the session to emulate user clicking Manage Domain + # in the admin interface + session = self.client.session + session["analyst_action"] = "foo" + session["analyst_action_location"] = self.domain_no_information.id + session.save() - detail_page = self.client.get(reverse("domain", kwargs={"pk": self.domain_no_information.id})) + detail_page = self.client.get(reverse("domain", kwargs={"pk": self.domain_no_information.id})) - self.assertContains(detail_page, "noinformation.gov") - self.assertContains(detail_page, "Domain missing domain information") + self.assertContains(detail_page, "noinformation.gov") + self.assertContains(detail_page, "Domain missing domain information") class TestDomainManagers(TestDomainOverview): @@ -3430,124 +3436,121 @@ class TestDomainContactInformation(TestDomainOverview): class TestDomainSecurityEmail(TestDomainOverview): def test_domain_security_email_existing_security_contact(self): """Can load domain's security email page.""" - self.mockSendPatch = patch("registrar.models.domain.registry.send") - self.mockedSendFunction = self.mockSendPatch.start() - self.mockedSendFunction.side_effect = self.mockSend + with less_console_noise(): + self.mockSendPatch = patch("registrar.models.domain.registry.send") + self.mockedSendFunction = self.mockSendPatch.start() + self.mockedSendFunction.side_effect = self.mockSend - domain_contact, _ = Domain.objects.get_or_create(name="freeman.gov") - # Add current user to this domain - _ = UserDomainRole(user=self.user, domain=domain_contact, role="admin").save() - page = self.client.get(reverse("domain-security-email", kwargs={"pk": domain_contact.id})) + domain_contact, _ = Domain.objects.get_or_create(name="freeman.gov") + # Add current user to this domain + _ = UserDomainRole(user=self.user, domain=domain_contact, role="admin").save() + page = self.client.get(reverse("domain-security-email", kwargs={"pk": domain_contact.id})) - # Loads correctly - self.assertContains(page, "Security email") - self.assertContains(page, "security@mail.gov") - self.mockSendPatch.stop() + # Loads correctly + self.assertContains(page, "Security email") + self.assertContains(page, "security@mail.gov") + self.mockSendPatch.stop() def test_domain_security_email_no_security_contact(self): """Loads a domain with no defined security email. We should not show the default.""" - self.mockSendPatch = patch("registrar.models.domain.registry.send") - self.mockedSendFunction = self.mockSendPatch.start() - self.mockedSendFunction.side_effect = self.mockSend + with less_console_noise(): + self.mockSendPatch = patch("registrar.models.domain.registry.send") + self.mockedSendFunction = self.mockSendPatch.start() + self.mockedSendFunction.side_effect = self.mockSend - page = self.client.get(reverse("domain-security-email", kwargs={"pk": self.domain.id})) + page = self.client.get(reverse("domain-security-email", kwargs={"pk": self.domain.id})) - # Loads correctly - self.assertContains(page, "Security email") - self.assertNotContains(page, "dotgov@cisa.dhs.gov") - self.mockSendPatch.stop() + # Loads correctly + self.assertContains(page, "Security email") + self.assertNotContains(page, "dotgov@cisa.dhs.gov") + self.mockSendPatch.stop() def test_domain_security_email(self): """Can load domain's security email page.""" - page = self.client.get(reverse("domain-security-email", kwargs={"pk": self.domain.id})) - self.assertContains(page, "Security email") + with less_console_noise(): + page = self.client.get(reverse("domain-security-email", kwargs={"pk": self.domain.id})) + self.assertContains(page, "Security email") def test_domain_security_email_form(self): """Adding a security email works. Uses self.app WebTest because we need to interact with forms. """ - security_email_page = self.app.get(reverse("domain-security-email", kwargs={"pk": self.domain.id})) - session_id = self.app.cookies[settings.SESSION_COOKIE_NAME] - security_email_page.form["security_email"] = "mayor@igorville.gov" - self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) - mock_client = MagicMock() - with boto3_mocking.clients.handler_for("sesv2", mock_client): - with less_console_noise(): # swallow log warning message - result = security_email_page.form.submit() - self.assertEqual(result.status_code, 302) - self.assertEqual( - result["Location"], - reverse("domain-security-email", kwargs={"pk": self.domain.id}), - ) + with less_console_noise(): + security_email_page = self.app.get(reverse("domain-security-email", kwargs={"pk": self.domain.id})) + session_id = self.app.cookies[settings.SESSION_COOKIE_NAME] + security_email_page.form["security_email"] = "mayor@igorville.gov" + self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) + mock_client = MagicMock() + with boto3_mocking.clients.handler_for("sesv2", mock_client): + with less_console_noise(): # swallow log warning message + result = security_email_page.form.submit() + self.assertEqual(result.status_code, 302) + self.assertEqual( + result["Location"], + reverse("domain-security-email", kwargs={"pk": self.domain.id}), + ) - self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) - success_page = result.follow() - self.assertContains(success_page, "The security email for this domain has been updated") + self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) + success_page = result.follow() + self.assertContains(success_page, "The security email for this domain has been updated") - def test_security_email_form_messages(self): + def test_domain_security_email_form_messages(self): """ Test against the success and error messages that are defined in the view """ - p = "adminpass" - self.client.login(username="superuser", password=p) - - form_data_registry_error = { - "security_email": "test@failCreate.gov", - } - - form_data_contact_error = { - "security_email": "test@contactError.gov", - } - - form_data_success = { - "security_email": "test@something.gov", - } - - test_cases = [ - ( - "RegistryError", - form_data_registry_error, - str(GenericError(code=GenericErrorCodes.CANNOT_CONTACT_REGISTRY)), - ), - ( - "ContactError", - form_data_contact_error, - str(SecurityEmailError(code=SecurityEmailErrorCodes.BAD_DATA)), - ), - ( - "RegistrySuccess", - form_data_success, - "The security email for this domain has been updated.", - ), - # Add more test cases with different scenarios here - ] - - for test_name, data, expected_message in test_cases: - response = self.client.post( - reverse("domain-security-email", kwargs={"pk": self.domain.id}), - data=data, - follow=True, - ) - - # Check the response status code, content, or any other relevant assertions - self.assertEqual(response.status_code, 200) - - # Check if the expected message tag is set - if test_name == "RegistryError" or test_name == "ContactError": - message_tag = "error" - elif test_name == "RegistrySuccess": - message_tag = "success" - else: - # Handle other cases if needed - message_tag = "info" # Change to the appropriate default - - # Check the message tag - messages = list(response.context["messages"]) - self.assertEqual(len(messages), 1) - message = messages[0] - self.assertEqual(message.tags, message_tag) - self.assertEqual(message.message.strip(), expected_message.strip()) + with less_console_noise(): + p = "adminpass" + self.client.login(username="superuser", password=p) + form_data_registry_error = { + "security_email": "test@failCreate.gov", + } + form_data_contact_error = { + "security_email": "test@contactError.gov", + } + form_data_success = { + "security_email": "test@something.gov", + } + test_cases = [ + ( + "RegistryError", + form_data_registry_error, + str(GenericError(code=GenericErrorCodes.CANNOT_CONTACT_REGISTRY)), + ), + ( + "ContactError", + form_data_contact_error, + str(SecurityEmailError(code=SecurityEmailErrorCodes.BAD_DATA)), + ), + ( + "RegistrySuccess", + form_data_success, + "The security email for this domain has been updated.", + ), + # Add more test cases with different scenarios here + ] + for test_name, data, expected_message in test_cases: + response = self.client.post( + reverse("domain-security-email", kwargs={"pk": self.domain.id}), + data=data, + follow=True, + ) + # Check the response status code, content, or any other relevant assertions + self.assertEqual(response.status_code, 200) + # Check if the expected message tag is set + if test_name == "RegistryError" or test_name == "ContactError": + message_tag = "error" + elif test_name == "RegistrySuccess": + message_tag = "success" + else: + # Handle other cases if needed + message_tag = "info" # Change to the appropriate default + # Check the message tag + messages = list(response.context["messages"]) + self.assertEqual(len(messages), 1) + message = messages[0] + self.assertEqual(message.tags, message_tag) + self.assertEqual(message.message.strip(), expected_message.strip()) def test_domain_overview_blocked_for_ineligible_user(self): """We could easily duplicate this test for all domain management