# Path: redcap/project.py
# class Project(
#     methods.field_names.FieldNames,
#     methods.files.Files,
#     methods.instruments.Instruments,
#     methods.metadata.Metadata,
#     methods.project_info.ProjectInfo,
#     methods.records.Records,
#     methods.reports.Reports,
#     methods.surveys.Surveys,
#     methods.users.Users,
#     methods.version.Version,
# ):
#     """Main class for interacting with REDCap projects
# 
#     Attributes:
#         verify_ssl: Verify SSL, default True. Can pass path to CA_BUNDLE
# 
#     Note:
#         Your REDCap token should be kept **secret**! Treat it like a password
#         and NEVER save it directly in your script/application. Rather it should be obscured
#         and retrieved 'behind the scenes'. For example, saving the token as an environment
#         variable and retrieving it with `os.getenv`. The creation of the `TOKEN` string in
#         the example is not shown, for the above reasons
# 
#     Examples:
#         >>> from redcap import Project
#         >>> URL = "https://redcapdemo.vanderbilt.edu/api/"
#         >>> proj = Project(URL, TOKEN)
#         >>> proj.field_names
#         ['record_id', 'field_1', 'checkbox_field', 'upload_field']
#         >>> proj.is_longitudinal
#         True
#         >>> proj.def_field
#         'record_id'
# 
#         The url and token attributes are read-only, to prevent users from accidentally
#         overwriting them
#         >>> proj.url = "whoops"
#         Traceback (most recent call last):
#         ...
#         AttributeError: can't set attribute
#     """
# 
#     @property
#     def redcap_version(self) -> Optional[semantic_version.Version]:
#         """REDCap version of the Project"""
#         self._redcap_version: Optional[semantic_version.Version]
#         try:
#             return self._redcap_version
#         except AttributeError:
#             self._redcap_version = self.export_version()
#             return self._redcap_version
# 
# Path: tests/unit/callback_utils.py
# def get_survey_project_request_handler(request_type: str) -> Callable:
#     """Given a request type, extract the handler function"""
#     handlers_dict = {
#         "formEventMapping": handle_simple_project_form_event_mapping_request,
#         "metadata": handle_simple_project_metadata_request,
#         "record": handle_survey_project_records_request,
#     }
# 
#     return handlers_dict[request_type]
# 
# def parse_request(req: Request) -> List[Union[dict, str]]:
#     """Extract the body of a request into a dict"""
#     parsed = parse.urlparse(f"?{req.body}")
#     data = parse.parse_qs(parsed.query)
#     headers = {"Content-Type": "application/json"}
# 
#     try:
#         request_type = data["content"][0]
#     except KeyError as missing_key:
#         if " filename" in str(data):
#             # file import doesn't have 'content' key
#             request_type = "file"
#         else:
#             raise missing_key
# 
#     return [data, headers, request_type]


import pytest
import responses
from redcap import Project
from tests.unit.callback_utils import get_survey_project_request_handler, parse_request
#! /usr/bin/env python
"""Test suite for Project class with survey against mocked REDCap server"""
# pylint: disable=missing-function-docstring
# pylint: disable=redefined-outer-name




@pytest.fixture(scope="module")
def survey_project(project_urls, project_token, mocked_responses) -> Project:
    """Mocked simple REDCap project, with survey fields"""

    def request_callback_survey(req):
        request_data, request_headers, request_type = parse_request(req)
        request_handler = get_survey_project_request_handler(request_type)
        response = request_handler(data=request_data, headers=request_headers)
        return response

    survey_project_url = project_urls["survey_project"]
    mocked_responses.add_callback(
        responses.POST,
        survey_project_url,
        callback=request_callback_survey,
        content_type="application/json",
    )

    return Project(survey_project_url, project_token, verify_ssl=False)


def test_init(survey_project):

# Path: redcap/project.py
# class Project(
#     methods.field_names.FieldNames,
#     methods.files.Files,
#     methods.instruments.Instruments,
#     methods.metadata.Metadata,
#     methods.project_info.ProjectInfo,
#     methods.records.Records,
#     methods.reports.Reports,
#     methods.surveys.Surveys,
#     methods.users.Users,
#     methods.version.Version,
# ):
#     """Main class for interacting with REDCap projects
# 
#     Attributes:
#         verify_ssl: Verify SSL, default True. Can pass path to CA_BUNDLE
# 
#     Note:
#         Your REDCap token should be kept **secret**! Treat it like a password
#         and NEVER save it directly in your script/application. Rather it should be obscured
#         and retrieved 'behind the scenes'. For example, saving the token as an environment
#         variable and retrieving it with `os.getenv`. The creation of the `TOKEN` string in
#         the example is not shown, for the above reasons
# 
#     Examples:
#         >>> from redcap import Project
#         >>> URL = "https://redcapdemo.vanderbilt.edu/api/"
#         >>> proj = Project(URL, TOKEN)
#         >>> proj.field_names
#         ['record_id', 'field_1', 'checkbox_field', 'upload_field']
#         >>> proj.is_longitudinal
#         True
#         >>> proj.def_field
#         'record_id'
# 
#         The url and token attributes are read-only, to prevent users from accidentally
#         overwriting them
#         >>> proj.url = "whoops"
#         Traceback (most recent call last):
#         ...
#         AttributeError: can't set attribute
#     """
# 
#     @property
#     def redcap_version(self) -> Optional[semantic_version.Version]:
#         """REDCap version of the Project"""
#         self._redcap_version: Optional[semantic_version.Version]
#         try:
#             return self._redcap_version
#         except AttributeError:
#             self._redcap_version = self.export_version()
#             return self._redcap_version
# 
# Path: tests/unit/callback_utils.py
# def get_survey_project_request_handler(request_type: str) -> Callable:
#     """Given a request type, extract the handler function"""
#     handlers_dict = {
#         "formEventMapping": handle_simple_project_form_event_mapping_request,
#         "metadata": handle_simple_project_metadata_request,
#         "record": handle_survey_project_records_request,
#     }
# 
#     return handlers_dict[request_type]
# 
# def parse_request(req: Request) -> List[Union[dict, str]]:
#     """Extract the body of a request into a dict"""
#     parsed = parse.urlparse(f"?{req.body}")
#     data = parse.parse_qs(parsed.query)
#     headers = {"Content-Type": "application/json"}
# 
#     try:
#         request_type = data["content"][0]
#     except KeyError as missing_key:
#         if " filename" in str(data):
#             # file import doesn't have 'content' key
#             request_type = "file"
#         else:
#             raise missing_key
# 
#     return [data, headers, request_type]


# Path: tests/unit/test_survey_project.py
import pytest
import responses
from redcap import Project
from tests.unit.callback_utils import get_survey_project_request_handler, parse_request

#! /usr/bin/env python
"""Test suite for Project class with survey against mocked REDCap server"""
# pylint: disable=missing-function-docstring
# pylint: disable=redefined-outer-name




@pytest.fixture(scope="module")
def survey_project(project_urls, project_token, mocked_responses) -> Project:
    """Mocked simple REDCap project, with survey fields"""

    def request_callback_survey(req):
        request_data, request_headers, request_type = parse_request(req)
        request_handler = get_survey_project_request_handler(request_type)
        response = request_handler(data=request_data, headers=request_headers)
        return response

    survey_project_url = project_urls["survey_project"]
    mocked_responses.add_callback(
        responses.POST,
        survey_project_url,
        callback=request_callback_survey,
        content_type="application/json",
    )

    return Project(survey_project_url, project_token, verify_ssl=False)


def test_init(survey_project):

    assert isinstance(survey_project, Project)