Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#1458] Update klant from profile form data #669

Merged
merged 1 commit into from
Jun 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 95 additions & 6 deletions src/open_inwoner/accounts/tests/test_profile_views.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import io

from django.test import override_settings
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _

import requests_mock
from django_webtest import WebTest
from PIL import Image
from timeline_logger.models import TimelineLog
from webtest import Upload

Expand All @@ -15,14 +12,15 @@
from open_inwoner.haalcentraal.tests.mixins import HaalCentraalMixin
from open_inwoner.pdc.tests.factories import CategoryFactory
from open_inwoner.utils.logentry import LOG_ACTIONS
from open_inwoner.utils.tests.helpers import create_image_bytes
from open_inwoner.utils.tests.helpers import AssertTimelineLogMixin, create_image_bytes

from ...cms.profile.cms_apps import ProfileApphook
from ...cms.tests import cms_tools
from ...openklant.tests.data import MockAPIReadPatchData
from ...questionnaire.tests.factories import QuestionnaireStepFactory
from ..choices import ContactTypeChoices, LoginTypeChoices
from ..forms import BrpUserForm, UserForm
from .factories import ActionFactory, DocumentFactory, UserFactory
from .factories import ActionFactory, DigidUserFactory, DocumentFactory, UserFactory


@override_settings(ROOT_URLCONF="open_inwoner.cms.tests.urls")
Expand Down Expand Up @@ -193,7 +191,7 @@ def test_expected_message_is_shown_when_all_notifications_disabled(self):


@override_settings(ROOT_URLCONF="open_inwoner.cms.tests.urls")
class EditProfileTests(WebTest):
class EditProfileTests(AssertTimelineLogMixin, WebTest):
def setUp(self):
self.url = reverse("profile:edit")
self.return_url = reverse("profile:detail")
Expand Down Expand Up @@ -435,6 +433,97 @@ def test_image_field_is_not_rendered_when_begeleider_and_digid_login(self):
self.assertNotIn("image", form.fields.keys())
self.assertEqual(response.pyquery("#id_image"), [])

@requests_mock.Mocker()
def test_modify_phone_and_email_updates_klant_api(self, m):
MockAPIReadPatchData.setUpServices()
data = MockAPIReadPatchData().install_mocks(m)

response = self.app.get(self.url, user=data.user)
form = response.forms["profile-edit"]
form["email"] = "new@example.com"
form["phonenumber"] = "01234456789"
form.submit()

# user data tested in other cases

self.assertTrue(data.matchers[0].called)
klant_patch_data = data.matchers[1].request_history[0].json()
self.assertEqual(
klant_patch_data,
{
"emailadres": "new@example.com",
"telefoonnummer": "01234456789",
},
)
self.assertTimelineLog("retrieved klant for BSN-user")
self.assertTimelineLog(
"patched klant from user profile edit with fields: emailadres, telefoonnummer"
)

@requests_mock.Mocker()
def test_modify_phone_updates_klant_api_but_skips_unchanged(self, m):
MockAPIReadPatchData.setUpServices()
data = MockAPIReadPatchData().install_mocks(m)

response = self.app.get(self.url, user=data.user)
form = response.forms["profile-edit"]
form.submit()

# user data tested in other cases

self.assertFalse(data.matchers[0].called)
self.assertFalse(data.matchers[1].called)

@requests_mock.Mocker()
def test_modify_phone_updates_klant_api_but_skip_unchanged_email(self, m):
MockAPIReadPatchData.setUpServices()
data = MockAPIReadPatchData().install_mocks(m)

response = self.app.get(self.url, user=data.user)
form = response.forms["profile-edit"]
form["phonenumber"] = "01234456789"
form.submit()

# user data tested in other cases

self.assertTrue(data.matchers[0].called)
klant_patch_data = data.matchers[1].request_history[0].json()
self.assertEqual(
klant_patch_data,
{
"telefoonnummer": "01234456789",
},
)
self.assertTimelineLog("retrieved klant for BSN-user")
self.assertTimelineLog(
"patched klant from user profile edit with fields: telefoonnummer"
)

@requests_mock.Mocker()
def test_modify_phone_updates_klant_api_but_skip_unchanged_phone(self, m):
MockAPIReadPatchData.setUpServices()
data = MockAPIReadPatchData().install_mocks(m)

response = self.app.get(self.url, user=data.user)
form = response.forms["profile-edit"]
form["email"] = "new@example.com"
form.submit()

# user data tested in other cases

self.assertTrue(data.matchers[0].called)
klant_patch_data = data.matchers[1].request_history[0].json()
self.assertEqual(
klant_patch_data,
{
"emailadres": "new@example.com",
},
)
self.assertTimelineLog("retrieved klant for BSN-user")
self.assertTimelineLog(
"patched klant from user profile edit with fields: emailadres"
)


@requests_mock.Mocker()
@override_settings(ROOT_URLCONF="open_inwoner.cms.tests.urls")
Expand Down
27 changes: 27 additions & 0 deletions src/open_inwoner/accounts/views/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from open_inwoner.utils.mixins import ExportMixin
from open_inwoner.utils.views import CommonPageMixin, LogMixin

from ...openklant.wrap import fetch_klant_for_bsn, patch_klant
from ..forms import BrpUserForm, CategoriesForm, UserForm, UserNotificationsForm
from ..models import Action, User

Expand Down Expand Up @@ -133,10 +134,36 @@ def get_object(self):
def form_valid(self, form):
form.save()

self.update_klant_api({k: form.cleaned_data[k] for k in form.changed_data})

messages.success(self.request, _("Uw wijzigingen zijn opgeslagen"))
self.log_change(self.get_object(), _("profile was modified"))
return HttpResponseRedirect(self.get_success_url())

def update_klant_api(self, user_form_data: dict):
user: User = self.request.user
if not user.bsn or user.login_type != LoginTypeChoices.digid:
return
field_mapping = {
"emailadres": "email",
"telefoonnummer": "phonenumber",
}
update_data = {
api_name: user_form_data[local_name]
for api_name, local_name in field_mapping.items()
if user_form_data.get(local_name)
}
if update_data:
klant = fetch_klant_for_bsn(user.bsn)
if klant:
self.log_system_action("retrieved klant for BSN-user")

klant = patch_klant(klant, update_data)
if klant:
self.log_system_action(
f"patched klant from user profile edit with fields: {', '.join(sorted(update_data.keys()))}"
)

def get_form_class(self):
user = self.request.user
if user.is_digid_and_brp():
Expand Down
40 changes: 40 additions & 0 deletions src/open_inwoner/openklant/tests/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,46 @@ def setUpOASMocks(self, m):
mock_service_oas_get(m, CONTACTMOMENTEN_ROOT, "cmc")


class MockAPIReadPatchData(MockAPIData):
def __init__(self):
self.user = DigidUserFactory(
email="old@example.com",
phonenumber="0100000000",
)

self.klant_old = generate_oas_component(
"kc",
"schemas/Klant",
uuid="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
url=f"{KLANTEN_ROOT}klant/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
emailadres="bad@example.com",
telefoonnummer="",
)
self.klant_updated = generate_oas_component(
"kc",
"schemas/Klant",
uuid="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
url=f"{KLANTEN_ROOT}klant/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
emailadres="good@example.com",
telefoonnummer="0123456789",
)

def install_mocks(self, m) -> "MockAPIReadPatchData":
self.setUpOASMocks(m)
self.matchers = [
m.get(
f"{KLANTEN_ROOT}klanten?subjectNatuurlijkPersoon__inpBsn={self.user.bsn}",
json=paginated_response([self.klant_old]),
),
m.patch(
f"{KLANTEN_ROOT}klant/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
json=self.klant_updated,
status_code=200,
),
]
return self


class MockAPIReadData(MockAPIData):
def __init__(self):
self.user = DigidUserFactory(
Expand Down