-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into remove-respondent-dict
- Loading branch information
Showing
9 changed files
with
338 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import logging | ||
from uuid import UUID | ||
|
||
import structlog | ||
from flask import session | ||
from sqlalchemy.orm.exc import NoResultFound | ||
|
||
from ras_party.controllers.queries import ( | ||
query_respondent_by_party_uuid, | ||
query_respondent_enrolments, | ||
) | ||
from ras_party.models.models import Enrolment | ||
from ras_party.support.session_decorator import with_query_only_db_session | ||
|
||
logger = structlog.wrap_logger(logging.getLogger(__name__)) | ||
|
||
|
||
@with_query_only_db_session | ||
def respondent_enrolments( | ||
session: session, party_uuid: UUID, business_id: UUID = None, survey_id: UUID = None, status: int = None | ||
) -> list[Enrolment]: | ||
""" | ||
returns a list of respondent Enrolments. Business_id, survey_id and status can also be added as conditions | ||
""" | ||
|
||
respondent = query_respondent_by_party_uuid(party_uuid, session) | ||
if not respondent: | ||
raise NoResultFound | ||
|
||
return query_respondent_enrolments(session, respondent.id, business_id, survey_id, status) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import logging | ||
from uuid import UUID | ||
|
||
import structlog | ||
from flask import Blueprint, Response, current_app, make_response, request | ||
from flask_httpauth import HTTPBasicAuth | ||
from sqlalchemy.exc import DataError | ||
from sqlalchemy.orm.exc import NoResultFound | ||
from werkzeug.exceptions import BadRequest, NotFound | ||
|
||
from ras_party.controllers.enrolments_controller import respondent_enrolments | ||
from ras_party.uuid_helper import is_valid_uuid4 | ||
|
||
logger = structlog.wrap_logger(logging.getLogger(__name__)) | ||
enrolments_view = Blueprint("enrolments_view", __name__) | ||
auth = HTTPBasicAuth() | ||
|
||
|
||
@enrolments_view.before_request | ||
@auth.login_required | ||
def before_respondent_view(): | ||
pass | ||
|
||
|
||
@auth.get_password | ||
def get_pw(username): | ||
config_username = current_app.config["SECURITY_USER_NAME"] | ||
config_password = current_app.config["SECURITY_USER_PASSWORD"] | ||
if username == config_username: | ||
return config_password | ||
|
||
|
||
@enrolments_view.route("/respondent/<party_uuid>", methods=["GET"]) | ||
def get_respondent_enrolments(party_uuid: UUID) -> Response: | ||
json = request.get_json() | ||
business_id = json.get("business_id") | ||
survey_id = json.get("survey_id") | ||
status = json.get("status") | ||
|
||
if not is_valid_uuid4(party_uuid): | ||
logger.error(f"party_id not a valid uuid {party_uuid}") | ||
return BadRequest() | ||
|
||
try: | ||
enrolments = respondent_enrolments( | ||
party_uuid=party_uuid, business_id=business_id, survey_id=survey_id, status=status | ||
) | ||
except NoResultFound: | ||
logger.error(f"Respondent not found for party_uuid {party_uuid}") | ||
return NotFound() | ||
except DataError: | ||
logger.error( | ||
"Data error, enrolment search parameters are not valid", | ||
party_uuid=party_uuid, | ||
business_id=business_id, | ||
survey_id=survey_id, | ||
status=status, | ||
) | ||
return BadRequest() | ||
|
||
return make_response([enrolment.to_dict() for enrolment in enrolments], 200) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
from test.party_client import PartyTestClient | ||
|
||
from sqlalchemy.exc import DataError | ||
from sqlalchemy.orm.exc import NoResultFound | ||
|
||
from ras_party.controllers.enrolments_controller import respondent_enrolments | ||
from ras_party.models.models import ( | ||
Business, | ||
BusinessRespondent, | ||
Enrolment, | ||
EnrolmentStatus, | ||
Respondent, | ||
) | ||
from ras_party.support.session_decorator import with_db_session | ||
|
||
respondents_enrolments = [ | ||
{ | ||
"respondent": "b6f9d6e8-b840-4c95-a6ce-9ef145dd1f85", | ||
"enrolment_details": [ | ||
{ | ||
"business": "75d9af56-1225-4d43-b41d-1199f5f89daa", | ||
"survey_id": "9200d295-9d6e-41fe-b541-747ae67a279f", | ||
"status": EnrolmentStatus.ENABLED, | ||
}, | ||
{ | ||
"business": "98e2c9dd-a760-47dd-ba18-439fd5fb93a3", | ||
"survey_id": "c641f6ad-a5eb-4d82-a647-7cd586549bbc", | ||
"status": EnrolmentStatus.ENABLED, | ||
}, | ||
], | ||
}, | ||
{ | ||
"respondent": "5718649e-30bf-4c25-a2c0-aaa733e54ed6", | ||
"enrolment_details": [ | ||
{ | ||
"business": "af25c9d5-6893-4342-9d24-4b88509e965f", | ||
"survey_id": "9200d295-9d6e-41fe-b541-747ae67a279f", | ||
"status": EnrolmentStatus.ENABLED, | ||
}, | ||
{ | ||
"business": "75d9af56-1225-4d43-b41d-1199f5f89daa", | ||
"survey_id": "9200d295-9d6e-41fe-b541-747ae67a279f", | ||
"status": EnrolmentStatus.DISABLED, | ||
}, | ||
], | ||
}, | ||
] | ||
|
||
|
||
class TestEnrolments(PartyTestClient): | ||
|
||
def setUp(self): | ||
self._add_enrolments() | ||
|
||
def test_get_enrolments_party_id(self): | ||
enrolments = respondent_enrolments(party_uuid="b6f9d6e8-b840-4c95-a6ce-9ef145dd1f85") | ||
|
||
self.assertEqual(len(enrolments), 2) | ||
self.assertEqual(str(enrolments[0].business_id), "75d9af56-1225-4d43-b41d-1199f5f89daa") | ||
self.assertEqual(str(enrolments[1].business_id), "98e2c9dd-a760-47dd-ba18-439fd5fb93a3") | ||
|
||
def test_get_enrolments_party_id_and_business_id_and_survey_id(self): | ||
enrolments = respondent_enrolments( | ||
party_uuid="b6f9d6e8-b840-4c95-a6ce-9ef145dd1f85", | ||
business_id="75d9af56-1225-4d43-b41d-1199f5f89daa", | ||
survey_id="9200d295-9d6e-41fe-b541-747ae67a279f", | ||
) | ||
|
||
self.assertEqual(len(enrolments), 1) | ||
self.assertEqual(str(enrolments[0].respondent_id), "1") | ||
self.assertEqual(str(enrolments[0].business_id), "75d9af56-1225-4d43-b41d-1199f5f89daa") | ||
self.assertEqual(str(enrolments[0].survey_id), "9200d295-9d6e-41fe-b541-747ae67a279f") | ||
|
||
def test_get_enrolments_party_id_enabled(self): | ||
enrolments = respondent_enrolments( | ||
party_uuid="5718649e-30bf-4c25-a2c0-aaa733e54ed6", status=EnrolmentStatus.ENABLED | ||
) | ||
|
||
self.assertEqual(len(enrolments), 1) | ||
self.assertEqual(str(enrolments[0].business_id), "af25c9d5-6893-4342-9d24-4b88509e965f") | ||
self.assertEqual(str(enrolments[0].survey_id), "9200d295-9d6e-41fe-b541-747ae67a279f") | ||
|
||
def test_get_enrolments_party_id_disabled(self): | ||
enrolments = respondent_enrolments( | ||
party_uuid="5718649e-30bf-4c25-a2c0-aaa733e54ed6", status=EnrolmentStatus.DISABLED | ||
) | ||
|
||
self.assertEqual(len(enrolments), 1) | ||
self.assertEqual(str(enrolments[0].business_id), "75d9af56-1225-4d43-b41d-1199f5f89daa") | ||
self.assertEqual(str(enrolments[0].survey_id), "9200d295-9d6e-41fe-b541-747ae67a279f") | ||
|
||
def test_get_enrolments_party_id_not_found_respondent(self): | ||
with self.assertRaises(NoResultFound): | ||
respondent_enrolments(party_uuid="e6a016da-f7e8-4cb0-88da-9d34a7c1382a") | ||
|
||
def test_get_enrolments_party_id_data_error(self): | ||
with self.assertRaises(DataError): | ||
respondent_enrolments(party_uuid="malformed_id") | ||
|
||
@with_db_session | ||
def _add_enrolments(self, session): | ||
businesses = {} | ||
|
||
for respondent_enrolment in respondents_enrolments: | ||
respondent = Respondent(party_uuid=respondent_enrolment["respondent"]) | ||
session.add(respondent) | ||
|
||
for enrolment in respondent_enrolment["enrolment_details"]: | ||
if not (business := businesses.get(enrolment["business"])): | ||
business = Business(party_uuid=enrolment["business"]) | ||
session.add(business) | ||
businesses[enrolment["business"]] = business | ||
|
||
business_respondent = BusinessRespondent(business=business, respondent=respondent) | ||
session.add(business_respondent) | ||
session.flush() | ||
enrolment = Enrolment( | ||
business_id=business.party_uuid, | ||
survey_id=enrolment["survey_id"], | ||
respondent_id=respondent.id, | ||
status=enrolment["status"], | ||
) | ||
session.add(enrolment) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import json | ||
from test.party_client import PartyTestClient | ||
from unittest.mock import patch | ||
|
||
from sqlalchemy.exc import DataError | ||
from sqlalchemy.orm.exc import NoResultFound | ||
|
||
from ras_party.models.models import Enrolment, EnrolmentStatus | ||
|
||
|
||
class TestEnrolmentsView(PartyTestClient): | ||
|
||
@patch("ras_party.views.enrolments_view.respondent_enrolments") | ||
def test_get_enrolments(self, respondent_enrolments): | ||
respondent_enrolments.return_value = [ | ||
Enrolment( | ||
business_id="79af714a-ee1d-446c-9f39-763296ec1f05", | ||
survey_id="38553552-7d08-42e4-b86b-06f158c4b95e", | ||
respondent_id=1, | ||
status=EnrolmentStatus.ENABLED, | ||
) | ||
] | ||
response = self.get_respondent_enrolments("b146f595-62a0-4d6d-ba88-ef40cffdf8a7") | ||
|
||
expected_response = [ | ||
{ | ||
"business_id": "79af714a-ee1d-446c-9f39-763296ec1f05", | ||
"survey_id": "38553552-7d08-42e4-b86b-06f158c4b95e", | ||
"status": "ENABLED", | ||
} | ||
] | ||
|
||
self.assertEqual(expected_response, json.loads(response.data)) | ||
|
||
@patch("ras_party.views.enrolments_view.respondent_enrolments") | ||
def test_get_enrolments_not_found_respondent(self, respondent_enrolments): | ||
respondent_enrolments.side_effect = NoResultFound | ||
response = self.get_respondent_enrolments("707778b9-cdb0-467a-9585-ee06bca47e2c") | ||
|
||
self.assertEqual(404, response.status_code) | ||
|
||
@patch("ras_party.views.enrolments_view.respondent_enrolments") | ||
def test_get_enrolments_data_error(self, respondent_enrolments): | ||
respondent_enrolments.side_effect = DataError("InvalidTextRepresentation", "party_uuid", "orig") | ||
response = self.get_respondent_enrolments("malformed_id") | ||
|
||
self.assertEqual(400, response.status_code) | ||
|
||
def test_get_enrolments_no_params(self): | ||
response = self.get_respondent_enrolments({}) | ||
|
||
self.assertEqual(400, response.status_code) |