diff --git a/src/objecttypes/tests/commands/__init__.py b/src/objecttypes/tests/commands/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/objecttypes/tests/commands/test_setup_configuration.py b/src/objecttypes/tests/commands/test_setup_configuration.py new file mode 100644 index 00000000..40304559 --- /dev/null +++ b/src/objecttypes/tests/commands/test_setup_configuration.py @@ -0,0 +1,86 @@ +import uuid +from io import StringIO + +from django.contrib.sites.models import Site +from django.core.management import CommandError, call_command +from django.test import TestCase, override_settings +from django.urls import reverse + +import requests_mock +from rest_framework import status + +from objecttypes.config.objects import ObjectsAuthStep +from objecttypes.config.site import SiteConfigurationStep + + +@override_settings( + OBJECTTYPES_DOMAIN="objecttypes.example.com", + OBJECTTYPES_ORGANIZATION="ACME", + OBJECTS_OBJECTTYPES_TOKEN="some-random-string", + OBJECTS_OBJECTTYPES_PERSON="Some Person", + OBJECTS_OBJECTTYPES_EMAIL="objects@objects.local", +) +class SetupConfigurationTests(TestCase): + def setUp(self): + super().setUp() + + self.addCleanup(Site.objects.clear_cache) + + @requests_mock.Mocker() + def test_setup_configuration(self, m): + stdout = StringIO() + # mocks + m.get("http://objecttypes.example.com/", status_code=200) + m.get("http://objecttypes.example.com/api/v2/objecttypes", json=[]) + + call_command("setup_configuration", stdout=stdout) + + with self.subTest("Command output"): + command_output = stdout.getvalue().splitlines() + expected_output = [ + f"Configuration will be set up with following steps: [{SiteConfigurationStep()}, " + f"{ObjectsAuthStep()}]", + f"Configuring {SiteConfigurationStep()}...", + f"{SiteConfigurationStep()} is successfully configured", + f"Configuring {ObjectsAuthStep()}...", + f"{ObjectsAuthStep()} is successfully configured", + "Instance configuration completed.", + ] + + self.assertEqual(command_output, expected_output) + + with self.subTest("Site configured correctly"): + site = Site.objects.get_current() + self.assertEqual(site.domain, "objecttypes.example.com") + self.assertEqual(site.name, "Objecttypes ACME") + + with self.subTest("Objects can query Objecttypes API"): + response = self.client.get( + reverse("v2:objecttype-list"), + HTTP_AUTHORIZATION="Token some-random-string", + ) + + self.assertEqual(response.status_code, status.HTTP_200_OK) + + @requests_mock.Mocker() + def test_setup_configuration_selftest_fails(self, m): + m.get("http://objecttypes.example.com/", status_code=200) + m.get("http://objecttypes.example.com/api/v2/objecttypes", status_code=500) + + with self.assertRaisesMessage( + CommandError, + "Configuration test failed with errors: " + "Objects API Authentication Configuration: " + "Could not list objecttypes for the configured token", + ): + call_command("setup_configuration") + + @requests_mock.Mocker() + def test_setup_configuration_without_selftest(self, m): + stdout = StringIO() + + call_command("setup_configuration", no_selftest=True, stdout=stdout) + command_output = stdout.getvalue() + + self.assertEqual(len(m.request_history), 0) + self.assertTrue("Selftest is skipped" in command_output) diff --git a/src/objecttypes/tests/config/__init__.py b/src/objecttypes/tests/config/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/objecttypes/tests/config/test_objects_configuration.py b/src/objecttypes/tests/config/test_objects_configuration.py new file mode 100644 index 00000000..044680c7 --- /dev/null +++ b/src/objecttypes/tests/config/test_objects_configuration.py @@ -0,0 +1,72 @@ +from unittest.mock import patch + +from django.test import TestCase, override_settings + +import requests +import requests_mock +from django_setup_configuration.exceptions import SelfTestFailed + +from objecttypes.config.objects import ObjectsAuthStep +from objecttypes.token.models import TokenAuth + + +@override_settings( + OBJECTS_OBJECTTYPES_TOKEN="some-random-string", + OBJECTS_OBJECTTYPES_PERSON="Some Person", + OBJECTS_OBJECTTYPES_EMAIL="objects@objects.local", +) +class ObjectsConfigurationTests(TestCase): + def test_configure(self): + configuration = ObjectsAuthStep() + + configuration.configure() + + token_auth = TokenAuth.objects.get(token="some-random-string") + self.assertEqual(token_auth.contact_person, "Some Person") + self.assertEqual(token_auth.email, "objects@objects.local") + + @requests_mock.Mocker() + @patch( + "objecttypes.config.objects.build_absolute_url", + return_value="http://testserver/objecttypes", + ) + def test_selftest_ok(self, m, *mocks): + configuration = ObjectsAuthStep() + configuration.configure() + m.get("http://testserver/objecttypes", json=[]) + + configuration.test_configuration() + + self.assertEqual(m.last_request.url, "http://testserver/objecttypes") + self.assertEqual(m.last_request.method, "GET") + + @requests_mock.Mocker() + @patch( + "objecttypes.config.objects.build_absolute_url", + return_value="http://testserver/objecttypes", + ) + def test_selftest_fail(self, m, *mocks): + configuration = ObjectsAuthStep() + configuration.configure() + + mock_kwargs = ( + {"exc": requests.ConnectTimeout}, + {"exc": requests.ConnectionError}, + {"status_code": 404}, + {"status_code": 403}, + {"status_code": 500}, + ) + for mock_config in mock_kwargs: + with self.subTest(mock=mock_config): + m.get("http://testserver/objecttypes", **mock_config) + + with self.assertRaises(SelfTestFailed): + configuration.test_configuration() + + def test_is_configured(self): + configuration = ObjectsAuthStep() + self.assertFalse(configuration.is_configured()) + + configuration.configure() + + self.assertTrue(configuration.is_configured()) diff --git a/src/objecttypes/tests/config/test_site_configuration.py b/src/objecttypes/tests/config/test_site_configuration.py new file mode 100644 index 00000000..4dccee19 --- /dev/null +++ b/src/objecttypes/tests/config/test_site_configuration.py @@ -0,0 +1,66 @@ +from django.contrib.sites.models import Site +from django.test import TestCase, override_settings + +import requests +import requests_mock +from django_setup_configuration.exceptions import SelfTestFailed + +from objecttypes.config.site import SiteConfigurationStep + + +@override_settings( + OBJECTTYPES_DOMAIN="localhost:8000", + OBJECTTYPES_ORGANIZATION="ACME", +) +class SiteConfigurationTests(TestCase): + def setUp(self): + super().setUp() + + self.addCleanup(Site.objects.clear_cache) + + def test_set_domain(self): + configuration = SiteConfigurationStep() + configuration.configure() + + site = Site.objects.get_current() + self.assertEqual(site.domain, "localhost:8000") + self.assertEqual(site.name, "Objecttypes ACME") + + @requests_mock.Mocker() + def test_configuration_check_ok(self, m): + m.get("http://localhost:8000/", status_code=200) + configuration = SiteConfigurationStep() + configuration.configure() + + configuration.test_configuration() + + self.assertEqual(m.last_request.url, "http://localhost:8000/") + self.assertEqual(m.last_request.method, "GET") + + @requests_mock.Mocker() + def test_configuration_check_failures(self, m): + configuration = SiteConfigurationStep() + configuration.configure() + + mock_kwargs = ( + {"exc": requests.ConnectTimeout}, + {"exc": requests.ConnectionError}, + {"status_code": 404}, + {"status_code": 403}, + {"status_code": 500}, + ) + for mock_config in mock_kwargs: + with self.subTest(mock=mock_config): + m.get("http://localhost:8000/", **mock_config) + + with self.assertRaises(SelfTestFailed): + configuration.test_configuration() + + def test_is_configured(self): + configuration = SiteConfigurationStep() + + self.assertFalse(configuration.is_configured()) + + configuration.configure() + + self.assertTrue(configuration.is_configured())