def test_show_method_prints_object_with_formatting_functions(crudl_mock_model): """ Este test comprueba que, para un modelo y PK dado, el método `show`: 1. Obtiene ese objeto de la BD mediante el método de `peewee` `get` 2. Formatea dicho objeto con el método `format_single_element`, usando como argumento el método `get_field_names()` del _meta del modelo. 3. Imprime por pantalla el objeto formateado mediante el método `print_table` """ from peewee2click import CRUDL format_func = 'peewee2click.CRUDL.format_single_element' print_func = 'peewee2click.CRUDL.print_table' model_mock = MagicMock() # Hacky!!! peewee usa el operador == de manera particular, así que devuelvo # ambos parámetros para asegurar que la invocación es exactamente así model_mock._meta.primary_key.__eq__ = lambda x, y: (x, y,) with patch(format_func) as format_mock, patch(print_func) as print_mock: CRUDL.show(model_mock, 3) model_mock.get.assert_called_once_with(model_mock._meta.primary_key == 3) format_mock.assert_called_once_with( model_mock.get.return_value, sorted(model_mock._meta.fields.keys.return_value)) print_mock.assert_called_once_with(format_mock.return_value)
def test_list_method_adds_extra_fields(): """ Este test comprueba que el método `list` para un modelo, unos campos base y unos campos extra dados: 1. Obtiene de BD todos los objetos de ese tipo con el método `select` de peewee 2. Formatea dichos objetos con el método `format_multiple_elements`, usando como argumentos los campos base y los extra 3. Imprime por pantalla el objeto formateado mediante el método `print_table` pasando como parámetro headers los campos base y los extra """ from peewee2click import CRUDL format_func = 'peewee2click.CRUDL.format_multiple_elements' print_func = 'peewee2click.CRUDL.print_table' model_mock = MagicMock() base_fields = [MagicMock()] extra_fields = [MagicMock()] with patch(format_func) as format_mock, patch(print_func) as print_mock: CRUDL.list(model_mock, base_fields, extra_fields=extra_fields) model_mock.select.assert_called_once_with() format_mock.assert_called_once_with(model_mock.select.return_value, base_fields + extra_fields) print_mock.assert_called_once_with(format_mock.return_value, headers=base_fields + extra_fields)
def test_show_method_returns_true_if_existing_object(crudl_mock_model): """ Este test comprueba que el método `show` devuelve True cuando se le pasa el pk de un objeto existente """ from peewee2click import CRUDL CRUDL.create(crudl_mock_model, force=True, text_attr="mock", char_attr="", int_attr=1, bool_attr=True) assert CRUDL.show(crudl_mock_model, 1) is True
def test_create_method_creates_object_when_force(crudl_mock_model): """ Este test comprueba que el método `create` crea un objeto en base de datos cuando se le pasa el parámetro `force=True` """ from peewee2click import CRUDL CRUDL.create(crudl_mock_model, force=True, text_attr="mock", char_attr="", int_attr=1, bool_attr=True) assert crudl_mock_model.select().where( crudl_mock_model.text_attr == "mock").exists()
def test_delete_method_asks_for_confirmation_when_no_force(): """ Este test comprueba que el método `delete` pregunta al usuario la confirmación usando el método `click.confirm` cuando el parámetro `force` es False """ from peewee2click import CRUDL with patch('peewee2click.click.confirm') as click_mock: CRUDL.delete(MagicMock(), 1, False) click_mock.assert_called_once_with(ANY)
def test_delete_method_delete_object_if_exists(crudl_mock_model): """ Este test comprueba que el método `delete` elimina un objeto de base de datos cuando se le pasa el parámetro `force=True` """ from peewee2click import CRUDL crudl_mock_model.create(text_attr="mock", char_attr="", int_attr=1, bool_attr=True) CRUDL.delete(crudl_mock_model, 1, force=True) assert not crudl_mock_model.select().where( crudl_mock_model.id == 1).exists()
def test_update_method_updates_fields_in_database(crudl_mock_model, field, new_value): """ Este test comprueba que el método `update` actualiza los campos en base de datos después de una ejecución correcta """ from peewee2click import CRUDL crudl_mock_model.create(text_attr="mock", char_attr="", int_attr=1, bool_attr=True) CRUDL.update(crudl_mock_model, 1, True, **{field: new_value}) assert crudl_mock_model.select().where( getattr(crudl_mock_model, field) == new_value).exists()
def test_update_method_updates_object_when_confirm_is_true(crudl_mock_model): """ Este test comprueba que el método `update` actualiza un objeto en base de datos cuando la respuesta a `click.confirm` es True """ from peewee2click import CRUDL crudl_mock_model.create(text_attr="mock", char_attr="", int_attr=1, bool_attr=True) with patch('peewee2click.click.confirm', return_value=True): CRUDL.update(crudl_mock_model, 1, False, text_attr="new_mock") assert crudl_mock_model.select().where( crudl_mock_model.text_attr == "new_mock").exists()
def test_delete_method_doesnt_delete_object_when_confirm_is_false( crudl_mock_model): """ Este test comprueba que el método `delete` no elimina un objeto de base de datos cuando la respuesta a `click.confirm` es False """ from peewee2click import CRUDL crudl_mock_model.create(text_attr="mock", char_attr="", int_attr=1, bool_attr=True) with patch('peewee2click.click.confirm', return_value=False): CRUDL.delete(crudl_mock_model, 1, False) assert crudl_mock_model.select().where(crudl_mock_model.id == 1).exists()
def test_update_method_doesnt_call_update_if_no_changes(crudl_mock_model, force): """ Este test comprueba que el método `update` no llama a la función `update` de `peewee` si se intenta actualizar un objeto sin pasarle parámetros a actualizar """ from peewee2click import CRUDL crudl_mock_model.create(text_attr="mock", char_attr="", int_attr=1, bool_attr=True) with patch.object(crudl_mock_model, 'update') as instance_update_mock: CRUDL.update(crudl_mock_model, 1, force) assert not instance_update_mock.called
def test_update_method_asks_for_confirmation_when_no_force(): """ Este test comprueba que el método `update` pregunta al usuario la confirmación usando el método `click.confirm` cuando el parámetro `force` es False """ from peewee2click import CRUDL model = MagicMock() # Queremos que la interfaz de execute sea realista y devuelva un entero, # simulando ser el número de filas afectadas. model.update.return_value.where.return_value.execute.return_value = 0 with patch('peewee2click.click.confirm') as click_mock: CRUDL.update(model, 1, False, new_field="whatever") click_mock.assert_called_once_with(ANY)
def test_print_table_return_table_in_tabulate_format(): """ Este test comprueba que el método `print_table` llama una vez a `tabulate` con los parámetros apropiados y después usa su salida para imprimirla por pantalla usando `click.echo` """ from peewee2click import CRUDL tabulate_func = 'peewee2click.tabulate' echo_func = 'peewee2click.click.echo' with patch(tabulate_func) as tabulate_mock, patch(echo_func) as echo_mock: CRUDL.print_table("mock", foo="bar") tabulate_mock.assert_called_once_with("mock", tablefmt=CRUDL.TABLEFMT, foo="bar") echo_mock.assert_called_once_with( "\n{}\n".format(tabulate_mock.return_value))
def test_show_method_returns_false_if_not_existing_object(crudl_mock_model): """ Este test comprueba que el método `show` devuelve False cuando se le pasa el pk de un objeto no existente """ from peewee2click import CRUDL assert CRUDL.show(crudl_mock_model, 1) is False
def test_update_method_returns_false_if_invalid_id(crudl_mock_model): """ Este test comprueba que el método `update` devuelve False cuando se le pasa el pk de un objeto no existente """ from peewee2click import CRUDL new_attrs = {'text_attr': 'foo'} assert CRUDL.update(crudl_mock_model, 1, True, **new_attrs) is False
def test_update_method_returns_false_if_no_changes(crudl_mock_model, force): """ Este test comprueba que el método `update` devuelve False cuando se intenta actualizar un objeto sin pasarle parámetros a actualizar """ from peewee2click import CRUDL crudl_mock_model.create(text_attr="mock", char_attr="", int_attr=1, bool_attr=True) assert CRUDL.update(crudl_mock_model, 1, force) is False
def test_update_method_returns_true_if_valid_id(crudl_mock_model): """ Este test comprueba que el método `update` devuelve True cuando se le pasa el pk de un objeto existente """ from peewee2click import CRUDL new_attrs = {'text_attr': 'foo'} crudl_mock_model.create(text_attr="mock", char_attr="", int_attr=1, bool_attr=True) assert CRUDL.update(crudl_mock_model, 1, True, **new_attrs) is True
def test_list_method_removes_duplicated_fields(): """ Este test comprueba que el método `list` para un modelo, unos campos base y unos campos extra dados (ambos con elementos repetidos): 1. Obtiene de BD todos los objetos de ese tipo con el método `select` de peewee 2. Formatea dichos objetos con el método `format_multiple_elements`, usando como argumentos los campos base y los extra, pero con los elementos sin repetir en ambos casos 3. Imprime por pantalla el objeto formateado mediante el método `print_table` pasando como parámetro headers los campos base y los extra, pero con los elementos sin repetir en ambos casos """ from peewee2click import CRUDL format_func = 'peewee2click.CRUDL.format_multiple_elements' print_func = 'peewee2click.CRUDL.print_table' model_mock = MagicMock() field_mock = MagicMock() extra_field_mock = MagicMock() # Fields repetidos, comprobaremos que se limitan a dos (en lugar de cuatro) base_fields = [field_mock, field_mock] extra_fields = [extra_field_mock, extra_field_mock] with patch(format_func) as format_mock, patch(print_func) as print_mock: CRUDL.list(model_mock, base_fields, extra_fields=extra_fields) # En los asserts comparamos contra una lista que solo tiene dos fields expected_fields = [field_mock, extra_field_mock] model_mock.select.assert_called_once_with() format_mock.assert_called_once_with(model_mock.select.return_value, expected_fields) print_mock.assert_called_once_with(format_mock.return_value, headers=expected_fields)
def test_format_single_element(): """ Este test comprueba que el método `format_single_element` devuelve una lista de campos de un elemento formateados de la manera apropiada """ from peewee2click import CRUDL element = MagicMock() res = CRUDL.format_single_element(element, ['foo', 'bar', 'baz']) assert res == [ ('foo', repr(element.foo)), ('bar', repr(element.bar)), ('baz', repr(element.baz)), ]
def test_format_multiple_elements(): """ Este test comprueba que el método `format_multiple_element` devuelve una lista de listas de campos de varios elementos formateados de la manera apropiada """ from peewee2click import CRUDL e1, e2, e3 = MagicMock(), MagicMock(), MagicMock() elements = [e1, e2, e3] res = CRUDL.format_multiple_elements(elements, ['foo', 'bar', 'baz']) assert res == [ [repr(e1.foo), repr(e1.bar), repr(e1.baz)], [repr(e2.foo), repr(e2.bar), repr(e2.baz)], [repr(e3.foo), repr(e3.bar), repr(e3.baz)], ]