Best Python code snippet using lisa_python
test_user.py
Source:test_user.py
1from unittest.mock import Mock, patch2import pytest3from django.core.exceptions import ObjectDoesNotExist4from django.urls import reverse5from django.utils import timezone6from rest_framework import status7from rest_framework.response import Response8from rest_framework.test import APIClient9from apps.base.constants import ADMIN_PERMISSIONS, EDITOR_PERMISSIONS10from apps.base.models import UserNotificationPolicy11from apps.user_management.models.user import default_working_hours12from common.constants.role import Role13@pytest.mark.django_db14def test_update_user(15 make_organization,16 make_team,17 make_user_for_organization,18 make_token_for_organization,19 make_user_auth_headers,20):21 organization = make_organization()22 admin = make_user_for_organization(organization)23 team = make_team(organization)24 team.users.add(admin)25 _, token = make_token_for_organization(organization)26 client = APIClient()27 url = reverse("api-internal:user-detail", kwargs={"pk": admin.public_primary_key})28 data = {29 "unverified_phone_number": "+79123456789",30 "current_team": team.public_primary_key,31 }32 response = client.put(url, data, format="json", **make_user_auth_headers(admin, token))33 assert response.status_code == status.HTTP_200_OK34 assert response.json()["unverified_phone_number"] == data["unverified_phone_number"]35 assert response.json()["current_team"] == data["current_team"]36@pytest.mark.django_db37def test_update_user_cant_change_email_and_username(38 make_organization,39 make_user_for_organization,40 make_token_for_organization,41 make_user_auth_headers,42):43 organization = make_organization()44 admin = make_user_for_organization(organization)45 _, token = make_token_for_organization(organization)46 client = APIClient()47 url = reverse("api-internal:user-detail", kwargs={"pk": admin.public_primary_key})48 phone_number = "+79123456789"49 data = {50 "unverified_phone_number": phone_number,51 "email": "test@amixr.io",52 "username": "bob",53 }54 expected_response = {55 "pk": admin.public_primary_key,56 "organization": {"pk": organization.public_primary_key, "name": organization.org_title},57 "current_team": None,58 "email": admin.email,59 "hide_phone_number": False,60 "username": admin.username,61 "role": admin.role,62 "timezone": None,63 "working_hours": default_working_hours(),64 "unverified_phone_number": phone_number,65 "verified_phone_number": None,66 "telegram_configuration": None,67 "messaging_backends": {68 "TESTONLY": {69 "user": admin.username,70 }71 },72 "cloud_connection_status": 0,73 "permissions": ADMIN_PERMISSIONS,74 "notification_chain_verbal": {"default": "", "important": ""},75 "slack_user_identity": None,76 "avatar": admin.avatar_url,77 }78 response = client.put(url, data, format="json", **make_user_auth_headers(admin, token))79 assert response.status_code == status.HTTP_200_OK80 assert response.json() == expected_response81@pytest.mark.django_db82def test_list_users(83 make_organization,84 make_user_for_organization,85 make_token_for_organization,86 make_user_auth_headers,87):88 organization = make_organization()89 admin = make_user_for_organization(organization)90 editor = make_user_for_organization(organization, role=Role.EDITOR)91 _, token = make_token_for_organization(organization)92 client = APIClient()93 url = reverse("api-internal:user-list")94 expected_payload = {95 "count": 2,96 "next": None,97 "previous": None,98 "results": [99 {100 "pk": admin.public_primary_key,101 "organization": {"pk": organization.public_primary_key, "name": organization.org_title},102 "current_team": None,103 "email": admin.email,104 "hide_phone_number": False,105 "username": admin.username,106 "role": admin.role,107 "timezone": None,108 "working_hours": default_working_hours(),109 "unverified_phone_number": None,110 "verified_phone_number": None,111 "telegram_configuration": None,112 "messaging_backends": {113 "TESTONLY": {114 "user": admin.username,115 }116 },117 "permissions": ADMIN_PERMISSIONS,118 "notification_chain_verbal": {"default": "", "important": ""},119 "slack_user_identity": None,120 "avatar": admin.avatar_url,121 "cloud_connection_status": 0,122 },123 {124 "pk": editor.public_primary_key,125 "organization": {"pk": organization.public_primary_key, "name": organization.org_title},126 "current_team": None,127 "email": editor.email,128 "hide_phone_number": False,129 "username": editor.username,130 "role": editor.role,131 "timezone": None,132 "working_hours": default_working_hours(),133 "unverified_phone_number": None,134 "verified_phone_number": None,135 "telegram_configuration": None,136 "messaging_backends": {137 "TESTONLY": {138 "user": editor.username,139 }140 },141 "permissions": EDITOR_PERMISSIONS,142 "notification_chain_verbal": {"default": "", "important": ""},143 "slack_user_identity": None,144 "avatar": editor.avatar_url,145 "cloud_connection_status": 0,146 },147 ],148 }149 response = client.get(url, format="json", **make_user_auth_headers(admin, token))150 assert response.status_code == status.HTTP_200_OK151 assert response.json() == expected_payload152@pytest.mark.django_db153def test_notification_chain_verbal(154 make_organization,155 make_user_for_organization,156 make_token_for_organization,157 make_user_auth_headers,158 make_user_notification_policy,159):160 organization = make_organization()161 admin = make_user_for_organization(organization)162 _, token = make_token_for_organization(organization)163 data_for_creation = [164 {"step": UserNotificationPolicy.Step.NOTIFY, "notify_by": UserNotificationPolicy.NotificationChannel.SLACK},165 {"step": UserNotificationPolicy.Step.WAIT, "wait_delay": timezone.timedelta(minutes=5)},166 {167 "step": UserNotificationPolicy.Step.NOTIFY,168 "notify_by": UserNotificationPolicy.NotificationChannel.PHONE_CALL,169 },170 {"step": UserNotificationPolicy.Step.WAIT, "wait_delay": None},171 {"step": UserNotificationPolicy.Step.NOTIFY, "notify_by": UserNotificationPolicy.NotificationChannel.TELEGRAM},172 {"step": None},173 {174 "step": UserNotificationPolicy.Step.NOTIFY,175 "notify_by": UserNotificationPolicy.NotificationChannel.SLACK,176 "important": True,177 },178 {"step": UserNotificationPolicy.Step.WAIT, "wait_delay": timezone.timedelta(minutes=5), "important": True},179 {180 "step": UserNotificationPolicy.Step.NOTIFY,181 "notify_by": UserNotificationPolicy.NotificationChannel.PHONE_CALL,182 "important": True,183 },184 {"step": UserNotificationPolicy.Step.WAIT, "wait_delay": None, "important": True},185 {186 "step": UserNotificationPolicy.Step.NOTIFY,187 "notify_by": UserNotificationPolicy.NotificationChannel.TELEGRAM,188 "important": True,189 },190 ]191 for data in data_for_creation:192 make_user_notification_policy(admin, **data)193 client = APIClient()194 url = reverse("api-internal:user-detail", kwargs={"pk": admin.public_primary_key})195 expected_notification_chain = {196 "default": "Slack - 5 min - \U0000260E - Telegram",197 "important": "Slack - 5 min - \U0000260E - Telegram",198 }199 response = client.get(url, format="json", **make_user_auth_headers(admin, token))200 assert response.status_code == status.HTTP_200_OK201 assert response.json()["notification_chain_verbal"] == expected_notification_chain202@pytest.mark.django_db203@pytest.mark.parametrize(204 "role,expected_status",205 [206 (Role.ADMIN, status.HTTP_200_OK),207 (Role.EDITOR, status.HTTP_200_OK),208 (Role.VIEWER, status.HTTP_403_FORBIDDEN),209 ],210)211def test_user_update_self_permissions(212 make_organization,213 make_user_for_organization,214 make_token_for_organization,215 make_user_auth_headers,216 role,217 expected_status,218):219 organization = make_organization()220 tester = make_user_for_organization(organization, role=role)221 _, token = make_token_for_organization(organization)222 client = APIClient()223 url = reverse("api-internal:user-detail", kwargs={"pk": tester.public_primary_key})224 with patch(225 "apps.api.views.user.UserView.update",226 return_value=Response(227 status=status.HTTP_200_OK,228 ),229 ):230 response = client.put(url, format="json", **make_user_auth_headers(tester, token))231 assert response.status_code == expected_status232@pytest.mark.django_db233@pytest.mark.parametrize(234 "role,expected_status",235 [236 (Role.ADMIN, status.HTTP_200_OK),237 (Role.EDITOR, status.HTTP_403_FORBIDDEN),238 (Role.VIEWER, status.HTTP_403_FORBIDDEN),239 ],240)241def test_user_update_other_permissions(242 make_organization,243 make_user_for_organization,244 make_token_for_organization,245 make_user_auth_headers,246 role,247 expected_status,248):249 organization = make_organization()250 admin = make_user_for_organization(organization)251 tester = make_user_for_organization(organization, role=role)252 _, token = make_token_for_organization(organization)253 client = APIClient()254 url = reverse("api-internal:user-detail", kwargs={"pk": admin.public_primary_key})255 data = {"unverified_phone_number": "+79123456789"}256 response = client.put(url, data, format="json", **make_user_auth_headers(tester, token))257 assert response.status_code == expected_status258@pytest.mark.django_db259@pytest.mark.parametrize(260 "role,expected_status",261 [262 (Role.ADMIN, status.HTTP_200_OK),263 (Role.EDITOR, status.HTTP_200_OK),264 (Role.VIEWER, status.HTTP_403_FORBIDDEN),265 ],266)267def test_user_list_permissions(268 make_organization,269 make_user_for_organization,270 make_token_for_organization,271 make_user_auth_headers,272 role,273 expected_status,274):275 organization = make_organization()276 tester = make_user_for_organization(organization, role=role)277 _, token = make_token_for_organization(organization)278 client = APIClient()279 url = reverse("api-internal:user-list")280 with patch(281 "apps.api.views.user.UserView.list",282 return_value=Response(283 status=status.HTTP_200_OK,284 ),285 ):286 response = client.get(url, format="json", **make_user_auth_headers(tester, token))287 assert response.status_code == expected_status288@pytest.mark.django_db289@pytest.mark.parametrize(290 "role,expected_status",291 [292 (Role.ADMIN, status.HTTP_200_OK),293 (Role.EDITOR, status.HTTP_200_OK),294 (Role.VIEWER, status.HTTP_200_OK),295 ],296)297def test_user_detail_self_permissions(298 make_organization,299 make_user_for_organization,300 make_token_for_organization,301 make_user_auth_headers,302 role,303 expected_status,304):305 organization = make_organization()306 tester = make_user_for_organization(organization, role=role)307 _, token = make_token_for_organization(organization)308 client = APIClient()309 url = reverse("api-internal:user-detail", kwargs={"pk": tester.public_primary_key})310 with patch(311 "apps.api.views.user.UserView.list",312 return_value=Response(313 status=status.HTTP_200_OK,314 ),315 ):316 response = client.get(url, format="json", **make_user_auth_headers(tester, token))317 assert response.status_code == expected_status318@pytest.mark.django_db319@pytest.mark.parametrize(320 "role,expected_status",321 [322 (Role.ADMIN, status.HTTP_200_OK),323 (Role.EDITOR, status.HTTP_403_FORBIDDEN),324 (Role.VIEWER, status.HTTP_403_FORBIDDEN),325 ],326)327def test_user_detail_other_permissions(328 make_organization,329 make_user_for_organization,330 make_token_for_organization,331 make_user_auth_headers,332 role,333 expected_status,334):335 organization = make_organization()336 admin = make_user_for_organization(organization)337 tester = make_user_for_organization(organization, role=role)338 _, token = make_token_for_organization(organization)339 client = APIClient()340 url = reverse("api-internal:user-detail", kwargs={"pk": admin.public_primary_key})341 response = client.get(url, format="json", **make_user_auth_headers(tester, token))342 assert response.status_code == expected_status343@pytest.mark.django_db344@pytest.mark.parametrize(345 "role,expected_status",346 [347 (Role.ADMIN, status.HTTP_200_OK),348 (Role.EDITOR, status.HTTP_200_OK),349 (Role.VIEWER, status.HTTP_403_FORBIDDEN),350 ],351)352def test_user_get_own_verification_code(353 make_organization,354 make_user_for_organization,355 make_token_for_organization,356 make_user_auth_headers,357 role,358 expected_status,359):360 organization = make_organization()361 tester = make_user_for_organization(organization, role=role)362 _, token = make_token_for_organization(organization)363 client = APIClient()364 url = reverse("api-internal:user-get-verification-code", kwargs={"pk": tester.public_primary_key})365 with patch(366 "apps.api.views.user.UserView.get_verification_code",367 return_value=Response(368 status=status.HTTP_200_OK,369 ),370 ):371 response = client.get(url, format="json", **make_user_auth_headers(tester, token))372 assert response.status_code == expected_status373@pytest.mark.django_db374@pytest.mark.parametrize(375 "role,expected_status",376 [377 (Role.ADMIN, status.HTTP_200_OK),378 (Role.EDITOR, status.HTTP_403_FORBIDDEN),379 (Role.VIEWER, status.HTTP_403_FORBIDDEN),380 ],381)382def test_user_get_other_verification_code(383 make_organization,384 make_user_for_organization,385 make_token_for_organization,386 make_user_auth_headers,387 role,388 expected_status,389):390 organization = make_organization()391 admin = make_user_for_organization(organization)392 tester = make_user_for_organization(organization, role=role)393 _, token = make_token_for_organization(organization)394 client = APIClient()395 url = reverse("api-internal:user-get-verification-code", kwargs={"pk": admin.public_primary_key})396 with patch("apps.twilioapp.phone_manager.PhoneManager.send_verification_code", return_value=Mock()):397 response = client.get(url, format="json", **make_user_auth_headers(tester, token))398 assert response.status_code == expected_status399@pytest.mark.django_db400@pytest.mark.parametrize(401 "role,expected_status",402 [403 (Role.ADMIN, status.HTTP_200_OK),404 (Role.EDITOR, status.HTTP_200_OK),405 (Role.VIEWER, status.HTTP_403_FORBIDDEN),406 ],407)408def test_user_verify_own_phone(409 make_organization,410 make_user_for_organization,411 make_token_for_organization,412 make_user_auth_headers,413 role,414 expected_status,415):416 organization = make_organization()417 tester = make_user_for_organization(organization, role=role)418 _, token = make_token_for_organization(organization)419 client = APIClient()420 url = reverse("api-internal:user-verify-number", kwargs={"pk": tester.public_primary_key})421 with patch(422 "apps.api.views.user.UserView.verify_number",423 return_value=Response(424 status=status.HTTP_200_OK,425 ),426 ):427 response = client.put(url, format="json", **make_user_auth_headers(tester, token))428 assert response.status_code == expected_status429"""430Tests below are outdated431"""432@pytest.mark.django_db433@pytest.mark.parametrize(434 "role,expected_status",435 [436 (Role.ADMIN, status.HTTP_200_OK),437 (Role.EDITOR, status.HTTP_403_FORBIDDEN),438 (Role.VIEWER, status.HTTP_403_FORBIDDEN),439 ],440)441def test_user_verify_another_phone(442 make_organization,443 make_user_for_organization,444 make_token_for_organization,445 make_user_auth_headers,446 role,447 expected_status,448):449 organization = make_organization()450 tester = make_user_for_organization(organization, role=role)451 other_user = make_user_for_organization(organization, role=Role.EDITOR)452 _, token = make_token_for_organization(organization)453 client = APIClient()454 url = reverse("api-internal:user-verify-number", kwargs={"pk": other_user.public_primary_key})455 with patch("apps.twilioapp.phone_manager.PhoneManager.verify_phone_number", return_value=(True, None)):456 response = client.put(f"{url}?token=12345", format="json", **make_user_auth_headers(tester, token))457 assert response.status_code == expected_status458@pytest.mark.django_db459@pytest.mark.parametrize(460 "role,expected_status",461 [462 (Role.ADMIN, status.HTTP_200_OK),463 (Role.EDITOR, status.HTTP_200_OK),464 (Role.VIEWER, status.HTTP_403_FORBIDDEN),465 ],466)467def test_user_get_own_telegram_verification_code(468 make_organization,469 make_user_for_organization,470 make_token_for_organization,471 make_user_auth_headers,472 role,473 expected_status,474):475 organization = make_organization()476 tester = make_user_for_organization(organization, role=role)477 _, token = make_token_for_organization(organization)478 client = APIClient()479 url = reverse("api-internal:user-get-telegram-verification-code", kwargs={"pk": tester.public_primary_key})480 response = client.get(url, format="json", **make_user_auth_headers(tester, token))481 assert response.status_code == expected_status482@pytest.mark.django_db483@pytest.mark.parametrize(484 "role,expected_status",485 [486 (Role.ADMIN, status.HTTP_200_OK),487 (Role.EDITOR, status.HTTP_403_FORBIDDEN),488 (Role.VIEWER, status.HTTP_403_FORBIDDEN),489 ],490)491def test_user_get_another_telegram_verification_code(492 make_organization,493 make_user_for_organization,494 make_token_for_organization,495 make_user_auth_headers,496 role,497 expected_status,498):499 organization = make_organization()500 tester = make_user_for_organization(organization, role=role)501 other_user = make_user_for_organization(organization, role=Role.EDITOR)502 _, token = make_token_for_organization(organization)503 client = APIClient()504 url = reverse("api-internal:user-get-telegram-verification-code", kwargs={"pk": other_user.public_primary_key})505 response = client.get(url, format="json", **make_user_auth_headers(tester, token))506 assert response.status_code == expected_status507@pytest.mark.django_db508def test_admin_can_update_user(509 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers510):511 organization = make_organization()512 tester = make_user_for_organization(organization, role=Role.ADMIN)513 other_user = make_user_for_organization(organization, role=Role.EDITOR)514 _, token = make_token_for_organization(organization)515 client = APIClient()516 data = {517 "email": "test@amixr.io",518 "role": Role.ADMIN,519 "username": "updated_test_username",520 "unverified_phone_number": "+1234567890",521 "slack_login": "",522 }523 url = reverse("api-internal:user-detail", kwargs={"pk": other_user.public_primary_key})524 response = client.put(url, format="json", data=data, **make_user_auth_headers(tester, token))525 assert response.status_code == status.HTTP_200_OK526@pytest.mark.django_db527def test_admin_can_update_himself(528 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers529):530 organization = make_organization()531 admin = make_user_for_organization(organization, role=Role.ADMIN)532 _, token = make_token_for_organization(organization)533 client = APIClient()534 data = {535 "email": "test@amixr.io",536 "role": Role.ADMIN,537 "username": "updated_test_username",538 "unverified_phone_number": "+1234567890",539 "slack_login": "",540 }541 url = reverse("api-internal:user-detail", kwargs={"pk": admin.public_primary_key})542 response = client.put(url, format="json", data=data, **make_user_auth_headers(admin, token))543 assert response.status_code == status.HTTP_200_OK544@pytest.mark.django_db545def test_admin_can_list_users(546 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers547):548 organization = make_organization()549 admin = make_user_for_organization(organization, role=Role.ADMIN)550 _, token = make_token_for_organization(organization)551 client = APIClient()552 url = reverse("api-internal:user-list")553 response = client.get(url, format="json", **make_user_auth_headers(admin, token))554 assert response.status_code == status.HTTP_200_OK555@pytest.mark.django_db556def test_admin_can_detail_users(557 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers558):559 organization = make_organization()560 admin = make_user_for_organization(organization, role=Role.ADMIN)561 editor = make_user_for_organization(organization, role=Role.EDITOR)562 _, token = make_token_for_organization(organization)563 client = APIClient()564 url = reverse("api-internal:user-detail", kwargs={"pk": editor.public_primary_key})565 response = client.get(url, format="json", **make_user_auth_headers(admin, token))566 assert response.status_code == status.HTTP_200_OK567@patch("apps.twilioapp.phone_manager.PhoneManager.send_verification_code", return_value=Mock())568@pytest.mark.django_db569def test_admin_can_get_own_verification_code(570 mock_verification_start,571 make_organization,572 make_user_for_organization,573 make_token_for_organization,574 make_user_auth_headers,575):576 organization = make_organization()577 admin = make_user_for_organization(organization, role=Role.ADMIN)578 _, token = make_token_for_organization(organization)579 client = APIClient()580 url = reverse("api-internal:user-get-verification-code", kwargs={"pk": admin.public_primary_key})581 response = client.get(url, format="json", **make_user_auth_headers(admin, token))582 assert response.status_code == status.HTTP_200_OK583@patch("apps.twilioapp.phone_manager.PhoneManager.send_verification_code", return_value=Mock())584@pytest.mark.django_db585def test_admin_can_get_another_user_verification_code(586 mock_verification_start,587 make_organization,588 make_user_for_organization,589 make_token_for_organization,590 make_user_auth_headers,591):592 organization = make_organization()593 admin = make_user_for_organization(organization, role=Role.ADMIN)594 editor = make_user_for_organization(organization, role=Role.EDITOR)595 _, token = make_token_for_organization(organization)596 client = APIClient()597 url = reverse("api-internal:user-get-verification-code", kwargs={"pk": editor.public_primary_key})598 response = client.get(url, format="json", **make_user_auth_headers(admin, token))599 assert response.status_code == status.HTTP_200_OK600@patch("apps.twilioapp.phone_manager.PhoneManager.verify_phone_number", return_value=(True, None))601@pytest.mark.django_db602def test_admin_can_verify_own_phone(603 mocked_verification_check,604 make_organization,605 make_user_for_organization,606 make_token_for_organization,607 make_user_auth_headers,608):609 organization = make_organization()610 admin = make_user_for_organization(organization, role=Role.ADMIN)611 _, token = make_token_for_organization(organization)612 client = APIClient()613 url = reverse("api-internal:user-verify-number", kwargs={"pk": admin.public_primary_key})614 response = client.put(f"{url}?token=12345", format="json", **make_user_auth_headers(admin, token))615 assert response.status_code == status.HTTP_200_OK616@patch("apps.twilioapp.phone_manager.PhoneManager.verify_phone_number", return_value=(True, None))617@pytest.mark.django_db618def test_admin_can_verify_another_user_phone(619 mocked_verification_check,620 make_organization,621 make_user_for_organization,622 make_token_for_organization,623 make_user_auth_headers,624):625 organization = make_organization()626 admin = make_user_for_organization(organization, role=Role.ADMIN)627 editor = make_user_for_organization(organization, role=Role.EDITOR)628 _, token = make_token_for_organization(organization)629 client = APIClient()630 url = reverse("api-internal:user-verify-number", kwargs={"pk": editor.public_primary_key})631 response = client.put(f"{url}?token=12345", format="json", **make_user_auth_headers(admin, token))632 assert response.status_code == status.HTTP_200_OK633@pytest.mark.django_db634def test_admin_can_get_own_telegram_verification_code(635 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers636):637 organization = make_organization()638 admin = make_user_for_organization(organization, role=Role.ADMIN)639 _, token = make_token_for_organization(organization)640 client = APIClient()641 url = reverse("api-internal:user-get-telegram-verification-code", kwargs={"pk": admin.public_primary_key})642 response = client.get(url, format="json", **make_user_auth_headers(admin, token))643 assert response.status_code == status.HTTP_200_OK644@pytest.mark.django_db645def test_admin_can_get_another_user_telegram_verification_code(646 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers647):648 organization = make_organization()649 admin = make_user_for_organization(organization, role=Role.ADMIN)650 editor = make_user_for_organization(organization, role=Role.EDITOR)651 _, token = make_token_for_organization(organization)652 client = APIClient()653 url = reverse("api-internal:user-get-telegram-verification-code", kwargs={"pk": editor.public_primary_key})654 response = client.get(url, format="json", **make_user_auth_headers(admin, token))655 assert response.status_code == status.HTTP_200_OK656@pytest.mark.django_db657def test_admin_can_get_another_user_backend_verification_code(658 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers659):660 organization = make_organization()661 admin = make_user_for_organization(organization, role=Role.ADMIN)662 editor = make_user_for_organization(organization, role=Role.EDITOR)663 _, token = make_token_for_organization(organization)664 client = APIClient()665 url = (666 reverse("api-internal:user-get-backend-verification-code", kwargs={"pk": editor.public_primary_key})667 + "?backend=TESTONLY"668 )669 response = client.get(url, format="json", **make_user_auth_headers(admin, token))670 assert response.status_code == status.HTTP_200_OK671@pytest.mark.django_db672def test_admin_can_unlink_another_user_backend_account(673 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers674):675 organization = make_organization()676 admin = make_user_for_organization(organization, role=Role.ADMIN)677 editor = make_user_for_organization(organization, role=Role.EDITOR)678 _, token = make_token_for_organization(organization)679 client = APIClient()680 url = reverse("api-internal:user-unlink-backend", kwargs={"pk": editor.public_primary_key}) + "?backend=TESTONLY"681 response = client.post(url, format="json", **make_user_auth_headers(admin, token))682 assert response.status_code == status.HTTP_200_OK683@pytest.mark.django_db684def test_admin_can_unlink_another_user_slack_account(685 make_organization_with_slack_team_identity,686 make_user_for_organization,687 make_user_with_slack_user_identity,688 make_token_for_organization,689 make_user_auth_headers,690):691 organization, slack_team_identity = make_organization_with_slack_team_identity()692 admin = make_user_for_organization(organization, role=Role.ADMIN)693 editor, slack_user_identity_1 = make_user_with_slack_user_identity(694 slack_team_identity, organization, slack_id="user_1", role=Role.EDITOR695 )696 _, token = make_token_for_organization(organization)697 client = APIClient()698 url = reverse("api-internal:user-unlink-slack", kwargs={"pk": editor.public_primary_key})699 response = client.post(url, format="json", **make_user_auth_headers(admin, token))700 assert response.status_code == status.HTTP_200_OK701 editor.refresh_from_db()702 assert editor.slack_user_identity is None703"""Test user permissions"""704@pytest.mark.django_db705def test_user_cant_update_user(706 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers707):708 organization = make_organization()709 first_user = make_user_for_organization(organization, role=Role.EDITOR)710 second_user = make_user_for_organization(organization, role=Role.EDITOR)711 _, token = make_token_for_organization(organization)712 client = APIClient()713 data = {714 "email": "test@amixr.io",715 "role": Role.ADMIN,716 "username": "updated_test_username",717 "unverified_phone_number": "+1234567890",718 "slack_login": "",719 }720 url = reverse("api-internal:user-detail", kwargs={"pk": first_user.public_primary_key})721 response = client.put(url, format="json", data=data, **make_user_auth_headers(second_user, token))722 assert response.status_code == status.HTTP_403_FORBIDDEN723@pytest.mark.django_db724def test_user_can_update_themself(725 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers726):727 organization = make_organization()728 user = make_user_for_organization(organization, role=Role.EDITOR)729 _, token = make_token_for_organization(organization)730 client = APIClient()731 data = {732 "email": "test@amixr.io",733 "role": Role.EDITOR,734 "username": "updated_test_username",735 "unverified_phone_number": "+1234567890",736 "slack_login": "",737 }738 url = reverse("api-internal:user-detail", kwargs={"pk": user.public_primary_key})739 response = client.put(url, format="json", data=data, **make_user_auth_headers(user, token))740 assert response.status_code == status.HTTP_200_OK741@pytest.mark.django_db742def test_user_can_list_users(743 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers744):745 organization = make_organization()746 editor = make_user_for_organization(organization, role=Role.EDITOR)747 _, token = make_token_for_organization(organization)748 client = APIClient()749 url = reverse("api-internal:user-list")750 response = client.get(url, format="json", **make_user_auth_headers(editor, token))751 assert response.status_code == status.HTTP_200_OK752@pytest.mark.django_db753def test_user_can_detail_users(754 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers755):756 organization = make_organization()757 admin = make_user_for_organization(organization, role=Role.ADMIN)758 editor = make_user_for_organization(organization, role=Role.EDITOR)759 _, token = make_token_for_organization(organization)760 client = APIClient()761 url = reverse("api-internal:user-detail", kwargs={"pk": admin.public_primary_key})762 response = client.get(url, format="json", **make_user_auth_headers(editor, token))763 assert response.status_code == status.HTTP_403_FORBIDDEN764@patch("apps.twilioapp.phone_manager.PhoneManager.send_verification_code", return_value=Mock())765@pytest.mark.django_db766def test_user_can_get_own_verification_code(767 mock_verification_start,768 make_organization,769 make_user_for_organization,770 make_token_for_organization,771 make_user_auth_headers,772):773 organization = make_organization()774 user = make_user_for_organization(organization, role=Role.EDITOR)775 _, token = make_token_for_organization(organization)776 client = APIClient()777 url = reverse("api-internal:user-get-verification-code", kwargs={"pk": user.public_primary_key})778 response = client.get(f"{url}", format="json", **make_user_auth_headers(user, token))779 assert response.status_code == status.HTTP_200_OK780@patch("apps.twilioapp.phone_manager.PhoneManager.send_verification_code", return_value=Mock())781@pytest.mark.django_db782def test_user_cant_get_another_user_verification_code(783 mock_verification_start,784 make_organization,785 make_user_for_organization,786 make_token_for_organization,787 make_user_auth_headers,788):789 organization = make_organization()790 first_user = make_user_for_organization(organization, role=Role.EDITOR)791 second_user = make_user_for_organization(organization, role=Role.EDITOR)792 _, token = make_token_for_organization(organization)793 client = APIClient()794 url = reverse("api-internal:user-get-verification-code", kwargs={"pk": first_user.public_primary_key})795 response = client.get(f"{url}", format="json", **make_user_auth_headers(second_user, token))796 assert response.status_code == status.HTTP_403_FORBIDDEN797@patch("apps.twilioapp.phone_manager.PhoneManager.verify_phone_number", return_value=(True, None))798@pytest.mark.django_db799def test_user_can_verify_own_phone(800 mocked_verification_check,801 make_organization,802 make_user_for_organization,803 make_token_for_organization,804 make_user_auth_headers,805):806 organization = make_organization()807 user = make_user_for_organization(organization, role=Role.EDITOR)808 _, token = make_token_for_organization(organization)809 client = APIClient()810 url = reverse("api-internal:user-verify-number", kwargs={"pk": user.public_primary_key})811 response = client.put(f"{url}?token=12345", format="json", **make_user_auth_headers(user, token))812 assert response.status_code == status.HTTP_200_OK813@patch("apps.twilioapp.phone_manager.PhoneManager.verify_phone_number", return_value=(True, None))814@pytest.mark.django_db815def test_user_cant_verify_another_user_phone(816 mocked_verification_check,817 make_organization,818 make_user_for_organization,819 make_token_for_organization,820 make_user_auth_headers,821):822 organization = make_organization()823 first_user = make_user_for_organization(organization, role=Role.EDITOR)824 second_user = make_user_for_organization(organization, role=Role.EDITOR)825 _, token = make_token_for_organization(organization)826 client = APIClient()827 url = reverse("api-internal:user-verify-number", kwargs={"pk": first_user.public_primary_key})828 response = client.put(f"{url}?token=12345", format="json", **make_user_auth_headers(second_user, token))829 assert response.status_code == status.HTTP_403_FORBIDDEN830@pytest.mark.django_db831def test_user_can_get_own_telegram_verification_code(832 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers833):834 organization = make_organization()835 user = make_user_for_organization(organization, role=Role.EDITOR)836 _, token = make_token_for_organization(organization)837 client = APIClient()838 url = reverse("api-internal:user-get-telegram-verification-code", kwargs={"pk": user.public_primary_key})839 response = client.get(f"{url}", format="json", **make_user_auth_headers(user, token))840 assert response.status_code == status.HTTP_200_OK841@pytest.mark.django_db842def test_user_cant_get_another_user_telegram_verification_code(843 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers844):845 organization = make_organization()846 first_user = make_user_for_organization(organization, role=Role.EDITOR)847 second_user = make_user_for_organization(organization, role=Role.EDITOR)848 _, token = make_token_for_organization(organization)849 client = APIClient()850 url = reverse("api-internal:user-get-telegram-verification-code", kwargs={"pk": first_user.public_primary_key})851 response = client.get(f"{url}", format="json", **make_user_auth_headers(second_user, token))852 assert response.status_code == status.HTTP_403_FORBIDDEN853@pytest.mark.django_db854def test_user_can_get_own_backend_verification_code(855 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers856):857 organization = make_organization()858 user = make_user_for_organization(organization, role=Role.EDITOR)859 _, token = make_token_for_organization(organization)860 client = APIClient()861 url = (862 reverse("api-internal:user-get-backend-verification-code", kwargs={"pk": user.public_primary_key})863 + "?backend=TESTONLY"864 )865 with patch(866 "apps.base.tests.messaging_backend.TestOnlyBackend.generate_user_verification_code",867 return_value="the-code",868 ) as mock_generate_code:869 response = client.get(f"{url}", format="json", **make_user_auth_headers(user, token))870 assert response.status_code == status.HTTP_200_OK871 assert response.json() == "the-code"872 mock_generate_code.assert_called_once_with(user)873@pytest.mark.django_db874def test_user_cant_get_another_user_backend_verification_code(875 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers876):877 organization = make_organization()878 first_user = make_user_for_organization(organization, role=Role.EDITOR)879 second_user = make_user_for_organization(organization, role=Role.EDITOR)880 _, token = make_token_for_organization(organization)881 client = APIClient()882 url = (883 reverse("api-internal:user-get-backend-verification-code", kwargs={"pk": first_user.public_primary_key})884 + "?backend=TESTONLY"885 )886 response = client.get(f"{url}", format="json", **make_user_auth_headers(second_user, token))887 assert response.status_code == status.HTTP_403_FORBIDDEN888@pytest.mark.django_db889def test_user_can_unlink_own_slack_account(890 make_organization_with_slack_team_identity,891 make_user_with_slack_user_identity,892 make_token_for_organization,893 make_user_auth_headers,894):895 organization, slack_team_identity = make_organization_with_slack_team_identity()896 user, slack_user_identity_1 = make_user_with_slack_user_identity(897 slack_team_identity, organization, slack_id="user_1", role=Role.EDITOR898 )899 _, token = make_token_for_organization(organization)900 client = APIClient()901 url = reverse("api-internal:user-unlink-slack", kwargs={"pk": user.public_primary_key})902 response = client.post(url, format="json", **make_user_auth_headers(user, token))903 assert response.status_code == status.HTTP_200_OK904 user.refresh_from_db()905 assert user.slack_user_identity is None906@pytest.mark.django_db907def test_user_can_unlink_backend_own_account(908 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers909):910 organization = make_organization()911 user = make_user_for_organization(organization, role=Role.EDITOR)912 _, token = make_token_for_organization(organization)913 client = APIClient()914 url = reverse("api-internal:user-unlink-backend", kwargs={"pk": user.public_primary_key}) + "?backend=TESTONLY"915 response = client.post(f"{url}", format="json", **make_user_auth_headers(user, token))916 assert response.status_code == status.HTTP_200_OK917@pytest.mark.django_db918def test_user_unlink_backend_invalid_backend_id(919 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers920):921 organization = make_organization()922 user = make_user_for_organization(organization, role=Role.EDITOR)923 _, token = make_token_for_organization(organization)924 client = APIClient()925 url = reverse("api-internal:user-unlink-backend", kwargs={"pk": user.public_primary_key}) + "?backend=INVALID"926 response = client.post(f"{url}", format="json", **make_user_auth_headers(user, token))927 assert response.status_code == status.HTTP_400_BAD_REQUEST928@pytest.mark.django_db929def test_user_unlink_backend_backend_account_not_found(930 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers931):932 organization = make_organization()933 user = make_user_for_organization(organization, role=Role.EDITOR)934 _, token = make_token_for_organization(organization)935 client = APIClient()936 url = reverse("api-internal:user-unlink-backend", kwargs={"pk": user.public_primary_key}) + "?backend=TESTONLY"937 with patch("apps.base.tests.messaging_backend.TestOnlyBackend.unlink_user", side_effect=ObjectDoesNotExist):938 response = client.post(f"{url}", format="json", **make_user_auth_headers(user, token))939 assert response.status_code == status.HTTP_400_BAD_REQUEST940@pytest.mark.django_db941def test_user_cant_unlink_slack_another_user(942 make_organization_with_slack_team_identity,943 make_user_with_slack_user_identity,944 make_token_for_organization,945 make_user_auth_headers,946):947 organization, slack_team_identity = make_organization_with_slack_team_identity()948 first_user, slack_user_identity_1 = make_user_with_slack_user_identity(949 slack_team_identity, organization, slack_id="user_1", role=Role.EDITOR950 )951 second_user, slack_user_identity_2 = make_user_with_slack_user_identity(952 slack_team_identity, organization, slack_id="user_2", role=Role.EDITOR953 )954 _, token = make_token_for_organization(organization)955 client = APIClient()956 url = reverse("api-internal:user-unlink-slack", kwargs={"pk": first_user.public_primary_key})957 response = client.post(url, format="json", **make_user_auth_headers(second_user, token))958 assert response.status_code == status.HTTP_403_FORBIDDEN959 first_user.refresh_from_db()960 assert first_user.slack_user_identity is not None961@pytest.mark.django_db962def test_user_cant_unlink_backend__another_user(963 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers964):965 organization = make_organization()966 first_user = make_user_for_organization(organization, role=Role.EDITOR)967 second_user = make_user_for_organization(organization, role=Role.EDITOR)968 _, token = make_token_for_organization(organization)969 client = APIClient()970 url = (971 reverse("api-internal:user-unlink-backend", kwargs={"pk": first_user.public_primary_key}) + "?backend=TESTONLY"972 )973 response = client.post(f"{url}", format="json", **make_user_auth_headers(second_user, token))974 assert response.status_code == status.HTTP_403_FORBIDDEN975"""Test stakeholder permissions"""976@pytest.mark.django_db977def test_viewer_cant_create_user(978 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers979):980 organization = make_organization()981 user = make_user_for_organization(organization, role=Role.VIEWER)982 _, token = make_token_for_organization(organization)983 client = APIClient()984 url = reverse("api-internal:user-list")985 data = {986 "email": "test@amixr.io",987 "role": Role.ADMIN,988 "username": "test_username",989 "unverified_phone_number": None,990 "slack_login": "",991 }992 response = client.post(url, format="json", data=data, **make_user_auth_headers(user, token))993 assert response.status_code == status.HTTP_403_FORBIDDEN994@pytest.mark.django_db995def test_viewer_cant_update_user(996 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers997):998 organization = make_organization()999 first_user = make_user_for_organization(organization, role=Role.EDITOR)1000 second_user = make_user_for_organization(organization, role=Role.VIEWER)1001 _, token = make_token_for_organization(organization)1002 data = {1003 "email": "test@amixr.io",1004 "role": Role.EDITOR,1005 "username": "updated_test_username",1006 "unverified_phone_number": "+1234567890",1007 "slack_login": "",1008 }1009 client = APIClient()1010 url = reverse("api-internal:user-detail", kwargs={"pk": first_user.public_primary_key})1011 response = client.put(url, format="json", data=data, **make_user_auth_headers(second_user, token))1012 assert response.status_code == status.HTTP_403_FORBIDDEN1013@pytest.mark.django_db1014def test_viewer_cant_update_himself(1015 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers1016):1017 organization = make_organization()1018 user = make_user_for_organization(organization, role=Role.VIEWER)1019 _, token = make_token_for_organization(organization)1020 data = {1021 "email": "test@amixr.io",1022 "role": Role.VIEWER,1023 "username": "updated_test_username",1024 "unverified_phone_number": "+1234567890",1025 "slack_login": "",1026 }1027 client = APIClient()1028 url = reverse("api-internal:user-detail", kwargs={"pk": user.public_primary_key})1029 response = client.put(url, format="json", data=data, **make_user_auth_headers(user, token))1030 assert response.status_code == status.HTTP_403_FORBIDDEN1031@pytest.mark.django_db1032def test_viewer_cant_list_users(1033 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers1034):1035 organization = make_organization()1036 user = make_user_for_organization(organization, role=Role.VIEWER)1037 _, token = make_token_for_organization(organization)1038 client = APIClient()1039 url = reverse("api-internal:user-list")1040 response = client.get(url, format="json", **make_user_auth_headers(user, token))1041 assert response.status_code == status.HTTP_403_FORBIDDEN1042@pytest.mark.django_db1043def test_viewer_cant_detail_users(1044 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers1045):1046 organization = make_organization()1047 first_user = make_user_for_organization(organization, role=Role.EDITOR)1048 second_user = make_user_for_organization(organization, role=Role.VIEWER)1049 _, token = make_token_for_organization(organization)1050 client = APIClient()1051 url = reverse("api-internal:user-detail", kwargs={"pk": first_user.public_primary_key})1052 response = client.get(url, format="json", **make_user_auth_headers(second_user, token))1053 assert response.status_code == status.HTTP_403_FORBIDDEN1054@patch("apps.twilioapp.phone_manager.PhoneManager.send_verification_code", return_value=Mock())1055@pytest.mark.django_db1056def test_viewer_cant_get_own_verification_code(1057 mock_verification_start,1058 make_organization,1059 make_user_for_organization,1060 make_token_for_organization,1061 make_user_auth_headers,1062):1063 organization = make_organization()1064 user = make_user_for_organization(organization, role=Role.VIEWER)1065 _, token = make_token_for_organization(organization)1066 client = APIClient()1067 url = reverse("api-internal:user-get-verification-code", kwargs={"pk": user.public_primary_key})1068 response = client.get(url, format="json", **make_user_auth_headers(user, token))1069 assert response.status_code == status.HTTP_403_FORBIDDEN1070@patch("apps.twilioapp.phone_manager.PhoneManager.send_verification_code", return_value=Mock())1071@pytest.mark.django_db1072def test_viewer_cant_get_another_user_verification_code(1073 mock_verification_start,1074 make_organization,1075 make_user_for_organization,1076 make_token_for_organization,1077 make_user_auth_headers,1078):1079 organization = make_organization()1080 first_user = make_user_for_organization(organization, role=Role.EDITOR)1081 second_user = make_user_for_organization(organization, role=Role.VIEWER)1082 _, token = make_token_for_organization(organization)1083 client = APIClient()1084 url = reverse("api-internal:user-get-verification-code", kwargs={"pk": first_user.public_primary_key})1085 response = client.get(url, format="json", **make_user_auth_headers(second_user, token))1086 assert response.status_code == status.HTTP_403_FORBIDDEN1087@patch("apps.twilioapp.phone_manager.PhoneManager.verify_phone_number", return_value=(True, None))1088@pytest.mark.django_db1089def test_viewer_cant_verify_own_phone(1090 mocked_verification_check,1091 make_organization,1092 make_user_for_organization,1093 make_token_for_organization,1094 make_user_auth_headers,1095):1096 organization = make_organization()1097 user = make_user_for_organization(organization, role=Role.VIEWER)1098 _, token = make_token_for_organization(organization)1099 client = APIClient()1100 url = reverse("api-internal:user-verify-number", kwargs={"pk": user.public_primary_key})1101 response = client.put(f"{url}?token=12345", format="json", **make_user_auth_headers(user, token))1102 assert response.status_code == status.HTTP_403_FORBIDDEN1103@patch("apps.twilioapp.phone_manager.PhoneManager.verify_phone_number", return_value=(True, None))1104@pytest.mark.django_db1105def test_viewer_cant_verify_another_user_phone(1106 mocked_verification_check,1107 make_organization,1108 make_user_for_organization,1109 make_token_for_organization,1110 make_user_auth_headers,1111):1112 organization = make_organization()1113 first_user = make_user_for_organization(organization, role=Role.EDITOR)1114 second_user = make_user_for_organization(organization, role=Role.VIEWER)1115 _, token = make_token_for_organization(organization)1116 client = APIClient()1117 url = reverse("api-internal:user-verify-number", kwargs={"pk": first_user.public_primary_key})1118 response = client.put(f"{url}?token=12345", format="json", **make_user_auth_headers(second_user, token))1119 assert response.status_code == status.HTTP_403_FORBIDDEN1120@pytest.mark.django_db1121def test_viewer_cant_get_own_telegram_verification_code(1122 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers1123):1124 organization = make_organization()1125 user = make_user_for_organization(organization, role=Role.VIEWER)1126 _, token = make_token_for_organization(organization)1127 client = APIClient()1128 url = reverse("api-internal:user-get-telegram-verification-code", kwargs={"pk": user.public_primary_key})1129 response = client.get(f"{url}", format="json", **make_user_auth_headers(user, token))1130 assert response.status_code == status.HTTP_403_FORBIDDEN1131@pytest.mark.django_db1132def test_viewer_cant_get_another_user_telegram_verification_code(1133 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers1134):1135 organization = make_organization()1136 first_user = make_user_for_organization(organization, role=Role.EDITOR)1137 second_user = make_user_for_organization(organization, role=Role.VIEWER)1138 _, token = make_token_for_organization(organization)1139 client = APIClient()1140 url = reverse("api-internal:user-get-telegram-verification-code", kwargs={"pk": first_user.public_primary_key})1141 response = client.get(url, format="json", **make_user_auth_headers(second_user, token))1142 assert response.status_code == status.HTTP_403_FORBIDDEN1143@pytest.mark.django_db1144@pytest.mark.parametrize(1145 "role,expected_status,initial_unverified_number,initial_verified_number",1146 [1147 (Role.ADMIN, status.HTTP_200_OK, "+1234567890", None),1148 (Role.EDITOR, status.HTTP_200_OK, "+1234567890", None),1149 (Role.VIEWER, status.HTTP_403_FORBIDDEN, "+1234567890", None),1150 (Role.ADMIN, status.HTTP_200_OK, None, "+1234567890"),1151 (Role.EDITOR, status.HTTP_200_OK, None, "+1234567890"),1152 (Role.VIEWER, status.HTTP_403_FORBIDDEN, None, "+1234567890"),1153 ],1154)1155def test_forget_own_number(1156 make_organization,1157 make_team,1158 make_user_for_organization,1159 make_token_for_organization,1160 make_user_auth_headers,1161 role,1162 expected_status,1163 initial_unverified_number,1164 initial_verified_number,1165):1166 organization = make_organization()1167 admin = make_user_for_organization(organization, role=Role.ADMIN)1168 user = make_user_for_organization(1169 organization,1170 role=role,1171 unverified_phone_number=initial_unverified_number,1172 _verified_phone_number=initial_verified_number,1173 )1174 _, token = make_token_for_organization(organization)1175 client = APIClient()1176 url = reverse("api-internal:user-forget-number", kwargs={"pk": user.public_primary_key})1177 with patch(1178 "apps.twilioapp.phone_manager.PhoneManager.notify_about_changed_verified_phone_number", return_value=None1179 ):1180 response = client.put(url, None, format="json", **make_user_auth_headers(user, token))1181 assert response.status_code == expected_status1182 user_detail_url = reverse("api-internal:user-detail", kwargs={"pk": user.public_primary_key})1183 response = client.get(user_detail_url, None, format="json", **make_user_auth_headers(admin, token))1184 assert response.status_code == status.HTTP_200_OK1185 if expected_status == status.HTTP_200_OK:1186 assert not response.json()["unverified_phone_number"]1187 assert not response.json()["verified_phone_number"]1188 else:1189 assert response.json()["unverified_phone_number"] == initial_unverified_number1190 assert response.json()["verified_phone_number"] == initial_verified_number1191@pytest.mark.django_db1192@pytest.mark.parametrize(1193 "role,expected_status,initial_unverified_number,initial_verified_number",1194 [1195 (Role.ADMIN, status.HTTP_200_OK, "+1234567890", None),1196 (Role.EDITOR, status.HTTP_403_FORBIDDEN, "+1234567890", None),1197 (Role.VIEWER, status.HTTP_403_FORBIDDEN, "+1234567890", None),1198 (Role.ADMIN, status.HTTP_200_OK, None, "+1234567890"),1199 (Role.EDITOR, status.HTTP_403_FORBIDDEN, None, "+1234567890"),1200 (Role.VIEWER, status.HTTP_403_FORBIDDEN, None, "+1234567890"),1201 ],1202)1203def test_forget_other_number(1204 make_organization,1205 make_team,1206 make_user_for_organization,1207 make_token_for_organization,1208 make_user_auth_headers,1209 role,1210 expected_status,1211 initial_unverified_number,1212 initial_verified_number,1213):1214 organization = make_organization()1215 user = make_user_for_organization(1216 organization,1217 role=Role.ADMIN,1218 unverified_phone_number=initial_unverified_number,1219 _verified_phone_number=initial_verified_number,1220 )1221 other_user = make_user_for_organization(organization, role=role)1222 _, token = make_token_for_organization(organization)1223 client = APIClient()1224 url = reverse("api-internal:user-forget-number", kwargs={"pk": user.public_primary_key})1225 with patch(1226 "apps.twilioapp.phone_manager.PhoneManager.notify_about_changed_verified_phone_number", return_value=None1227 ):1228 response = client.put(url, None, format="json", **make_user_auth_headers(other_user, token))1229 assert response.status_code == expected_status1230 user_detail_url = reverse("api-internal:user-detail", kwargs={"pk": user.public_primary_key})1231 response = client.get(user_detail_url, None, format="json", **make_user_auth_headers(user, token))1232 assert response.status_code == status.HTTP_200_OK1233 if expected_status == status.HTTP_200_OK:1234 assert not response.json()["unverified_phone_number"]1235 assert not response.json()["verified_phone_number"]1236 else:1237 assert response.json()["unverified_phone_number"] == initial_unverified_number1238 assert response.json()["verified_phone_number"] == initial_verified_number1239@pytest.mark.django_db1240def test_viewer_cant_get_own_backend_verification_code(1241 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers1242):1243 organization = make_organization()1244 user = make_user_for_organization(organization, role=Role.VIEWER)1245 _, token = make_token_for_organization(organization)1246 client = APIClient()1247 url = (1248 reverse("api-internal:user-get-backend-verification-code", kwargs={"pk": user.public_primary_key})1249 + "?backend=TESTONLY"1250 )1251 response = client.get(f"{url}", format="json", **make_user_auth_headers(user, token))1252 assert response.status_code == status.HTTP_403_FORBIDDEN1253@pytest.mark.django_db1254def test_viewer_cant_get_another_user_backend_verification_code(1255 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers1256):1257 organization = make_organization()1258 first_user = make_user_for_organization(organization, role=Role.EDITOR)1259 second_user = make_user_for_organization(organization, role=Role.VIEWER)1260 _, token = make_token_for_organization(organization)1261 client = APIClient()1262 url = (1263 reverse("api-internal:user-get-backend-verification-code", kwargs={"pk": first_user.public_primary_key})1264 + "?backend=TESTONLY"1265 )1266 response = client.get(url, format="json", **make_user_auth_headers(second_user, token))1267 assert response.status_code == status.HTTP_403_FORBIDDEN1268@pytest.mark.django_db1269def test_viewer_cant_unlink_backend_own_user(1270 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers1271):1272 organization = make_organization()1273 user = make_user_for_organization(organization, role=Role.VIEWER)1274 _, token = make_token_for_organization(organization)1275 client = APIClient()1276 url = reverse("api-internal:user-unlink-backend", kwargs={"pk": user.public_primary_key}) + "?backend=TESTONLY"1277 response = client.post(f"{url}", format="json", **make_user_auth_headers(user, token))1278 assert response.status_code == status.HTTP_403_FORBIDDEN1279@pytest.mark.django_db1280def test_viewer_cant_unlink_backend_another_user(1281 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers1282):1283 organization = make_organization()1284 first_user = make_user_for_organization(organization, role=Role.EDITOR)1285 second_user = make_user_for_organization(organization, role=Role.VIEWER)1286 _, token = make_token_for_organization(organization)1287 client = APIClient()1288 url = (1289 reverse("api-internal:user-unlink-backend", kwargs={"pk": first_user.public_primary_key}) + "?backend=TESTONLY"1290 )1291 response = client.post(url, format="json", **make_user_auth_headers(second_user, token))1292 assert response.status_code == status.HTTP_403_FORBIDDEN1293@pytest.mark.django_db1294def test_change_timezone(1295 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers1296):1297 organization = make_organization()1298 user = make_user_for_organization(organization, role=Role.EDITOR)1299 _, token = make_token_for_organization(organization)1300 client = APIClient()1301 url = reverse("api-internal:user-detail", kwargs={"pk": user.public_primary_key})1302 data = {"timezone": "Europe/London"}1303 response = client.put(f"{url}", data, format="json", **make_user_auth_headers(user, token))1304 assert response.status_code == status.HTTP_200_OK1305 assert "timezone" in response.json()1306 assert response.json()["timezone"] == "Europe/London"1307@pytest.mark.django_db1308@pytest.mark.parametrize("timezone", ["", 1, "NotATimezone"])1309def test_invalid_timezone(1310 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers, timezone1311):1312 organization = make_organization()1313 user = make_user_for_organization(organization, role=Role.EDITOR)1314 _, token = make_token_for_organization(organization)1315 client = APIClient()1316 url = reverse("api-internal:user-detail", kwargs={"pk": user.public_primary_key})1317 data = {"timezone": timezone}1318 response = client.put(f"{url}", data, format="json", **make_user_auth_headers(user, token))1319 assert response.status_code == status.HTTP_400_BAD_REQUEST1320@pytest.mark.django_db1321def test_change_working_hours(1322 make_organization, make_user_for_organization, make_token_for_organization, make_user_auth_headers1323):1324 organization = make_organization()1325 user = make_user_for_organization(organization, role=Role.EDITOR)1326 _, token = make_token_for_organization(organization)1327 client = APIClient()1328 url = reverse("api-internal:user-detail", kwargs={"pk": user.public_primary_key})1329 periods = [{"start": "05:00:00", "end": "23:00:00"}]1330 working_hours = {1331 day: periods for day in ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"]1332 }1333 data = {"working_hours": working_hours}1334 response = client.put(f"{url}", data, format="json", **make_user_auth_headers(user, token))1335 assert response.status_code == status.HTTP_200_OK1336 assert "working_hours" in response.json()1337 assert response.json()["working_hours"] == working_hours1338@pytest.mark.django_db1339@pytest.mark.parametrize(1340 "working_hours_extra",1341 [1342 {},1343 {"sunday": 1},1344 {"sunday": ""},1345 {"sunday": {"start": "18:00:00"}},1346 {"sunday": {"start": "", "end": ""}},1347 {"sunday": {"start": "18:00:00", "end": None}},1348 {"sunday": {"start": "18:00:00", "end": "18:00:00"}},1349 {"sunday": {"start": "18:00:00", "end": "9:00:00"}},1350 {"sunday": {"start": "18:00:00", "end": "9:00:00", "extra": 1}},1351 ],1352)1353def test_invalid_working_hours(1354 make_organization,1355 make_user_for_organization,1356 make_token_for_organization,1357 make_user_auth_headers,1358 working_hours_extra,1359):1360 organization = make_organization()1361 user = make_user_for_organization(organization, role=Role.EDITOR)1362 _, token = make_token_for_organization(organization)1363 client = APIClient()1364 url = reverse("api-internal:user-detail", kwargs={"pk": user.public_primary_key})1365 periods = [{"start": "05:00:00", "end": "23:00:00"}]1366 working_hours = {day: periods for day in ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday"]}1367 working_hours.update(working_hours_extra)1368 data = {"working_hours": working_hours}1369 response = client.put(f"{url}", data, format="json", **make_user_auth_headers(user, token))...
make_einstein.py
Source:make_einstein.py
1from enum import Enum2class Nationality(Enum):3 brit = 04 swede = 15 dane = 26 norwegian = 37 german = 48 def __int__(self):9 return self.value10class Color(Enum):11 red = 012 green = 113 yellow = 214 blue = 315 white = 416 def __int__(self):17 return self.value18class Beverage(Enum):19 tea = 020 coffee = 121 milk = 222 beer = 323 water = 424 def __int__(self):25 return self.value26class Cigar(Enum):27 pallmall = 028 dunhill = 129 blends = 230 bluemasters = 331 prince = 432 def __int__(self):33 return self.value34class Pet(Enum):35 dogs = 036 birds = 137 cats = 238 horse = 339 fish = 440 def __int__(self):41 return self.value42class Clause:43 def __init__(self):44 self.s = set([])45 def __str__(self):46 ret_str = ""47 for p in self.s:48 ret_str += str(p)49 ret_str += " "50 ret_str += "0"51 return ret_str52 53 def __repr__(self):54 ret_str = ""55 for p in self.s:56 ret_str += str(p)57 ret_str += " "58 ret_str += "0"59 return ret_str60 def add_literal(self, l):61 self.s.add(l)62def make_literal(prop, negated=False):63 if negated:64 return -(prop + 1)65 else:66 return prop + 167 68def make_einstein_prop(n=None, c=None, b=None, s=None, p=None, h=None):69 assert(isinstance(n, Nationality) or n is None)70 assert(isinstance(c, Color) or c is None)71 assert(isinstance(b, Beverage) or b is None)72 assert(isinstance(s, Cigar) or s is None)73 assert(isinstance(p, Pet) or p is None)74 assert(isinstance(h, int) or h is None)75 num_not_none = sum([x is not None for x in [n, c, b, s, p, h]])76 assert(num_not_none==2)77 prop_num = 078 # Nationality79 if n is not None:80 if c is not None:81 # NC82 prop_num = prop_num + (int(n)*5) + int(c)83 return prop_num84 elif b is not None:85 # NB86 prop_num = 2587 prop_num = prop_num + (int(n)*5) + int(b)88 return prop_num89 elif s is not None:90 # NS91 prop_num = 5092 prop_num = prop_num + (int(n)*5) + int(s)93 return prop_num94 elif p is not None:95 # NP96 prop_num = 7597 prop_num = prop_num + (int(n)*5) + int(p)98 return prop_num99 else:100 # NH101 prop_num = 100102 prop_num = prop_num + (int(n)*5) + int(h)103 return prop_num104 # Color105 elif c is not None:106 prop_num = 125107 if b is not None:108 # CB109 prop_num = prop_num + (int(c)*5) + int(b)110 return prop_num111 elif s is not None:112 # CS113 prop_num = prop_num + 25114 prop_num = prop_num + (int(c)*5) + int(s)115 return prop_num116 elif p is not None:117 # CP118 prop_num = prop_num + 50119 prop_num = prop_num + (int(c)*5) + int(p)120 return prop_num121 else:122 # CH123 prop_num = prop_num + 75124 prop_num = prop_num + (int(c)*5) + int(h)125 return prop_num126 # Beverage127 elif b is not None:128 prop_num = 225129 if s is not None:130 # BS131 prop_num = prop_num + (int(b)*5) + int(s)132 return prop_num133 elif p is not None:134 # BP135 prop_num = prop_num + 25136 prop_num = prop_num + (int(b)*5) + int(p)137 return prop_num138 else:139 # BH140 prop_num = prop_num + 50141 prop_num = prop_num + (int(b)*5) + int(h)142 return prop_num143 # Smoking144 elif s is not None:145 prop_num = 300146 if p is not None:147 # SP148 prop_num = prop_num + (int(s)*5) + int(p)149 return prop_num150 else:151 # SH152 prop_num = prop_num + 25153 prop_num = prop_num + (int(s)*5) + int(h)154 return prop_num155 # Pet156 else:157 # PH158 prop_num = 350159 prop_num = prop_num + (int(p)*5) + int(h)160 return prop_num161def make_exclusion_axioms(ns=None, cs=None, bs=None, ss=None, ps=None, hs=None):162 num_not_none = sum([x is not None for x in [ns, cs, bs, ss, ps, hs]])163 assert(num_not_none==2)164 axioms = []165 # Nationality166 if ns is not None:167 if cs is not None:168 # NC169 for c in cs:170 disjunctive_c = Clause()171 for i in range(len(ns)):172 disjunctive_c.add_literal(make_literal(make_einstein_prop(n=ns[i], c=c)))173 for j in range(i+1, len(ns)):174 exclusive_c = Clause()175 exclusive_c.add_literal(make_literal(make_einstein_prop(n=ns[i], c=c), negated=True))176 exclusive_c.add_literal(make_literal(make_einstein_prop(n=ns[j], c=c), negated=True))177 axioms.append(exclusive_c)178 axioms.append(disjunctive_c)179 for n in ns:180 disjunctive_c = Clause()181 for i in range(len(cs)):182 disjunctive_c.add_literal(make_literal(make_einstein_prop(n=n, c=cs[i])))183 for j in range(i+1, len(cs)):184 exclusive_c = Clause()185 exclusive_c.add_literal(make_literal(make_einstein_prop(n=n, c=cs[i]), negated=True))186 exclusive_c.add_literal(make_literal(make_einstein_prop(n=n, c=cs[j]), negated=True))187 axioms.append(exclusive_c)188 axioms.append(disjunctive_c)189 elif bs is not None:190 # NB191 for b in bs:192 disjunctive_c = Clause()193 for i in range(len(ns)):194 disjunctive_c.add_literal(make_literal(make_einstein_prop(n=ns[i], b=b)))195 for j in range(i+1, len(ns)):196 exclusive_c = Clause()197 exclusive_c.add_literal(make_literal(make_einstein_prop(n=ns[i], b=b), negated=True))198 exclusive_c.add_literal(make_literal(make_einstein_prop(n=ns[j], b=b), negated=True))199 axioms.append(exclusive_c)200 axioms.append(disjunctive_c)201 for n in ns:202 disjunctive_c = Clause()203 for i in range(len(bs)):204 disjunctive_c.add_literal(make_literal(make_einstein_prop(n=n, b=bs[i])))205 for j in range(i+1, len(bs)):206 exclusive_c = Clause()207 exclusive_c.add_literal(make_literal(make_einstein_prop(n=n, b=bs[i]), negated=True))208 exclusive_c.add_literal(make_literal(make_einstein_prop(n=n, b=bs[j]), negated=True))209 axioms.append(exclusive_c)210 axioms.append(disjunctive_c)211 elif ss is not None:212 # NS213 for s in ss:214 disjunctive_c = Clause()215 for i in range(len(ns)):216 disjunctive_c.add_literal(make_literal(make_einstein_prop(n=ns[i], s=s)))217 for j in range(i+1, len(ns)):218 exclusive_c = Clause()219 exclusive_c.add_literal(make_literal(make_einstein_prop(n=ns[i], s=s), negated=True))220 exclusive_c.add_literal(make_literal(make_einstein_prop(n=ns[j], s=s), negated=True))221 axioms.append(exclusive_c)222 axioms.append(disjunctive_c)223 for n in ns:224 disjunctive_c = Clause()225 for i in range(len(ss)):226 disjunctive_c.add_literal(make_literal(make_einstein_prop(n=n, s=ss[i])))227 for j in range(i+1, len(ss)):228 exclusive_c = Clause()229 exclusive_c.add_literal(make_literal(make_einstein_prop(n=n, s=ss[i]), negated=True))230 exclusive_c.add_literal(make_literal(make_einstein_prop(n=n, s=ss[j]), negated=True))231 axioms.append(exclusive_c)232 axioms.append(disjunctive_c)233 elif ps is not None:234 # NP235 for p in ps:236 disjunctive_c = Clause()237 for i in range(len(ns)):238 disjunctive_c.add_literal(make_literal(make_einstein_prop(n=ns[i], p=p)))239 for j in range(i+1, len(ns)):240 exclusive_c = Clause()241 exclusive_c.add_literal(make_literal(make_einstein_prop(n=ns[i], p=p), negated=True))242 exclusive_c.add_literal(make_literal(make_einstein_prop(n=ns[j], p=p), negated=True))243 axioms.append(exclusive_c)244 axioms.append(disjunctive_c)245 for n in ns:246 disjunctive_c = Clause()247 for i in range(len(ps)):248 disjunctive_c.add_literal(make_literal(make_einstein_prop(n=n, p=ps[i])))249 for j in range(i+1, len(ps)):250 exclusive_c = Clause()251 exclusive_c.add_literal(make_literal(make_einstein_prop(n=n, p=ps[i]), negated=True))252 exclusive_c.add_literal(make_literal(make_einstein_prop(n=n, p=ps[j]), negated=True))253 axioms.append(exclusive_c)254 axioms.append(disjunctive_c)255 else:256 # NH257 for h in hs:258 disjunctive_c = Clause()259 for i in range(len(ns)):260 disjunctive_c.add_literal(make_literal(make_einstein_prop(n=ns[i], h=h)))261 for j in range(i+1, len(ns)):262 exclusive_c = Clause()263 exclusive_c.add_literal(make_literal(make_einstein_prop(n=ns[i], h=h), negated=True))264 exclusive_c.add_literal(make_literal(make_einstein_prop(n=ns[j], h=h), negated=True))265 axioms.append(exclusive_c)266 axioms.append(disjunctive_c)267 for n in ns:268 disjunctive_c = Clause()269 for i in range(len(hs)):270 disjunctive_c.add_literal(make_literal(make_einstein_prop(n=n, h=hs[i])))271 for j in range(i+1, len(hs)):272 exclusive_c = Clause()273 exclusive_c.add_literal(make_literal(make_einstein_prop(n=n, h=hs[i]), negated=True))274 exclusive_c.add_literal(make_literal(make_einstein_prop(n=n, h=hs[j]), negated=True))275 axioms.append(exclusive_c)276 axioms.append(disjunctive_c)277 # Color278 elif cs is not None:279 if bs is not None:280 # CB281 for b in bs:282 disjunctive_c = Clause()283 for i in range(len(cs)):284 disjunctive_c.add_literal(make_literal(make_einstein_prop(c=cs[i], b=b)))285 for j in range(i+1, len(cs)):286 exclusive_c = Clause()287 exclusive_c.add_literal(make_literal(make_einstein_prop(c=cs[i], b=b), negated=True))288 exclusive_c.add_literal(make_literal(make_einstein_prop(c=cs[j], b=b), negated=True))289 axioms.append(exclusive_c)290 axioms.append(disjunctive_c)291 for c in cs:292 disjunctive_c = Clause()293 for i in range(len(bs)):294 disjunctive_c.add_literal(make_literal(make_einstein_prop(c=c, b=bs[i])))295 for j in range(i+1, len(bs)):296 exclusive_c = Clause()297 exclusive_c.add_literal(make_literal(make_einstein_prop(c=c, b=bs[i]), negated=True))298 exclusive_c.add_literal(make_literal(make_einstein_prop(c=c, b=bs[j]), negated=True))299 axioms.append(exclusive_c)300 axioms.append(disjunctive_c)301 elif ss is not None:302 # CS303 for s in ss:304 disjunctive_c = Clause()305 for i in range(len(cs)):306 disjunctive_c.add_literal(make_literal(make_einstein_prop(c=cs[i], s=s)))307 for j in range(i+1, len(cs)):308 exclusive_c = Clause()309 exclusive_c.add_literal(make_literal(make_einstein_prop(c=cs[i], s=s), negated=True))310 exclusive_c.add_literal(make_literal(make_einstein_prop(c=cs[j], s=s), negated=True))311 axioms.append(exclusive_c)312 axioms.append(disjunctive_c)313 for c in cs:314 disjunctive_c = Clause()315 for i in range(len(ss)):316 disjunctive_c.add_literal(make_literal(make_einstein_prop(c=c, s=ss[i])))317 for j in range(i+1, len(ss)):318 exclusive_c = Clause()319 exclusive_c.add_literal(make_literal(make_einstein_prop(c=c, s=ss[i]), negated=True))320 exclusive_c.add_literal(make_literal(make_einstein_prop(c=c, s=ss[j]), negated=True))321 axioms.append(exclusive_c)322 axioms.append(disjunctive_c)323 elif ps is not None:324 # CP325 for p in ps:326 disjunctive_c = Clause()327 for i in range(len(cs)):328 disjunctive_c.add_literal(make_literal(make_einstein_prop(c=cs[i], p=p)))329 for j in range(i+1, len(cs)):330 exclusive_c = Clause()331 exclusive_c.add_literal(make_literal(make_einstein_prop(c=cs[i], p=p), negated=True))332 exclusive_c.add_literal(make_literal(make_einstein_prop(c=cs[j], p=p), negated=True))333 axioms.append(exclusive_c)334 axioms.append(disjunctive_c)335 for c in cs:336 disjunctive_c = Clause()337 for i in range(len(ps)):338 disjunctive_c.add_literal(make_literal(make_einstein_prop(c=c, p=ps[i])))339 for j in range(i+1, len(ps)):340 exclusive_c = Clause()341 exclusive_c.add_literal(make_literal(make_einstein_prop(c=c, p=ps[i]), negated=True))342 exclusive_c.add_literal(make_literal(make_einstein_prop(c=c, p=ps[j]), negated=True))343 axioms.append(exclusive_c)344 axioms.append(disjunctive_c)345 else:346 # CH347 for h in hs:348 disjunctive_c = Clause()349 for i in range(len(cs)):350 disjunctive_c.add_literal(make_literal(make_einstein_prop(c=cs[i], h=h)))351 for j in range(i+1, len(cs)):352 exclusive_c = Clause()353 exclusive_c.add_literal(make_literal(make_einstein_prop(c=cs[i], h=h), negated=True))354 exclusive_c.add_literal(make_literal(make_einstein_prop(c=cs[j], h=h), negated=True))355 axioms.append(exclusive_c)356 axioms.append(disjunctive_c)357 for c in cs:358 disjunctive_c = Clause()359 for i in range(len(hs)):360 disjunctive_c.add_literal(make_literal(make_einstein_prop(c=c, h=hs[i])))361 for j in range(i+1, len(hs)):362 exclusive_c = Clause()363 exclusive_c.add_literal(make_literal(make_einstein_prop(c=c, h=hs[i]), negated=True))364 exclusive_c.add_literal(make_literal(make_einstein_prop(c=c, h=hs[j]), negated=True))365 axioms.append(exclusive_c)366 axioms.append(disjunctive_c)367 # Beverage368 elif bs is not None:369 if ss is not None:370 # BS371 for s in ss:372 disjunctive_c = Clause()373 for i in range(len(bs)):374 disjunctive_c.add_literal(make_literal(make_einstein_prop(b=bs[i], s=s)))375 for j in range(i+1, len(bs)):376 exclusive_c = Clause()377 exclusive_c.add_literal(make_literal(make_einstein_prop(b=bs[i], s=s), negated=True))378 exclusive_c.add_literal(make_literal(make_einstein_prop(b=bs[j], s=s), negated=True))379 axioms.append(exclusive_c)380 axioms.append(disjunctive_c)381 for b in bs:382 disjunctive_c = Clause()383 for i in range(len(ss)):384 disjunctive_c.add_literal(make_literal(make_einstein_prop(b=b, s=ss[i])))385 for j in range(i+1, len(ss)):386 exclusive_c = Clause()387 exclusive_c.add_literal(make_literal(make_einstein_prop(b=b, s=ss[i]), negated=True))388 exclusive_c.add_literal(make_literal(make_einstein_prop(b=b, s=ss[j]), negated=True))389 axioms.append(exclusive_c)390 axioms.append(disjunctive_c)391 elif ps is not None:392 # BP393 for p in ps:394 disjunctive_c = Clause()395 for i in range(len(bs)):396 disjunctive_c.add_literal(make_literal(make_einstein_prop(b=bs[i], p=p)))397 for j in range(i+1, len(bs)):398 exclusive_c = Clause()399 exclusive_c.add_literal(make_literal(make_einstein_prop(b=bs[i], p=p), negated=True))400 exclusive_c.add_literal(make_literal(make_einstein_prop(b=bs[j], p=p), negated=True))401 axioms.append(exclusive_c)402 axioms.append(disjunctive_c)403 for b in bs:404 disjunctive_c = Clause()405 for i in range(len(ps)):406 disjunctive_c.add_literal(make_literal(make_einstein_prop(b=b, p=ps[i])))407 for j in range(i+1, len(ps)):408 exclusive_c = Clause()409 exclusive_c.add_literal(make_literal(make_einstein_prop(b=b, p=ps[i]), negated=True))410 exclusive_c.add_literal(make_literal(make_einstein_prop(b=b, p=ps[j]), negated=True))411 axioms.append(exclusive_c)412 axioms.append(disjunctive_c)413 else:414 # BH415 for h in hs:416 disjunctive_c = Clause()417 for i in range(len(bs)):418 disjunctive_c.add_literal(make_literal(make_einstein_prop(b=bs[i], h=h)))419 for j in range(i+1, len(bs)):420 exclusive_c = Clause()421 exclusive_c.add_literal(make_literal(make_einstein_prop(b=bs[i], h=h), negated=True))422 exclusive_c.add_literal(make_literal(make_einstein_prop(b=bs[j], h=h), negated=True))423 axioms.append(exclusive_c)424 axioms.append(disjunctive_c)425 for b in bs:426 disjunctive_c = Clause()427 for i in range(len(hs)):428 disjunctive_c.add_literal(make_literal(make_einstein_prop(b=b, h=hs[i])))429 for j in range(i+1, len(hs)):430 exclusive_c = Clause()431 exclusive_c.add_literal(make_literal(make_einstein_prop(b=b, h=hs[i]), negated=True))432 exclusive_c.add_literal(make_literal(make_einstein_prop(b=b, h=hs[j]), negated=True))433 axioms.append(exclusive_c)434 axioms.append(disjunctive_c)435 # Smoking436 elif ss is not None:437 if ps is not None:438 # SP439 for p in ps:440 disjunctive_c = Clause()441 for i in range(len(ss)):442 disjunctive_c.add_literal(make_literal(make_einstein_prop(s=ss[i], p=p)))443 for j in range(i+1, len(ss)):444 exclusive_c = Clause()445 exclusive_c.add_literal(make_literal(make_einstein_prop(s=ss[i], p=p), negated=True))446 exclusive_c.add_literal(make_literal(make_einstein_prop(s=ss[j], p=p), negated=True))447 axioms.append(exclusive_c)448 axioms.append(disjunctive_c)449 for s in ss:450 disjunctive_c = Clause()451 for i in range(len(ps)):452 disjunctive_c.add_literal(make_literal(make_einstein_prop(s=s, p=ps[i])))453 for j in range(i+1, len(ps)):454 exclusive_c = Clause()455 exclusive_c.add_literal(make_literal(make_einstein_prop(s=s, p=ps[i]), negated=True))456 exclusive_c.add_literal(make_literal(make_einstein_prop(s=s, p=ps[j]), negated=True))457 axioms.append(exclusive_c)458 axioms.append(disjunctive_c)459 else:460 # SH461 for h in hs:462 disjunctive_c = Clause()463 for i in range(len(ss)):464 disjunctive_c.add_literal(make_literal(make_einstein_prop(s=ss[i], h=h)))465 for j in range(i+1, len(ss)):466 exclusive_c = Clause()467 exclusive_c.add_literal(make_literal(make_einstein_prop(s=ss[i], h=h), negated=True))468 exclusive_c.add_literal(make_literal(make_einstein_prop(s=ss[j], h=h), negated=True))469 axioms.append(exclusive_c)470 axioms.append(disjunctive_c)471 for s in ss:472 disjunctive_c = Clause()473 for i in range(len(hs)):474 disjunctive_c.add_literal(make_literal(make_einstein_prop(s=s, h=hs[i])))475 for j in range(i+1, len(hs)):476 exclusive_c = Clause()477 exclusive_c.add_literal(make_literal(make_einstein_prop(s=s, h=hs[i]), negated=True))478 exclusive_c.add_literal(make_literal(make_einstein_prop(s=s, h=hs[j]), negated=True))479 axioms.append(exclusive_c)480 axioms.append(disjunctive_c)481 # Pet482 else:483 # PH484 for h in hs:485 disjunctive_c = Clause()486 for i in range(len(ps)):487 disjunctive_c.add_literal(make_literal(make_einstein_prop(p=ps[i], h=h)))488 for j in range(i+1, len(ps)):489 exclusive_c = Clause()490 exclusive_c.add_literal(make_literal(make_einstein_prop(p=ps[i], h=h), negated=True))491 exclusive_c.add_literal(make_literal(make_einstein_prop(p=ps[j], h=h), negated=True))492 axioms.append(exclusive_c)493 axioms.append(disjunctive_c)494 for p in ps:495 disjunctive_c = Clause()496 for i in range(len(hs)):497 disjunctive_c.add_literal(make_literal(make_einstein_prop(p=p, h=hs[i])))498 for j in range(i+1, len(hs)):499 exclusive_c = Clause()500 exclusive_c.add_literal(make_literal(make_einstein_prop(p=p, h=hs[i]), negated=True))501 exclusive_c.add_literal(make_literal(make_einstein_prop(p=p, h=hs[j]), negated=True))502 axioms.append(exclusive_c)503 axioms.append(disjunctive_c)504 return axioms505# TODO Implement consistency axioms, which should say that (p_{n,c} and p_{n, p}) \implies p_{c, p}) 506# I.e. (\neg p_{n, c} \vee \neg p_{n, p} \vee p_{c, p}) for all combinations of pairs507def make_consistency_axioms():508 axioms = []509 for i in range(5):510 for j in range(5):511 for k in range(5):512 # NC513 c = Clause()514 c.add_literal(make_literal(make_einstein_prop(n=Nationality(j), h=i), negated=True))515 c.add_literal(make_literal(make_einstein_prop(c=Color(k), h=i), negated=True))516 c.add_literal(make_literal(make_einstein_prop(n=Nationality(j), c=Color(k))))517 axioms.append(c)518 # NB519 c = Clause()520 c.add_literal(make_literal(make_einstein_prop(n=Nationality(j), h=i), negated=True))521 c.add_literal(make_literal(make_einstein_prop(b=Beverage(k), h=i), negated=True))522 c.add_literal(make_literal(make_einstein_prop(n=Nationality(j), b=Beverage(k))))523 axioms.append(c)524 525 # NS526 c = Clause()527 c.add_literal(make_literal(make_einstein_prop(n=Nationality(j), h=i), negated=True))528 c.add_literal(make_literal(make_einstein_prop(s=Cigar(k), h=i), negated=True))529 c.add_literal(make_literal(make_einstein_prop(n=Nationality(j), s=Cigar(k))))530 axioms.append(c)531 # NP532 c = Clause()533 c.add_literal(make_literal(make_einstein_prop(n=Nationality(j), h=i), negated=True))534 c.add_literal(make_literal(make_einstein_prop(p=Pet(k), h=i), negated=True))535 c.add_literal(make_literal(make_einstein_prop(n=Nationality(j), p=Pet(k))))536 axioms.append(c)537 # CB538 c = Clause()539 c.add_literal(make_literal(make_einstein_prop(c=Color(j), h=i), negated=True))540 c.add_literal(make_literal(make_einstein_prop(b=Beverage(k), h=i), negated=True))541 c.add_literal(make_literal(make_einstein_prop(c=Color(j), b=Beverage(k))))542 axioms.append(c)543 # CS544 c = Clause()545 c.add_literal(make_literal(make_einstein_prop(c=Color(j), h=i), negated=True))546 c.add_literal(make_literal(make_einstein_prop(s=Cigar(k), h=i), negated=True))547 c.add_literal(make_literal(make_einstein_prop(c=Color(j), s=Cigar(k))))548 axioms.append(c)549 # CP550 c = Clause()551 c.add_literal(make_literal(make_einstein_prop(c=Color(j), h=i), negated=True))552 c.add_literal(make_literal(make_einstein_prop(p=Pet(k), h=i), negated=True))553 c.add_literal(make_literal(make_einstein_prop(c=Color(j), p=Pet(k))))554 axioms.append(c)555 # BS556 c = Clause()557 c.add_literal(make_literal(make_einstein_prop(b=Beverage(j), h=i), negated=True))558 c.add_literal(make_literal(make_einstein_prop(s=Cigar(k), h=i), negated=True))559 c.add_literal(make_literal(make_einstein_prop(b=Beverage(j), s=Cigar(k))))560 axioms.append(c)561 # BP562 c = Clause()563 c.add_literal(make_literal(make_einstein_prop(b=Beverage(j), h=i), negated=True))564 c.add_literal(make_literal(make_einstein_prop(p=Pet(k), h=i), negated=True))565 c.add_literal(make_literal(make_einstein_prop(b=Beverage(j), p=Pet(k))))566 axioms.append(c)567 # SP568 c = Clause()569 c.add_literal(make_literal(make_einstein_prop(s=Cigar(j), h=i), negated=True))570 c.add_literal(make_literal(make_einstein_prop(p=Pet(k), h=i), negated=True))571 c.add_literal(make_literal(make_einstein_prop(s=Cigar(j), p=Pet(k))))572 axioms.append(c)573 return axioms574def make_einstein_axioms():575 axioms = []576 ## Basic exclusion axioms577 ns = [Nationality.brit, Nationality.swede, Nationality.dane, Nationality.norwegian, Nationality.german]578 cs = [Color.red, Color.green, Color.yellow, Color.blue, Color.white]579 bs = [Beverage.tea, Beverage.coffee, Beverage.milk, Beverage.beer, Beverage.water]580 ss = [Cigar.pallmall, Cigar.dunhill, Cigar.blends, Cigar.bluemasters, Cigar.prince]581 ps = [Pet.dogs, Pet.birds, Pet.cats, Pet.horse, Pet.fish]582 hs = [0, 1, 2, 3, 4]583 axioms = axioms + make_exclusion_axioms(ns=ns, cs=cs)584 axioms = axioms + make_exclusion_axioms(ns=ns, bs=bs)585 axioms = axioms + make_exclusion_axioms(ns=ns, ss=ss)586 axioms = axioms + make_exclusion_axioms(ns=ns, ps=ps)587 axioms = axioms + make_exclusion_axioms(ns=ns, hs=hs)588 axioms = axioms + make_exclusion_axioms(cs=cs, bs=bs)589 axioms = axioms + make_exclusion_axioms(cs=cs, ss=ss)590 axioms = axioms + make_exclusion_axioms(cs=cs, ps=ps)591 axioms = axioms + make_exclusion_axioms(cs=cs, hs=hs)592 axioms = axioms + make_exclusion_axioms(bs=bs, ss=ss)593 axioms = axioms + make_exclusion_axioms(bs=bs, ps=ps)594 axioms = axioms + make_exclusion_axioms(bs=bs, hs=hs)595 axioms = axioms + make_exclusion_axioms(ss=ss, ps=ps)596 axioms = axioms + make_exclusion_axioms(ss=ss, hs=hs)597 axioms = axioms + make_exclusion_axioms(ps=ps, hs=hs)598 599 # Consistency axioms600 axioms = axioms + make_consistency_axioms()601 ## Fifteen facts602 # Brit lives in red house603 c1 = Clause()604 c1.add_literal(make_literal(make_einstein_prop(n=Nationality.brit, c=Color.red)))605 axioms.append(c1)606 # Swede keeps dogs607 c2 = Clause()608 c2.add_literal(make_literal(make_einstein_prop(n=Nationality.swede, p=Pet.dogs)))609 axioms.append(c2)610 # Dane drinks tea611 c3 = Clause()612 c3.add_literal(make_literal(make_einstein_prop(n=Nationality.dane, b=Beverage.tea)))613 axioms.append(c3)614 # Green house on the left of white house615 c4 = Clause()616 c4.add_literal(make_literal(make_einstein_prop(c=Color.white, h=1), negated=True))617 axioms.append(c4)618 c4 = Clause()619 c4.add_literal(make_literal(make_einstein_prop(c=Color.white, h=2), negated=True))620 c4.add_literal(make_literal(make_einstein_prop(c=Color.green, h=1)))621 axioms.append(c4)622 c4 = Clause()623 c4.add_literal(make_literal(make_einstein_prop(c=Color.white, h=3), negated=True))624 c4.add_literal(make_literal(make_einstein_prop(c=Color.green, h=2)))625 c4.add_literal(make_literal(make_einstein_prop(c=Color.green, h=1)))626 axioms.append(c4)627 c4 = Clause()628 c4.add_literal(make_literal(make_einstein_prop(c=Color.white, h=4), negated=True))629 c4.add_literal(make_literal(make_einstein_prop(c=Color.green, h=3)))630 c4.add_literal(make_literal(make_einstein_prop(c=Color.green, h=2)))631 c4.add_literal(make_literal(make_einstein_prop(c=Color.green, h=1)))632 axioms.append(c4)633 c4 = Clause()634 c4.add_literal(make_literal(make_einstein_prop(c=Color.white, h=5), negated=True))635 c4.add_literal(make_literal(make_einstein_prop(c=Color.green, h=4)))636 c4.add_literal(make_literal(make_einstein_prop(c=Color.green, h=3)))637 c4.add_literal(make_literal(make_einstein_prop(c=Color.green, h=2)))638 c4.add_literal(make_literal(make_einstein_prop(c=Color.green, h=1)))639 axioms.append(c4)640 # Green house's owner drinks coffee641 c5 = Clause()642 c5.add_literal(make_literal(make_einstein_prop(c=Color.green, b=Beverage.coffee)))643 axioms.append(c5)644 645 # Person who smokes Pall Mall drinks coffee646 c6 = Clause()647 c6.add_literal(make_literal(make_einstein_prop(s=Cigar.pallmall, p=Pet.birds)))648 axioms.append(c6)649 # The owner of the yellow house smokes Dunhill650 c7 = Clause()651 c7.add_literal(make_literal(make_einstein_prop(c=Color.yellow, s=Cigar.dunhill)))652 axioms.append(c7)653 # The man living in the center house drinks milk654 c8 = Clause()655 c8.add_literal(make_literal(make_einstein_prop(b=Beverage.milk, h=2)))656 axioms.append(c8)657 # The Norwegian lives in the first house658 c9 = Clause()659 c9.add_literal(make_literal(make_einstein_prop(n=Nationality.norwegian, h=0)))660 axioms.append(c9)661 # The man who smokes Blends lives next to the one who keeps cats662 c10 = Clause()663 c10.add_literal(make_literal(make_einstein_prop(s=Cigar.blends, h=0), negated=True))664 c10.add_literal(make_literal(make_einstein_prop(p=Pet.cats, h=1)))665 axioms.append(c10)666 c10 = Clause()667 c10.add_literal(make_literal(make_einstein_prop(s=Cigar.blends, h=1)))668 c10.add_literal(make_literal(make_einstein_prop(p=Pet.cats, h=0), negated=True))669 axioms.append(c10)670 c10 = Clause()671 c10.add_literal(make_literal(make_einstein_prop(s=Cigar.blends, h=4), negated=True))672 c10.add_literal(make_literal(make_einstein_prop(p=Pet.cats, h=3)))673 axioms.append(c10)674 c10 = Clause()675 c10.add_literal(make_literal(make_einstein_prop(s=Cigar.blends, h=3)))676 c10.add_literal(make_literal(make_einstein_prop(p=Pet.cats, h=4), negated=True))677 axioms.append(c10)678 c10 = Clause()679 c10.add_literal(make_literal(make_einstein_prop(s=Cigar.blends, h=1), negated=True))680 c10.add_literal(make_literal(make_einstein_prop(p=Pet.cats, h=0)))681 c10.add_literal(make_literal(make_einstein_prop(p=Pet.cats, h=2)))682 axioms.append(c10)683 c10 = Clause()684 c10.add_literal(make_literal(make_einstein_prop(s=Cigar.blends, h=2), negated=True))685 c10.add_literal(make_literal(make_einstein_prop(p=Pet.cats, h=1)))686 c10.add_literal(make_literal(make_einstein_prop(p=Pet.cats, h=3)))687 axioms.append(c10)688 c10 = Clause()689 c10.add_literal(make_literal(make_einstein_prop(s=Cigar.blends, h=3), negated=True))690 c10.add_literal(make_literal(make_einstein_prop(p=Pet.cats, h=2)))691 c10.add_literal(make_literal(make_einstein_prop(p=Pet.cats, h=4)))692 axioms.append(c10)693 # The man who keeps the horse lives next to the man who smokes Dunhill694 c11 = Clause()695 c11.add_literal(make_literal(make_einstein_prop(p=Pet.horse, h=0), negated=True))696 c11.add_literal(make_literal(make_einstein_prop(s=Cigar.dunhill, h=1)))697 axioms.append(c11)698 c11 = Clause()699 c11.add_literal(make_literal(make_einstein_prop(p=Pet.horse, h=1)))700 c11.add_literal(make_literal(make_einstein_prop(s=Cigar.dunhill, h=0), negated=True))701 axioms.append(c11)702 c11 = Clause()703 c11.add_literal(make_literal(make_einstein_prop(p=Pet.horse, h=4), negated=True))704 c11.add_literal(make_literal(make_einstein_prop(s=Cigar.dunhill, h=3)))705 axioms.append(c11)706 c11 = Clause()707 c11.add_literal(make_literal(make_einstein_prop(p=Pet.horse, h=3)))708 c11.add_literal(make_literal(make_einstein_prop(s=Cigar.dunhill, h=4), negated=True))709 axioms.append(c11)710 c11 = Clause()711 c11.add_literal(make_literal(make_einstein_prop(p=Pet.horse, h=1), negated=True))712 c11.add_literal(make_literal(make_einstein_prop(s=Cigar.dunhill, h=0)))713 c11.add_literal(make_literal(make_einstein_prop(s=Cigar.dunhill, h=2)))714 axioms.append(c11)715 c11 = Clause()716 c11.add_literal(make_literal(make_einstein_prop(p=Pet.horse, h=2), negated=True))717 c11.add_literal(make_literal(make_einstein_prop(s=Cigar.dunhill, h=1)))718 c11.add_literal(make_literal(make_einstein_prop(s=Cigar.dunhill, h=3)))719 axioms.append(c11)720 c11 = Clause()721 c11.add_literal(make_literal(make_einstein_prop(p=Pet.horse, h=3), negated=True))722 c11.add_literal(make_literal(make_einstein_prop(s=Cigar.dunhill, h=2)))723 c11.add_literal(make_literal(make_einstein_prop(s=Cigar.dunhill, h=4)))724 axioms.append(c11)725 # The owner who smokes Bluemasters drinks beer726 c12 = Clause()727 c12.add_literal(make_literal(make_einstein_prop(b=Beverage.beer, s=Cigar.bluemasters)))728 axioms.append(c12)729 # The German smokes Prince730 c13 = Clause()731 c13.add_literal(make_literal(make_einstein_prop(n=Nationality.german, s=Cigar.prince)))732 axioms.append(c13)733 # The Norwegian lives next to the blue house734 c14 = Clause()735 c14.add_literal(make_literal(make_einstein_prop(n=Nationality.norwegian, h=0), negated=True))736 c14.add_literal(make_literal(make_einstein_prop(c=Color.blue, h=1)))737 axioms.append(c14)738 c14 = Clause()739 c14.add_literal(make_literal(make_einstein_prop(n=Nationality.norwegian, h=1)))740 c14.add_literal(make_literal(make_einstein_prop(c=Color.blue, h=0), negated=True))741 axioms.append(c14)742 c14 = Clause()743 c14.add_literal(make_literal(make_einstein_prop(n=Nationality.norwegian, h=4), negated=True))744 c14.add_literal(make_literal(make_einstein_prop(c=Color.blue, h=3)))745 axioms.append(c14)746 c14 = Clause()747 c14.add_literal(make_literal(make_einstein_prop(n=Nationality.norwegian, h=3)))748 c14.add_literal(make_literal(make_einstein_prop(c=Color.blue, h=4), negated=True))749 axioms.append(c14)750 c14 = Clause()751 c14.add_literal(make_literal(make_einstein_prop(n=Nationality.norwegian, h=1), negated=True))752 c14.add_literal(make_literal(make_einstein_prop(c=Color.blue, h=0)))753 c14.add_literal(make_literal(make_einstein_prop(c=Color.blue, h=2)))754 axioms.append(c14)755 c14 = Clause()756 c14.add_literal(make_literal(make_einstein_prop(n=Nationality.norwegian, h=2), negated=True))757 c14.add_literal(make_literal(make_einstein_prop(c=Color.blue, h=1)))758 c14.add_literal(make_literal(make_einstein_prop(c=Color.blue, h=3)))759 axioms.append(c14)760 c14 = Clause()761 c14.add_literal(make_literal(make_einstein_prop(n=Nationality.norwegian, h=3), negated=True))762 c14.add_literal(make_literal(make_einstein_prop(c=Color.blue, h=2)))763 c14.add_literal(make_literal(make_einstein_prop(c=Color.blue, h=4)))764 axioms.append(c14)765 # The man who smokes Blends has a neighbor who drinks water766 c15 = Clause()767 c15.add_literal(make_literal(make_einstein_prop(s=Cigar.blends, h=0), negated=True))768 c15.add_literal(make_literal(make_einstein_prop(b=Beverage.water, h=1)))769 axioms.append(c15)770 c15 = Clause()771 c15.add_literal(make_literal(make_einstein_prop(s=Cigar.blends, h=1)))772 c15.add_literal(make_literal(make_einstein_prop(b=Beverage.water, h=0), negated=True))773 axioms.append(c15)774 c15 = Clause()775 c15.add_literal(make_literal(make_einstein_prop(s=Cigar.blends, h=4), negated=True))776 c15.add_literal(make_literal(make_einstein_prop(b=Beverage.water, h=3)))777 axioms.append(c15)778 c15 = Clause()779 c15.add_literal(make_literal(make_einstein_prop(s=Cigar.blends, h=3)))780 c15.add_literal(make_literal(make_einstein_prop(b=Beverage.water, h=4), negated=True))781 axioms.append(c15)782 c15 = Clause()783 c15.add_literal(make_literal(make_einstein_prop(s=Cigar.blends, h=1), negated=True))784 c15.add_literal(make_literal(make_einstein_prop(b=Beverage.water, h=0)))785 c15.add_literal(make_literal(make_einstein_prop(b=Beverage.water, h=2)))786 axioms.append(c15)787 c15 = Clause()788 c15.add_literal(make_literal(make_einstein_prop(s=Cigar.blends, h=2), negated=True))789 c15.add_literal(make_literal(make_einstein_prop(b=Beverage.water, h=1)))790 c15.add_literal(make_literal(make_einstein_prop(b=Beverage.water, h=3)))791 axioms.append(c15)792 c15 = Clause()793 c15.add_literal(make_literal(make_einstein_prop(s=Cigar.blends, h=3), negated=True))794 c15.add_literal(make_literal(make_einstein_prop(b=Beverage.water, h=2)))795 c15.add_literal(make_literal(make_einstein_prop(b=Beverage.water, h=4)))796 axioms.append(c15)797 return axioms798def run():799 assert(make_einstein_prop(n=Nationality.brit, c=Color.red) == 0)800 assert(make_einstein_prop(c=Color.red, b=Beverage.tea) == 125)801 assert(make_einstein_prop(b=Beverage.tea, s=Cigar.pallmall) == 225)802 assert(make_einstein_prop(s=Cigar.pallmall, p=Pet.dogs) == 300)803 assert(make_einstein_prop(p=Pet.dogs, h=0) == 350)804 assert(make_einstein_prop(p=Pet.fish, h=4) == 374)805 axioms = make_einstein_axioms()806 print("p cnf 375 {}".format(len(axioms)))807 for a in axioms:808 print(a)809if __name__ == "__main__":...
08.py
Source:08.py
1test = {2 'name': 'Problem 8',3 'points': 2,4 'suites': [5 {6 'cases': [7 {8 'answer': 'a list of restaurants reviewed by the user',9 'choices': [10 'a list of restaurants reviewed by the user',11 'a list of all possible restaurants',12 'a list of ratings for restaurants reviewed by the user'13 ],14 'hidden': False,15 'locked': False,16 'question': r"""17 In the starter code for best_predictor, what does the18 variable reviewed represent?19 """20 },21 {22 'answer': 'a predictor function and its r_squared value',23 'choices': [24 'a predictor function and its r_squared value',25 'a predictor function',26 'an r_squared value',27 'a restaurant'28 ],29 'hidden': False,30 'locked': False,31 'question': r"""32 Given a user, a list of restaurants, and a feature function, what33 does find_predictor from Problem 7 return?34 """35 },36 {37 'answer': 'the predictor with the highest r_squared value',38 'choices': [39 'the predictor with the highest r_squared value',40 'the predictor with the lowest r_squared value',41 'the first predictor in the list',42 'an arbitrary predictor'43 ],44 'hidden': False,45 'locked': False,46 'question': r"""47 After computing a list of [predictor, r_squared] pairs,48 which predictor should we select?49 """50 }51 ],52 'scored': False,53 'type': 'concept'54 },55 {56 'cases': [57 {58 'code': r"""59 >>> user = make_user('Cheapskate', [60 ... make_review('A', 2),61 ... make_review('B', 5),62 ... make_review('C', 2),63 ... make_review('D', 5),64 ... ])65 >>> cluster = [66 ... make_restaurant('A', [5, 2], [], 4, [67 ... make_review('A', 5)68 ... ]),69 ... make_restaurant('B', [3, 2], [], 2, [70 ... make_review('B', 5)71 ... ]),72 ... make_restaurant('C', [-2, 6], [], 4, [73 ... make_review('C', 4)74 ... ]),75 ... make_restaurant('D', [4, 2], [], 2, [76 ... make_review('D', 3),77 ... make_review('D', 4)78 ... ]),79 ... ]80 >>> fns = [restaurant_price, lambda r: mean(restaurant_ratings(r))]81 >>> pred = best_predictor(user, cluster, fns)82 >>> [round(pred(r), 5) for r in cluster] # should be a list of decimals83 [2.0, 5.0, 2.0, 5.0]84 """,85 'hidden': False,86 'locked': False87 },88 {89 'code': r"""90 >>> user = make_user('Cheapskate', [91 ... make_review('A', 2),92 ... make_review('B', 5),93 ... make_review('C', 2),94 ... make_review('D', 5),95 ... ])96 >>> cluster = [97 ... make_restaurant('A', [5, 2], [], 4, [98 ... make_review('A', 5)99 ... ]),100 ... make_restaurant('B', [3, 2], [], 2, [101 ... make_review('B', 5)102 ... ]),103 ... make_restaurant('C', [-2, 6], [], 4, [104 ... make_review('C', 4)105 ... ]),106 ... ]107 >>> fns = [restaurant_price, lambda r: mean(restaurant_ratings(r))]108 >>> pred = best_predictor(user, cluster, fns)109 >>> [round(pred(r), 5) for r in cluster]110 [2.0, 5.0, 2.0]111 """,112 'hidden': False,113 'locked': False114 },115 {116 'code': r"""117 >>> user = make_user('Cheapskate', [118 ... make_review('A', 2),119 ... make_review('B', 5),120 ... make_review('C', 2),121 ... make_review('D', 5),122 ... ])123 >>> cluster = [124 ... make_restaurant('A', [5, 2], [], 4, [125 ... make_review('A', 5)126 ... ]),127 ... make_restaurant('B', [3, 2], [], 2, [128 ... make_review('B', 5)129 ... ]),130 ... make_restaurant('C', [-2, 6], [], 4, [131 ... make_review('C', 4)132 ... ]),133 ... ]134 >>> fns = [lambda r: mean(restaurant_ratings(r)), restaurant_price]135 >>> pred = best_predictor(user, cluster, fns)136 >>> [round(pred(r), 5) for r in cluster] # Make sure you're iterating through feature_fns!137 [2.0, 5.0, 2.0]138 """,139 'hidden': False,140 'locked': False141 },142 {143 'code': r"""144 >>> user = make_user('Cheapskate', [145 ... make_review('A', 2),146 ... make_review('B', 5),147 ... make_review('C', 2),148 ... make_review('D', 5),149 ... ])150 >>> cluster = [151 ... make_restaurant('A', [5, 2], [], 4, [152 ... make_review('A', 5)153 ... ]),154 ... make_restaurant('B', [3, 2], [], 2, [155 ... make_review('B', 5)156 ... ]),157 ... make_restaurant('C', [-2, 6], [], 4, [158 ... make_review('C', 4)159 ... ]),160 ... make_restaurant('E', [1, 2], [], 4, [161 ... make_review('E', 4)162 ... ]),163 ... ]164 >>> fns = [lambda r: mean(restaurant_ratings(r)), restaurant_price]165 >>> pred = best_predictor(user, cluster, fns) # Make sure you're only using user-reviewed restaurants!166 >>> [round(pred(r), 5) for r in cluster]167 [2.0, 5.0, 2.0, 2.0]168 """,169 'hidden': False,170 'locked': False171 }172 ],173 'scored': True,174 'setup': r"""175 >>> import tests.test_functions as test176 >>> from recommend import *177 """,178 'teardown': '',179 'type': 'doctest'180 },181 {182 'cases': [183 {184 'code': r"""185 >>> user = make_user('Cheapskate', [186 ... make_review('A', 2),187 ... make_review('B', 5),188 ... make_review('C', 2),189 ... make_review('D', 5),190 ... ])191 >>> cluster = [192 ... make_restaurant('A', [5, 2], [], 4, [193 ... make_review('A', 5)194 ... ]),195 ... make_restaurant('B', [3, 2], [], 2, [196 ... make_review('B', 5)197 ... ]),198 ... make_restaurant('C', [-2, 6], [], 4, [199 ... make_review('C', 4)200 ... ]),201 ... make_restaurant('D', [4, 2], [], 2, [202 ... make_review('D', 3),203 ... make_review('D', 4)204 ... ]),205 ... ]206 >>> fns = [restaurant_price, lambda r: mean(restaurant_ratings(r))]207 >>> pred = best_predictor(user, cluster, fns)208 >>> # Hint: Price is a perfect predictor of this user's ratings,209 >>> # so the predicted ratings should equal the user's ratings210 >>> [round(pred(r), 5) for r in cluster] # should be a list of decimals211 [2.0, 5.0, 2.0, 5.0]212 """,213 'hidden': False,214 'locked': False215 },216 {217 'code': r"""218 >>> user = make_user('Cheapskate', [219 ... make_review('A', 2),220 ... make_review('B', 5),221 ... make_review('C', 2),222 ... make_review('D', 5),223 ... ])224 >>> cluster = [225 ... make_restaurant('A', [5, 2], [], 4, [226 ... make_review('A', 5)227 ... ]),228 ... make_restaurant('B', [3, 2], [], 2, [229 ... make_review('B', 5)230 ... ]),231 ... make_restaurant('C', [-2, 6], [], 4, [232 ... make_review('C', 4)233 ... ]),234 ... ]235 >>> fns = [restaurant_price, lambda r: mean(restaurant_ratings(r))]236 >>> pred = best_predictor(user, cluster, fns)237 >>> [round(pred(r), 5) for r in cluster]238 [2.0, 5.0, 2.0]239 """,240 'hidden': False,241 'locked': False242 },243 {244 'code': r"""245 >>> user = make_user('Cheapskate', [246 ... make_review('A', 2),247 ... make_review('B', 5),248 ... make_review('C', 2),249 ... make_review('D', 5),250 ... ])251 >>> cluster = [252 ... make_restaurant('A', [5, 2], [], 4, [253 ... make_review('A', 5)254 ... ]),255 ... make_restaurant('B', [3, 2], [], 2, [256 ... make_review('B', 5)257 ... ]),258 ... make_restaurant('C', [-2, 6], [], 4, [259 ... make_review('C', 4)260 ... ]),261 ... ]262 >>> fns = [lambda r: mean(restaurant_ratings(r)), restaurant_price]263 >>> pred = best_predictor(user, cluster, fns)264 >>> [round(pred(r), 5) for r in cluster] # Make sure you're iterating through feature_fns!265 [2.0, 5.0, 2.0]266 """,267 'hidden': False,268 'locked': False269 },270 {271 'code': r"""272 >>> user = make_user('Cheapskate', [273 ... make_review('A', 2),274 ... make_review('B', 5),275 ... make_review('C', 2),276 ... make_review('D', 5),277 ... ])278 >>> cluster = [279 ... make_restaurant('A', [5, 2], [], 4, [280 ... make_review('A', 5)281 ... ]),282 ... make_restaurant('B', [3, 2], [], 2, [283 ... make_review('B', 5)284 ... ]),285 ... make_restaurant('C', [-2, 6], [], 4, [286 ... make_review('C', 4)287 ... ]),288 ... make_restaurant('E', [1, 2], [], 4, [289 ... make_review('E', 4)290 ... ]),291 ... ]292 >>> fns = [lambda r: mean(restaurant_ratings(r)), restaurant_price]293 >>> pred = best_predictor(user, cluster, fns) # Make sure you're only using user-reviewed restaurants!294 >>> [round(pred(r), 5) for r in cluster]295 [2.0, 5.0, 2.0, 2.0]296 """,297 'hidden': False,298 'locked': False299 }300 ],301 'scored': True,302 'setup': r"""303 >>> import tests.test_functions as test304 >>> import recommend305 >>> test.swap_implementations(recommend)306 >>> from recommend import *307 """,308 'teardown': r"""309 >>> test.restore_implementations(recommend)310 """,311 'type': 'doctest'312 }313 ]...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!