def test_dictionary_consolidates_duplicate_entries(self):

        yes_or_no_dict_array = [
            {"label": {"French": "Oui", "English": "Yes"}, "name": "yes"},
            {"label": {"French": "Non", "English": "No"}, "name": "no"},
        ]

        first_yesno_question = MultipleChoiceQuestion(
            name="yn_q1", options=yes_or_no_dict_array, type="select one"
        )
        second_yesno_question = MultipleChoiceQuestion(
            name="yn_q2", options=yes_or_no_dict_array, type="select one"
        )

        s = Survey(name="yes_or_no_tests")
        s.add_child(first_yesno_question)
        s.add_child(second_yesno_question)

        # begin the processes in survey.to_xml()
        # 1. validate()
        s.validate()
Beispiel #2
0
class FloipSurvey(object):
    """
    Converter of a FLOIP Result descriptor to Openrosa XForm.
    """
    def __init__(self, descriptor=None, title=None, id_string=None):
        # Seek to begining of file if it has the seek attribute before loading
        # the file.
        if hasattr(descriptor, 'seek'):
            descriptor.seek(0)
        try:
            # descriptor is a file
            self.descriptor = json.load(descriptor)
        except AttributeError:
            try:
                # descriptor is a JSON string
                self.descriptor = json.loads(descriptor)
            except JSONDecodeError:
                # descriptor is a file path.
                self.descriptor = json.load(
                    codecs.open(descriptor, encoding='utf-8'))

        if self.descriptor['profile'] == FLOW_RESULTS_PROFILE:
            del self.descriptor['profile']

        self._package = Package(self.descriptor)
        self.descriptor = self._package.descriptor
        self._name = id_string or self._package.descriptor.get('name')
        assert self._name, "The 'name' property must be defined."
        title = title or self._package.descriptor.get('title') or self._name
        survey_dict = {
            constants.NAME: 'data',
            constants.ID_STRING: self._name,
            constants.TITLE: title,
            constants.TYPE: constants.SURVEY,
        }
        self._survey = Survey(**survey_dict)
        self.build()

    def build(self):
        """
        Creates the survey questions for the XForm a FLOIP descriptor.
        """
        if not self._package.resources:
            raise ValidationError("At least one data resource is required.")

        resource = self._package.resources[0]
        if 'schema' not in resource.descriptor:
            raise ValidationError("The 'schema' object is missing in resource")
        if 'questions' not in resource.descriptor['schema']:
            raise ValidationError(
                "The 'questions' object is missing from schema")

        questions = resource.descriptor['schema']['questions']
        if isinstance(questions, dict):
            question_keys = list(questions.keys())
            question_keys.sort()
            for name in question_keys:
                xform_from_floip_dict(self._survey, name, questions[name])
        elif isinstance(questions, list):
            for question in questions:
                for name in question:
                    xform_from_floip_dict(self._survey, name, question[name])
        else:
            raise ValidationError(
                "Expecting 'questions' to be an object or array")

        meta_dict = {
            "name": "meta",
            "type": "group",
            "control": {
                "bodyless": True
            },
            "children": [{
                "name": "instanceID",
                "type": "calculate",
                "bind": {
                    "calculate": "concat('uuid:', uuid())"
                }
            }, {
                "name": "contactID",
                "type": "string",
            }, {
                "name": "sessionID",
                "type": "string",
            }]
        }  # yapf: disable
        self._survey.add_child(create_survey_element_from_dict(meta_dict))
        self._survey.validate()

        # check that we can recreate the survey object from the survey JSON
        create_survey_element_from_dict(self._survey.to_json_dict())

    @property
    def survey(self):
        """
        Returns a pyxform `Survey` object
        """
        return self._survey

    def xml(self):
        """
        Returns a XForm XML
        """
        return self._survey.to_xml()

    def survey_dict(self):
        """
        Returns a XForm dict.
        """
        return self._survey.to_json_dict()