From 4eb53b80496eea30c89e66dd9d174c5d93313d95 Mon Sep 17 00:00:00 2001 From: vasileios Date: Thu, 13 Apr 2023 15:34:14 +0200 Subject: [PATCH 1/2] [#1364] Added django outgoing requests library --- requirements/base.in | 1 + requirements/base.txt | 4 + requirements/ci.txt | 6 + requirements/dev.txt | 6 + src/log_outgoing_requests/__init__.py | 0 src/log_outgoing_requests/admin.py | 48 ------ src/log_outgoing_requests/apps.py | 10 -- src/log_outgoing_requests/formatters.py | 30 ---- src/log_outgoing_requests/handlers.py | 44 ------ src/log_outgoing_requests/log_requests.py | 36 ----- .../migrations/0001_initial.py | 122 --------------- .../0002_alter_outgoingrequestslog_url.py | 24 --- .../migrations/0003_auto_20230321_0724.py | 33 ---- .../migrations/__init__.py | 0 src/log_outgoing_requests/models.py | 101 ------------- src/log_outgoing_requests/tests/__init__.py | 0 .../tests/test_logging.py | 141 ------------------ src/open_inwoner/conf/base.py | 1 - .../haalcentraal/tests/test_logging.py | 34 +++++ .../openzaak/tests/test_logging.py | 47 ++++++ 20 files changed, 98 insertions(+), 590 deletions(-) delete mode 100644 src/log_outgoing_requests/__init__.py delete mode 100644 src/log_outgoing_requests/admin.py delete mode 100644 src/log_outgoing_requests/apps.py delete mode 100644 src/log_outgoing_requests/formatters.py delete mode 100644 src/log_outgoing_requests/handlers.py delete mode 100644 src/log_outgoing_requests/log_requests.py delete mode 100644 src/log_outgoing_requests/migrations/0001_initial.py delete mode 100644 src/log_outgoing_requests/migrations/0002_alter_outgoingrequestslog_url.py delete mode 100644 src/log_outgoing_requests/migrations/0003_auto_20230321_0724.py delete mode 100644 src/log_outgoing_requests/migrations/__init__.py delete mode 100644 src/log_outgoing_requests/models.py delete mode 100644 src/log_outgoing_requests/tests/__init__.py delete mode 100644 src/log_outgoing_requests/tests/test_logging.py create mode 100644 src/open_inwoner/haalcentraal/tests/test_logging.py create mode 100644 src/open_inwoner/openzaak/tests/test_logging.py diff --git a/requirements/base.in b/requirements/base.in index df39cea20f..844918505a 100644 --- a/requirements/base.in +++ b/requirements/base.in @@ -48,6 +48,7 @@ django-htmx playwright django-yubin django-image-cropping +django-log-outgoing-requests # API libraries djangorestframework diff --git a/requirements/base.txt b/requirements/base.txt index e6e1814a64..03fa678783 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -86,6 +86,7 @@ django==3.2.15 # django-htmx # django-import-export # django-localflavor + # django-log-outgoing-requests # django-open-forms-client # django-otp # django-phonenumber-field @@ -167,6 +168,8 @@ django-js-asset==1.2.2 # django-mptt django-localflavor==3.1 # via -r requirements/base.in +django-log-outgoing-requests==0.1.0 + # via -r requirements/base.in django-mptt==0.13.4 # via django-filer django-open-forms-client==0.2.3 @@ -385,6 +388,7 @@ reportlab==3.6.12 # svglib requests==2.26.0 # via + # django-log-outgoing-requests # django-open-forms-client # django-rosetta # gemma-zds-client diff --git a/requirements/ci.txt b/requirements/ci.txt index 68887c6f62..a88e4541c4 100644 --- a/requirements/ci.txt +++ b/requirements/ci.txt @@ -145,6 +145,7 @@ django==3.2.15 # django-htmx # django-import-export # django-localflavor + # django-log-outgoing-requests # django-open-forms-client # django-otp # django-phonenumber-field @@ -275,6 +276,10 @@ django-localflavor==3.1 # via # -c requirements/base.txt # -r requirements/base.txt +django-log-outgoing-requests==0.1.0 + # via + # -c requirements/base.txt + # -r requirements/base.txt django-mptt==0.13.4 # via # -c requirements/base.txt @@ -718,6 +723,7 @@ requests==2.26.0 # via # -c requirements/base.txt # -r requirements/base.txt + # django-log-outgoing-requests # django-open-forms-client # django-rosetta # gemma-zds-client diff --git a/requirements/dev.txt b/requirements/dev.txt index 85e1afc152..1a1521e436 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -170,6 +170,7 @@ django==3.2.15 # django-htmx # django-import-export # django-localflavor + # django-log-outgoing-requests # django-open-forms-client # django-otp # django-phonenumber-field @@ -304,6 +305,10 @@ django-localflavor==3.1 # via # -c requirements/ci.txt # -r requirements/ci.txt +django-log-outgoing-requests==0.1.0 + # via + # -c requirements/ci.txt + # -r requirements/ci.txt django-mptt==0.13.4 # via # -c requirements/ci.txt @@ -814,6 +819,7 @@ requests==2.26.0 # -c requirements/ci.txt # -r requirements/ci.txt # ddt-api-calls + # django-log-outgoing-requests # django-open-forms-client # django-rosetta # gemma-zds-client diff --git a/src/log_outgoing_requests/__init__.py b/src/log_outgoing_requests/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/log_outgoing_requests/admin.py b/src/log_outgoing_requests/admin.py deleted file mode 100644 index fdc9531548..0000000000 --- a/src/log_outgoing_requests/admin.py +++ /dev/null @@ -1,48 +0,0 @@ -from django.contrib import admin -from django.utils.translation import gettext as _ - -from .models import OutgoingRequestsLog - - -@admin.register(OutgoingRequestsLog) -class OutgoingRequestsLogAdmin(admin.ModelAdmin): - fields = ( - "url", - "hostname", - "query_params", - "params", - "status_code", - "method", - "response_ms", - "timestamp", - "req_content_type", - "res_content_type", - "req_headers", - "res_headers", - "trace", - ) - readonly_fields = fields - list_display = ( - "hostname", - "url", - "params", - "status_code", - "method", - "response_ms", - "timestamp", - ) - list_filter = ("method", "status_code", "hostname") - search_fields = ("url", "params", "hostname") - date_hierarchy = "timestamp" - show_full_result_count = False - - def has_add_permission(self, request): - return False - - def has_change_permission(self, request, obj=None): - return False - - def query_params(self, obj): - return obj.query_params - - query_params.short_description = _("Query parameters") diff --git a/src/log_outgoing_requests/apps.py b/src/log_outgoing_requests/apps.py deleted file mode 100644 index dadea7879b..0000000000 --- a/src/log_outgoing_requests/apps.py +++ /dev/null @@ -1,10 +0,0 @@ -from django.apps import AppConfig - - -class LogOutgoingRequestsConfig(AppConfig): - name = "log_outgoing_requests" - - def ready(self): - from .log_requests import install_outgoing_requests_logging - - install_outgoing_requests_logging() diff --git a/src/log_outgoing_requests/formatters.py b/src/log_outgoing_requests/formatters.py deleted file mode 100644 index b12eae1154..0000000000 --- a/src/log_outgoing_requests/formatters.py +++ /dev/null @@ -1,30 +0,0 @@ -import logging -import textwrap - - -class HttpFormatter(logging.Formatter): - def _formatHeaders(self, d): - return "\n".join(f"{k}: {v}" for k, v in d.items()) - - def formatMessage(self, record): - result = super().formatMessage(record) - if record.name == "requests": - result += textwrap.dedent( - """ - ---------------- request ---------------- - {req.method} {req.url} - {reqhdrs} - - ---------------- response ---------------- - {res.status_code} {res.reason} {res.url} - {reshdrs} - - """ - ).format( - req=record.req, - res=record.res, - reqhdrs=self._formatHeaders(record.req.headers), - reshdrs=self._formatHeaders(record.res.headers), - ) - - return result diff --git a/src/log_outgoing_requests/handlers.py b/src/log_outgoing_requests/handlers.py deleted file mode 100644 index 631f14761a..0000000000 --- a/src/log_outgoing_requests/handlers.py +++ /dev/null @@ -1,44 +0,0 @@ -import logging -import traceback -from urllib.parse import urlparse - -from django.conf import settings - - -class DatabaseOutgoingRequestsHandler(logging.Handler): - def emit(self, record): - if settings.LOG_OUTGOING_REQUESTS_DB_SAVE: - from .models import OutgoingRequestsLog - - trace = None - - # save only the requests coming from the library requests - if record and record.getMessage() == "Outgoing request": - safe_req_headers = record.req.headers.copy() - - if "Authorization" in safe_req_headers: - safe_req_headers["Authorization"] = "***hidden***" - - if record.exc_info: - trace = traceback.format_exc() - - parsed_url = urlparse(record.req.url) - kwargs = { - "url": record.req.url, - "hostname": parsed_url.hostname, - "params": parsed_url.params, - "status_code": record.res.status_code, - "method": record.req.method, - "req_content_type": record.req.headers.get("Content-Type", ""), - "res_content_type": record.res.headers.get("Content-Type", ""), - "timestamp": record.requested_at, - "response_ms": int(record.res.elapsed.total_seconds() * 1000), - "req_headers": self.format_headers(safe_req_headers), - "res_headers": self.format_headers(record.res.headers), - "trace": trace, - } - - OutgoingRequestsLog.objects.create(**kwargs) - - def format_headers(self, headers): - return "\n".join(f"{k}: {v}" for k, v in headers.items()) diff --git a/src/log_outgoing_requests/log_requests.py b/src/log_outgoing_requests/log_requests.py deleted file mode 100644 index bac831275e..0000000000 --- a/src/log_outgoing_requests/log_requests.py +++ /dev/null @@ -1,36 +0,0 @@ -import logging - -from django.utils import timezone -from django.utils.translation import ugettext_lazy as _ - -from requests import Session - -logger = logging.getLogger("requests") - - -def hook_requests_logging(response, *args, **kwargs): - """ - A hook for requests library in order to add extra data to the logs - """ - extra = {"requested_at": timezone.now(), "req": response.request, "res": response} - logger.debug("Outgoing request", extra=extra) - - -def install_outgoing_requests_logging(): - """ - Log all outgoing requests which are made by the library requests during a session. - """ - - if hasattr(Session, "_original_request"): - logger.debug( - "Session is already patched OR has an ``_original_request`` attribute." - ) - return - - Session._original_request = Session.request - - def new_request(self, *args, **kwargs): - self.hooks["response"].append(hook_requests_logging) - return self._original_request(*args, **kwargs) - - Session.request = new_request diff --git a/src/log_outgoing_requests/migrations/0001_initial.py b/src/log_outgoing_requests/migrations/0001_initial.py deleted file mode 100644 index 11edcc0d07..0000000000 --- a/src/log_outgoing_requests/migrations/0001_initial.py +++ /dev/null @@ -1,122 +0,0 @@ -# Generated by Django 3.2.15 on 2023-03-15 06:41 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [] - - operations = [ - migrations.CreateModel( - name="OutgoingRequestsLog", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "url", - models.URLField( - blank=True, - default="", - help_text="The url of the outgoing request.", - verbose_name="URL", - ), - ), - ( - "hostname", - models.CharField( - blank=True, - default="", - help_text="The hostname part of the url.", - max_length=255, - verbose_name="Hostname", - ), - ), - ( - "params", - models.TextField( - blank=True, - help_text="The parameters (if they exist).", - verbose_name="Parameters", - ), - ), - ( - "status_code", - models.PositiveIntegerField( - blank=True, - help_text="The status code of the response.", - null=True, - verbose_name="Status code", - ), - ), - ( - "method", - models.CharField( - blank=True, - default="", - help_text="The type of request method.", - max_length=10, - verbose_name="Method", - ), - ), - ( - "req_content_type", - models.CharField( - blank=True, - default="", - help_text="The content type of the request.", - max_length=50, - verbose_name="Request content type", - ), - ), - ( - "res_content_type", - models.CharField( - blank=True, - default="", - help_text="The content type of the response.", - max_length=50, - verbose_name="Response content type", - ), - ), - ( - "response_ms", - models.PositiveIntegerField( - blank=True, - default=0, - help_text="This is the response time in ms.", - verbose_name="Response in ms", - ), - ), - ( - "timestamp", - models.DateTimeField( - help_text="This is the date and time the API call was made.", - verbose_name="Timestamp", - ), - ), - ( - "trace", - models.TextField( - blank=True, - help_text="Text providing information in case of request failure.", - null=True, - verbose_name="Trace", - ), - ), - ], - options={ - "verbose_name": "Outgoing Requests Log", - "verbose_name_plural": "Outgoing Requests Logs", - }, - ), - ] diff --git a/src/log_outgoing_requests/migrations/0002_alter_outgoingrequestslog_url.py b/src/log_outgoing_requests/migrations/0002_alter_outgoingrequestslog_url.py deleted file mode 100644 index 48589c9775..0000000000 --- a/src/log_outgoing_requests/migrations/0002_alter_outgoingrequestslog_url.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 3.2.15 on 2023-03-20 15:06 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("log_outgoing_requests", "0001_initial"), - ] - - operations = [ - migrations.AlterField( - model_name="outgoingrequestslog", - name="url", - field=models.URLField( - blank=True, - default="", - help_text="The url of the outgoing request.", - max_length=1000, - verbose_name="URL", - ), - ), - ] diff --git a/src/log_outgoing_requests/migrations/0003_auto_20230321_0724.py b/src/log_outgoing_requests/migrations/0003_auto_20230321_0724.py deleted file mode 100644 index 673313a1e8..0000000000 --- a/src/log_outgoing_requests/migrations/0003_auto_20230321_0724.py +++ /dev/null @@ -1,33 +0,0 @@ -# Generated by Django 3.2.15 on 2023-03-21 06:24 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("log_outgoing_requests", "0002_alter_outgoingrequestslog_url"), - ] - - operations = [ - migrations.AddField( - model_name="outgoingrequestslog", - name="req_headers", - field=models.TextField( - blank=True, - help_text="The request headers.", - null=True, - verbose_name="Request headers", - ), - ), - migrations.AddField( - model_name="outgoingrequestslog", - name="res_headers", - field=models.TextField( - blank=True, - help_text="The response headers.", - null=True, - verbose_name="Response headers", - ), - ), - ] diff --git a/src/log_outgoing_requests/migrations/__init__.py b/src/log_outgoing_requests/migrations/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/log_outgoing_requests/models.py b/src/log_outgoing_requests/models.py deleted file mode 100644 index 215e481a5c..0000000000 --- a/src/log_outgoing_requests/models.py +++ /dev/null @@ -1,101 +0,0 @@ -from urllib.parse import urlparse - -from django.db import models -from django.utils.functional import cached_property -from django.utils.translation import gettext_lazy as _ - - -class OutgoingRequestsLog(models.Model): - url = models.URLField( - verbose_name=_("URL"), - max_length=1000, - blank=True, - default="", - help_text=_("The url of the outgoing request."), - ) - - # hostname is added so we can filter on it in the admin page - hostname = models.CharField( - verbose_name=_("Hostname"), - max_length=255, - default="", - blank=True, - help_text=_("The hostname part of the url."), - ) - params = models.TextField( - verbose_name=_("Parameters"), - blank=True, - help_text=_("The parameters (if they exist)."), - ) - status_code = models.PositiveIntegerField( - verbose_name=_("Status code"), - null=True, - blank=True, - help_text=_("The status code of the response."), - ) - method = models.CharField( - verbose_name=_("Method"), - max_length=10, - default="", - blank=True, - help_text=_("The type of request method."), - ) - req_content_type = models.CharField( - verbose_name=_("Request content type"), - max_length=50, - default="", - blank=True, - help_text=_("The content type of the request."), - ) - res_content_type = models.CharField( - verbose_name=_("Response content type"), - max_length=50, - default="", - blank=True, - help_text=_("The content type of the response."), - ) - req_headers = models.TextField( - verbose_name=_("Request headers"), - blank=True, - null=True, - help_text=_("The request headers."), - ) - res_headers = models.TextField( - verbose_name=_("Response headers"), - blank=True, - null=True, - help_text=_("The response headers."), - ) - response_ms = models.PositiveIntegerField( - verbose_name=_("Response in ms"), - default=0, - blank=True, - help_text=_("This is the response time in ms."), - ) - timestamp = models.DateTimeField( - verbose_name=_("Timestamp"), - help_text=_("This is the date and time the API call was made."), - ) - trace = models.TextField( - verbose_name=_("Trace"), - blank=True, - null=True, - help_text=_("Text providing information in case of request failure."), - ) - - class Meta: - verbose_name = _("Outgoing Requests Log") - verbose_name_plural = _("Outgoing Requests Logs") - - def __str__(self): - return ("{hostname} at {date}").format( - hostname=self.hostname, date=self.timestamp - ) - - @cached_property - def url_parsed(self): - return urlparse(self.url) - - @property - def query_params(self): - return self.url_parsed.query diff --git a/src/log_outgoing_requests/tests/__init__.py b/src/log_outgoing_requests/tests/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/log_outgoing_requests/tests/test_logging.py b/src/log_outgoing_requests/tests/test_logging.py deleted file mode 100644 index 2bd094b059..0000000000 --- a/src/log_outgoing_requests/tests/test_logging.py +++ /dev/null @@ -1,141 +0,0 @@ -from django.test import TestCase, override_settings - -import requests -import requests_mock -from freezegun import freeze_time - -from ..models import OutgoingRequestsLog - - -@requests_mock.Mocker() -@freeze_time("2021-10-18 13:00:00") -class OutgoingRequestsLoggingTests(TestCase): - def _setUpMocks(self, m): - m.get( - "http://example.com/some-path?version=2.0", - status_code=200, - content=b"some content", - ) - - @override_settings(LOG_OUTGOING_REQUESTS_DB_SAVE=True) - def test_outgoing_requests_are_logged(self, m): - self._setUpMocks(m) - - with self.assertLogs("requests", level="DEBUG") as logs: - requests.get("http://example.com/some-path?version=2.0") - - self.assertEqual(logs.output, ["DEBUG:requests:Outgoing request"]) - self.assertEqual(logs.records[0].name, "requests") - self.assertEqual(logs.records[0].getMessage(), "Outgoing request") - self.assertEqual(logs.records[0].levelname, "DEBUG") - - @override_settings(LOG_OUTGOING_REQUESTS_DB_SAVE=True) - def test_expected_data_is_saved_when_saving_enabled(self, m): - methods = [ - ("GET", requests.get, m.get), - ("POST", requests.post, m.post), - ("PUT", requests.put, m.put), - ("PATCH", requests.patch, m.patch), - ("DELETE", requests.delete, m.delete), - ("HEAD", requests.head, m.head), - ] - - for method, func, mocked in methods: - with self.subTest(): - mocked( - "http://example.com/some-path?version=2.0", - status_code=200, - json={"test": "data"}, - request_headers={ - "Authorization": "test", - "Content-Type": "text/html", - }, - headers={ - "Date": "Tue, 21 Mar 2023 15:24:08 GMT", - "Content-Type": "application/json", - }, - ) - expected_req_headers = ( - "User-Agent: python-requests/2.26.0\n" - "Accept-Encoding: gzip, deflate, br\n" - "Accept: */*\n" - "Connection: keep-alive\n" - "Authorization: ***hidden***\n" - "Content-Type: text/html" - ) - if method not in ["HEAD", "GET"]: - expected_req_headers += "\nContent-Length: 0" - - response = func( - "http://example.com/some-path?version=2.0", - headers={"Authorization": "test", "Content-Type": "text/html"}, - ) - - request_log = OutgoingRequestsLog.objects.last() - - self.assertEqual( - request_log.url, "http://example.com/some-path?version=2.0" - ) - self.assertEqual(request_log.hostname, "example.com") - self.assertEqual(request_log.params, "") - self.assertEqual(request_log.query_params, "version=2.0") - self.assertEqual(response.status_code, 200) - self.assertEqual(request_log.method, method) - self.assertEqual(request_log.req_content_type, "text/html") - self.assertEqual(request_log.res_content_type, "application/json") - self.assertEqual(request_log.response_ms, 0) - self.assertEqual(request_log.req_headers, expected_req_headers) - self.assertEqual( - request_log.res_headers, - "Date: Tue, 21 Mar 2023 15:24:08 GMT\nContent-Type: application/json", - ) - self.assertEqual( - request_log.timestamp.strftime("%Y-%m-%d %H:%M:%S"), - "2021-10-18 13:00:00", - ) - self.assertIsNone(request_log.trace) - - @override_settings(LOG_OUTGOING_REQUESTS_DB_SAVE=True) - def test_authorization_header_is_hidden(self, m): - self._setUpMocks(m) - - requests.get( - "http://example.com/some-path?version=2.0", - headers={"Authorization": "test"}, - ) - log = OutgoingRequestsLog.objects.get() - - self.assertIn("Authorization: ***hidden***", log.req_headers) - - @override_settings(LOG_OUTGOING_REQUESTS_DB_SAVE=False) - def test_data_is_not_saved_when_saving_disabled(self, m): - self._setUpMocks(m) - - with self.assertLogs("requests", level="DEBUG") as logs: - requests.get("http://example.com/some-path?version=2.0") - - self.assertEqual(logs.output, ["DEBUG:requests:Outgoing request"]) - self.assertEqual(logs.records[0].name, "requests") - self.assertEqual(logs.records[0].getMessage(), "Outgoing request") - self.assertEqual(logs.records[0].levelname, "DEBUG") - self.assertFalse(OutgoingRequestsLog.objects.exists()) - - @override_settings(LOG_OUTGOING_REQUESTS_DB_SAVE=False) - def test_outgoing_requests_are_logged_when_saving_disabled(self, m): - self._setUpMocks(m) - - with self.assertLogs("requests", level="DEBUG") as logs: - requests.get("http://example.com/some-path?version=2.0") - - self.assertEqual(logs.output, ["DEBUG:requests:Outgoing request"]) - self.assertEqual(logs.records[0].name, "requests") - self.assertEqual(logs.records[0].getMessage(), "Outgoing request") - self.assertEqual(logs.records[0].levelname, "DEBUG") - - @override_settings(LOG_OUTGOING_REQUESTS_DB_SAVE=False) - def test_request_data_is_not_saved_when_saving_disabled(self, m): - self._setUpMocks(m) - - requests.get("http://example.com/some-path?version=2.0") - - self.assertFalse(OutgoingRequestsLog.objects.exists()) diff --git a/src/open_inwoner/conf/base.py b/src/open_inwoner/conf/base.py index 75715351ca..221fc7d3b5 100644 --- a/src/open_inwoner/conf/base.py +++ b/src/open_inwoner/conf/base.py @@ -4,7 +4,6 @@ from django.urls import reverse_lazy import sentry_sdk - from log_outgoing_requests.formatters import HttpFormatter from .utils import config, get_sentry_integrations diff --git a/src/open_inwoner/haalcentraal/tests/test_logging.py b/src/open_inwoner/haalcentraal/tests/test_logging.py new file mode 100644 index 0000000000..b1699d263d --- /dev/null +++ b/src/open_inwoner/haalcentraal/tests/test_logging.py @@ -0,0 +1,34 @@ +from django.test import TestCase + +import requests_mock +from freezegun import freeze_time +from log_outgoing_requests.models import OutgoingRequestsLog + +from open_inwoner.accounts.choices import LoginTypeChoices +from open_inwoner.accounts.tests.factories import UserFactory +from open_inwoner.utils.test import ClearCachesMixin + +from .mixins import HaalCentraalMixin + + +@freeze_time("2021-10-18 13:00:00") +@requests_mock.Mocker() +class TestPreSaveSignal(ClearCachesMixin, HaalCentraalMixin, TestCase): + def test_outgoing_requests_are_logged_and_saved(self, m): + self._setUpMocks_v_2(m) + self._setUpService() + + self.assertFalse(OutgoingRequestsLog.objects.exists()) + + user = UserFactory( + first_name="", last_name="", login_type=LoginTypeChoices.digid + ) + user.bsn = "999993847" + + with self.assertLogs() as captured: + user.save() + + logs_messages = [record.getMessage() for record in captured.records] + + self.assertIn("Outgoing request", logs_messages) + self.assertEqual(OutgoingRequestsLog.objects.count(), 2) diff --git a/src/open_inwoner/openzaak/tests/test_logging.py b/src/open_inwoner/openzaak/tests/test_logging.py new file mode 100644 index 0000000000..fddb85fd0a --- /dev/null +++ b/src/open_inwoner/openzaak/tests/test_logging.py @@ -0,0 +1,47 @@ +from django.test import TestCase + +import requests_mock +from log_outgoing_requests.models import OutgoingRequestsLog +from zgw_consumers.constants import APITypes +from zgw_consumers.test import generate_oas_component, mock_service_oas_get + +from open_inwoner.openzaak.cases import fetch_single_case + +from ...utils.test import ClearCachesMixin +from ..models import OpenZaakConfig +from .factories import ServiceFactory +from .shared import ZAKEN_ROOT + + +@requests_mock.Mocker() +class TestFetchSpecificCase(ClearCachesMixin, TestCase): + @classmethod + def setUpTestData(cls): + cls.zaak_service = ServiceFactory(api_root=ZAKEN_ROOT, api_type=APITypes.zrc) + cls.config = OpenZaakConfig.get_solo() + cls.config.zaak_service = cls.zaak_service + cls.config.save() + + cls.zaak = generate_oas_component( + "zrc", + "schemas/Zaak", + url=f"{ZAKEN_ROOT}zaken/d8bbdeb7-770f-4ca9-b1ea-77b4730bf67d", + identificatie="ZAAK-2022-0000000024", + omschrijving="Zaak naar aanleiding van ingezonden formulier", + startdatum="2022-01-02", + einddatum=None, + ) + + def test_outgoing_requests_are_logged_and_saved(self, m): + mock_service_oas_get(m, ZAKEN_ROOT, "zrc") + m.get(self.zaak["url"], json=self.zaak) + + self.assertFalse(OutgoingRequestsLog.objects.exists()) + + with self.assertLogs() as captured: + fetch_single_case("d8bbdeb7-770f-4ca9-b1ea-77b4730bf67d") + + logs_messages = [record.getMessage() for record in captured.records] + + self.assertIn("Outgoing request", logs_messages) + self.assertEqual(OutgoingRequestsLog.objects.count(), 2) From c44a7ab8f2585ac80926f3ca898d22c981e24382 Mon Sep 17 00:00:00 2001 From: vasileios Date: Tue, 18 Apr 2023 10:00:20 +0200 Subject: [PATCH 2/2] [#1364] Added django log outgoing requests library --- src/open_inwoner/haalcentraal/tests/test_logging.py | 5 ++++- src/open_inwoner/openzaak/tests/test_logging.py | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/open_inwoner/haalcentraal/tests/test_logging.py b/src/open_inwoner/haalcentraal/tests/test_logging.py index b1699d263d..12c676825d 100644 --- a/src/open_inwoner/haalcentraal/tests/test_logging.py +++ b/src/open_inwoner/haalcentraal/tests/test_logging.py @@ -29,6 +29,9 @@ def test_outgoing_requests_are_logged_and_saved(self, m): user.save() logs_messages = [record.getMessage() for record in captured.records] + saved_logs = OutgoingRequestsLog.objects.filter( + url="https://personen/api/brp/personen" + ) self.assertIn("Outgoing request", logs_messages) - self.assertEqual(OutgoingRequestsLog.objects.count(), 2) + self.assertTrue(saved_logs.exists()) diff --git a/src/open_inwoner/openzaak/tests/test_logging.py b/src/open_inwoner/openzaak/tests/test_logging.py index fddb85fd0a..28ee0a8d42 100644 --- a/src/open_inwoner/openzaak/tests/test_logging.py +++ b/src/open_inwoner/openzaak/tests/test_logging.py @@ -42,6 +42,7 @@ def test_outgoing_requests_are_logged_and_saved(self, m): fetch_single_case("d8bbdeb7-770f-4ca9-b1ea-77b4730bf67d") logs_messages = [record.getMessage() for record in captured.records] + saved_logs = OutgoingRequestsLog.objects.filter(url=self.zaak["url"]) self.assertIn("Outgoing request", logs_messages) - self.assertEqual(OutgoingRequestsLog.objects.count(), 2) + self.assertTrue(saved_logs.exists())