def test_update_creates_definition_filler_and_inactivates_existing_definition_filler(self):
        definition_filler_id = self.definition_filler.get_id()
        update_url = '/definition_fillers/{}'.format(definition_filler_id)
        self.assertEqual(True, self.definition_filler.get_is_active())
        definition_template_id = self.definition_filler.get_definition_template().get_id()
        filler = self.definition_filler.get_filler()
        definition_filler_data = {
            'definition_template_id': definition_template_id,
            'filler': filler
        }
        response = self.put(update_url, data=definition_filler_data)
        self.assertEqual(200, response.status_code)
        definition_filler = json.loads(response.data)
        self.assertIsNotNone(definition_filler.get('id'))
        self.assertIsNotNone(definition_filler.get('date_created'))
        self.assertIsNotNone(definition_filler.get('date_modified'))
        self.assertEqual(definition_template_id, definition_filler.get('definition_template').get('id'))
        self.assertEqual(filler, definition_filler.get('filler'))
        self.assertNotEqual(definition_filler_id, definition_filler.get('id'))
        self.assertIsNotNone(definition_filler.get('is_active'))

        # Make sure the definition_filler was actually updated in the database
        saved_definition_filler = DefinitionFillersService.get_instance().get(int(definition_filler.get('id')))
        self.assertEqual(saved_definition_filler.get_id(), definition_filler.get('id'))
        self.assertEqual(DefinitionFiller.dump_datetime(saved_definition_filler.get_date_created()), definition_filler.get('date_created'))
        self.assertEqual(DefinitionFiller.dump_datetime(saved_definition_filler.get_date_modified()), definition_filler.get('date_modified'))
        self.assertEqual(saved_definition_filler.get_definition_template().get_id(), definition_filler.get('definition_template').get('id'))
        self.assertEqual(saved_definition_filler.get_filler(), definition_filler.get('filler'))
        self.assertEqual(saved_definition_filler.get_is_dictionary(), definition_filler.get('is_dictionary'))
        self.assertEqual(saved_definition_filler.get_is_active(), definition_filler.get('is_active'))

        # Ensure old definition template was marked inactive
        old_definition_filler = DefinitionFillersService.get_instance().get(definition_filler_id)
        self.assertEqual(False, old_definition_filler.get_is_active())
 def test_index_returns_definition_fillers_for_word(self):
     index_url = '/definition_fillers'
     word_id = self.word.get_id()
     query_string = {'word_id': word_id}
     response = self.get(index_url, query_string=query_string)
     self.assertEqual(200, response.status_code)
     definition_fillers = json.loads(response.data)
     definition_fillers_from_db = DefinitionFillersService.get_instance().get_list_by_word(word_id)
     all_definition_fillers = DefinitionFillersService.get_instance().get_list()
     self.assertTrue(len(definition_fillers) > 0)
     self.assertTrue(len(definition_fillers) < len(all_definition_fillers))
     self.assertEqual(len(definition_fillers_from_db), len(definition_fillers))
    def test_create_returns_created_status(self):
        create_url = '/definition_fillers'
        definition_template = self.definition_filler.get_definition_template()
        definition_template_id = definition_template.get_id()
        filler = self.definition_filler.get_filler()
        is_dictionary = True
        definition_filler_data = {
            'definition_template_id': definition_template_id,
            'filler': filler,
            'is_dictionary': is_dictionary
        }
        response = self.post(create_url, data=definition_filler_data)
        self.assertEqual(201, response.status_code)
        definition_filler = json.loads(response.data)
        self.assertIsNotNone(definition_filler.get('id'))
        self.assertIsNotNone(definition_filler.get('date_created'))
        self.assertIsNotNone(definition_filler.get('date_modified'))
        self.assertEqual(definition_template.serialized, definition_filler.get('definition_template'))
        self.assertEqual(filler, definition_filler.get('filler'))
        self.assertEqual(is_dictionary, definition_filler.get('is_dictionary'))
        self.assertEqual(True, definition_filler.get('is_active'))

        # Make sure the definition_filler was actually saved to the database
        saved_definition_filler = DefinitionFillersService.get_instance().get(int(definition_filler.get('id')))
        self.assertEqual(saved_definition_filler.get_id(), definition_filler.get('id'))
        self.assertEqual(DefinitionFiller.dump_datetime(saved_definition_filler.get_date_created()), definition_filler.get('date_created'))
        self.assertEqual(DefinitionFiller.dump_datetime(saved_definition_filler.get_date_modified()), definition_filler.get('date_modified'))
        self.assertEqual(saved_definition_filler.get_definition_template().get_id(), definition_filler.get('definition_template').get('id'))
        self.assertEqual(saved_definition_filler.get_filler(), definition_filler.get('filler'))
        self.assertEqual(saved_definition_filler.get_is_dictionary(), definition_filler.get('is_dictionary'))
        self.assertEqual(saved_definition_filler.get_is_active(), definition_filler.get('is_active'))
def show(definition_filler_id):
    """
    Request:
    {}

    Response [422] (definition_filler with definition_filler_id doesn't exist):
    {
        "errors": {
            "DefinitionFillerNotFound": [
                "Unable to find DefinitionFiller"
            ]
        },
        "inputs": {
            "id": "definition_filler_id"
        }
    }

    Response [200] (success):
    {
        "id": "current value",
        "date_created": "current value",
        "date_modified": "current value",
        "definition_template": "current value",
        "filler": "current value",
        "is_dictionary": "current value",
        "is_active": "current value"
    }
    """
    # Get the definition_filler
    definition_filler = DefinitionFillersService.get_instance().get(definition_filler_id)

    if definition_filler:
        return render_view('definition_fillers/show', 200, definition_filler=definition_filler.serialized)

    return render_view('422', 422, errors=NOT_FOUND_ERROR, inputs={'id': definition_filler_id})
 def test_index_returns_offset_definition_fillers_for_definition_template(self):
     index_url = '/definition_fillers'
     definition_template_id = self.definition_template.get_id()
     definition_fillers_from_db = DefinitionFillersService.get_instance().get_list_by_definition_template(definition_template_id)
     offset = int(len(definition_fillers_from_db) / 2)
     query_string = {'definition_template_id': definition_template_id, 'offset': offset}
     response = self.get(index_url, query_string=query_string)
     self.assertEqual(200, response.status_code)
     definition_fillers = json.loads(response.data)
     self.assertEqual(len(definition_fillers_from_db) - offset, len(definition_fillers))
def delete(definition_filler_id):
    """
    Request:
    {}

    Response [422] (definition_filler with definition_filler_id doesn't exist):
    {
        "errors": {
            "DefinitionFillerNotFound": [
                "Unable to find DefinitionFiller"
            ]
        },
        "inputs": {
            "id": "definition_filler_id"
        }
    }

    Response [422] (save failure - unable to set definition_filler as inactive):
    {
        "errors": {
            "IntegrityError": [
                "Reason saving to the db failed"
            ]
        },
        "inputs": {
            "id": "definition_filler_id"
        }
    }

    Response [200] (success):
    {
        "id": "current value",
        "date_created": "current value",
        "date_modified": "current value",
        "definition_template": "current value",
        "filler": "current value",
        "is_dictionary": "current value",
        "is_active": "current value"
    }
    """
    # Get the definition_filler
    definition_filler = DefinitionFillersService.get_instance().get(definition_filler_id)

    # Verify the definition_filler creation inputs
    if definition_filler:
        try:
            definition_filler.update(**{'is_active': False})
            return render_view('definition_fillers/show', 200, definition_filler=definition_filler.serialized)
        except Exception as e:
            return render_view(
                '422', 422, errors={e.__class__.__name__: [e.message]}, inputs={'id': definition_filler_id}
            )

    return render_view('422', 422, errors=NOT_FOUND_ERROR, inputs={'id': definition_filler_id})
    def test_delete_deletes_definition_filler(self):
        delete_url = '/definition_fillers/{}'.format(self.definition_filler.get_id())
        self.assertEqual(True, self.definition_filler.get_is_active())
        response = self.delete(delete_url)
        self.assertEqual(200, response.status_code)
        definition_filler = json.loads(response.data)
        self.assertIsNotNone(definition_filler.get('id'))
        self.assertIsNotNone(definition_filler.get('date_created'))
        self.assertIsNotNone(definition_filler.get('date_modified'))
        self.assertIsNotNone(definition_filler.get('definition_template'))
        self.assertIsNotNone(definition_filler.get('filler'))
        self.assertIsNotNone(definition_filler.get('is_dictionary'))
        self.assertEqual(False, definition_filler.get('is_active'))

        # Make sure the definition_filler was actually updated in the database
        saved_definition_filler = DefinitionFillersService.get_instance().get(int(definition_filler.get('id')))
        self.assertEqual(saved_definition_filler.get_id(), definition_filler.get('id'))
        self.assertEqual(DefinitionFiller.dump_datetime(saved_definition_filler.get_date_created()), definition_filler.get('date_created'))
        self.assertEqual(DefinitionFiller.dump_datetime(saved_definition_filler.get_date_modified()), definition_filler.get('date_modified'))
        self.assertEqual(saved_definition_filler.get_definition_template().get_id(), definition_filler.get('definition_template').get('id'))
        self.assertEqual(saved_definition_filler.get_filler(), definition_filler.get('filler'))
        self.assertEqual(saved_definition_filler.get_is_dictionary(), definition_filler.get('is_dictionary'))
        self.assertEqual(saved_definition_filler.get_is_active(), definition_filler.get('is_active'))
def index():
    """
    Request:
    {
        "offset": "offset",
        "limit": "limit",
        "word_id": "word_id",
        "definition_template_id": "definition_template_id"
    }

    Response [422] (invalid parameters):
    {
        "errors": {
            "name of parameter that failed validation": [
                "Reason for validation failure"
            ],
            "name of another parameter that failed validation": [
                "Reason for validation failure"
            ],
        },
        "inputs": {
            "offset": "value passed in. empty string if missing",
            "limit": "value passed in. empty string if missing",
            "word_id": "value passed in. empty string if missing",
            "definition_template_id": "value passed in. empty string if missing"
        }
    }

    Response [200] (success):
    [
        {
            "id": "current value",
            "date_created": "current value",
            "date_modified": "current value",
            "definition_template": "current value",
            "filler": "current value",
            "is_dictionary": "current value",
            "is_active": "current value"
        },
        {
            "id": "current value",
            "date_created": "current value",
            "date_modified": "current value",
            "definition_template": "current value",
            "filler": "current value",
            "is_dictionary": "current value",
            "is_active": "current value"
        },
        ...
    ]
    """
    # Get the input validator
    inputs = ListInputs(get_inputs())

    # Verify the list inputs
    if inputs.validate():

        if inputs.word_id.data:
            definition_fillers = DefinitionFillersService.get_instance().get_list_by_word(
                inputs.word_id.data, inputs.limit.data, inputs.offset.data
            )
        elif inputs.definition_template_id.data:
            definition_fillers = DefinitionFillersService.get_instance().get_list_by_definition_template(
                inputs.definition_template_id.data, inputs.limit.data, inputs.offset.data
            )
        else:
            definition_fillers = DefinitionFillersService.get_instance().get_list(inputs.limit.data, inputs.offset.data)

        return render_view(
            'definition_fillers/index',
            200,
            definition_fillers={
                definition_filler.get_id(): definition_filler.serialized
                for definition_filler in definition_fillers
            }
        )

    return render_view('422', 422, errors=inputs.errors, inputs=inputs.serialized())
def update(definition_filler_id):
    """
    Request:
    {
        "definition_template_id": "definition_template_id",
        "filler": "filler",
        "is_dictionary": "is_dictionary",
        "is_active": "is_active"
    }

    Response [422] (definition_filler with definition_filler_id doesn't exist):
    {
        "errors": {
            "DefinitionFillerNotFound": [
                "Unable to find DefinitionFiller"
            ]
        },
        "inputs": {
            "id": "definition_filler_id"
        }
    }

    Response [422] (invalid parameters):
    {
        "errors": {
            "name of parameter that failed validation": [
                "Reason for validation failure"
            ],
            "name of another parameter that failed validation": [
                "Reason for validation failure"
            ],
        },
        "inputs": {
            "id": "definition_filler_id",
            "definition_template_id": "value passed in. empty string if missing",
            "filler": "value passed in. empty string if missing",
            "is_dictionary": "value passed in. empty string if missing",
            "is_active": "value passed in. empty string if missing"
        }
    }

    Response [422] (definition_template with definition_template_id doesn't exist):
    {
        "errors": {
            "DefinitionTemplateNotFound": [
                "Unable to find the specified DefinitionTemplate"
            ]
        },
        "inputs": {
            "id": "definition_filler_id",
            "definition_template_id": "value passed in. empty string if missing",
            "filler": "value passed in. empty string if missing",
            "is_dictionary": "value passed in. empty string if missing",
            "is_active": "value passed in. empty string if missing"
        }
    }

    Response [422] (save failure - invalid filler array length):
    {
        "errors": {
            "AttributeError": [
                "There are {} filler but {} filler lexical classes. These values must be the same"
            ]
        },
        "inputs": {
            "id": "definition_filler_id",
            "definition_template_id": "value passed in. empty string if missing",
            "filler": "value passed in. empty string if missing",
            "is_dictionary": "value passed in. empty string if missing",
            "is_active": "value passed in. empty string if missing"
        }
    }

    Response [422] (save failure):
    {
        "errors": {
            "IntegrityError": [
                "Reason saving to the db failed"
            ]
        },
        "inputs": {
            "id": "definition_filler_id",
            "definition_template_id": "value passed in. empty string if missing",
            "filler": "value passed in. empty string if missing",
            "is_dictionary": "value passed in. empty string if missing",
            "is_active": "value passed in. empty string if missing"
        }
    }

    Response [200] (success):
    {
        "id": "current value",
        "date_created": "current value",
        "date_modified": "current value",
        "definition_template": "current value",
        "filler": "current value",
        "is_dictionary": "current value",
        "is_active": "current value"
    }
    """
    # Get the definition_filler
    definition_filler = DefinitionFillersService.get_instance().get(definition_filler_id)

    # Verify the definition_filler creation inputs
    if definition_filler:

        # Get the input validator
        inputs = UpdateInputs(get_inputs())
        combined_inputs = dict(inputs.serialized().items() + {'id': definition_filler_id}.items())

        # Hack to deal with WTForms requirement that list inputs be validated against a list of choices
        filler = get_mixed_dict_from_multidict(get_inputs()).get('filler', [])
        inputs.filler.choices = [(fill, fill) for fill in filler]

        if inputs.validate_on_submit():
            # If we're only marking the filler as active or inactive, pass through to the update
            if inputs.is_active.data and \
                    not any([inputs.definition_template_id.data, inputs.filler.data, inputs.is_dictionary.data]):
                try:
                    definition_filler.update(**get_mixed_dict_from_multidict(get_inputs(), inputs))
                    return render_view(
                        'definition_fillers/show', 200, definition_filler=definition_filler.serialized
                    )
                except Exception as e:
                    return render_view('422', 422, errors={e.__class__.__name__: [e.message]}, inputs=combined_inputs)

            # If we're trying to change the filler, mark the old filler
            # as inactive and create a new one with the new parameters
            else:
                definition_filler.update(**{'is_active': False})

                definition_template = DefinitionTemplatesService.get_instance().get(
                    inputs.definition_template_id.data
                ) if inputs.definition_template_id.data else definition_filler.get_definition_template()
                filler = inputs.filler.data if inputs.filler.data else definition_filler.get_filler()
                is_dictionary = inputs.is_dictionary.data \
                    if inputs.is_dictionary.data else definition_filler.get_is_dictionary()
                is_active = inputs.is_active.data if inputs.is_active.data else definition_filler.get_is_active()

                if definition_template:
                    try:
                        definition_filler = DefinitionFiller(definition_template, filler, is_dictionary)
                        definition_filler.set_is_active(is_active)
                        definition_filler.save()
                        return render_view(
                            'definition_fillers/show', 200, definition_filler=definition_filler.serialized
                        )
                    except Exception as e:
                        return render_view(
                            '422', 422, errors={e.__class__.__name__: [e.message]}, inputs=combined_inputs
                        )

                return render_view('422', 422, errors=DEFINITION_TEMPLATE_NOT_FOUND_ERROR, inputs=inputs.serialized())

        return render_view('422', 422, errors=inputs.errors, inputs=combined_inputs)

    return render_view('422', 422, errors=NOT_FOUND_ERROR, inputs={'id': definition_filler_id})