def test_delete_row(send_mock, data_fixture): user = data_fixture.create_user() user_2 = data_fixture.create_user() table = data_fixture.create_database_table(name='Car', user=user) data_fixture.create_text_field(table=table, name='Name', text_default='Test') handler = RowHandler() model = table.get_model() row = handler.create_row(user=user, table=table) handler.create_row(user=user, table=table) with pytest.raises(UserNotInGroupError): handler.delete_row(user=user_2, table=table, row_id=row.id) with pytest.raises(RowDoesNotExist): handler.delete_row(user=user, table=table, row_id=99999) row_id = row.id handler.delete_row(user=user, table=table, row_id=row.id) assert model.objects.all().count() == 1 send_mock.assert_called_once() assert send_mock.call_args[1]['row_id'] == row_id assert send_mock.call_args[1]['row'] assert send_mock.call_args[1]['user'].id == user.id assert send_mock.call_args[1]['table'].id == table.id assert send_mock.call_args[1]['model']._generated_table_model
def test_if_duplicate_field_names_json_export(storage_mock, data_fixture): user = data_fixture.create_user() database = data_fixture.create_database_application(user=user) table = data_fixture.create_database_table(database=database) data_fixture.create_text_field(table=table, name="name", order=1) data_fixture.create_text_field(table=table, name="name", order=2) data_fixture.create_text_field(table=table, name="name", order=3) data_fixture.create_text_field(table=table, name='Another"name', order=4) data_fixture.create_text_field(table=table, name='Another"name', order=5) row_handler = RowHandler() row_handler.create_row(user=user, table=table) job, contents = run_export_job_with_mock_storage( table, None, storage_mock, user, {"exporter_type": "json"} ) assert ( contents == """[ { "id": 1, "name": "", "name 2": "", "name 3": "", "Another\\"name": "", "Another\\"name 2": "" } ] """ )
def test_single_select_field_type_get_order(data_fixture): user = data_fixture.create_user() database = data_fixture.create_database_application(user=user, name='Placeholder') table = data_fixture.create_database_table(name='Example', database=database) field = data_fixture.create_single_select_field(table=table) option_c = data_fixture.create_select_option(field=field, value='C', color='blue') option_a = data_fixture.create_select_option(field=field, value='A', color='blue') option_b = data_fixture.create_select_option(field=field, value='B', color='blue') grid_view = data_fixture.create_grid_view(table=table) view_handler = ViewHandler() row_handler = RowHandler() row_1 = row_handler.create_row(user=user, table=table, values={f'field_{field.id}': option_b.id}) row_2 = row_handler.create_row(user=user, table=table, values={f'field_{field.id}': option_a.id}) row_3 = row_handler.create_row(user=user, table=table, values={f'field_{field.id}': option_c.id}) row_4 = row_handler.create_row(user=user, table=table, values={f'field_{field.id}': option_b.id}) row_5 = row_handler.create_row(user=user, table=table, values={f'field_{field.id}': None}) sort = data_fixture.create_view_sort(view=grid_view, field=field, order='ASC') model = table.get_model() rows = view_handler.apply_sorting(grid_view, model.objects.all()) row_ids = [row.id for row in rows] assert row_ids == [row_5.id, row_2.id, row_1.id, row_4.id, row_3.id] sort.order = 'DESC' sort.save() rows = view_handler.apply_sorting(grid_view, model.objects.all()) row_ids = [row.id for row in rows] assert row_ids == [row_3.id, row_1.id, row_4.id, row_2.id, row_5.id] option_a.value = 'Z' option_a.save() sort.order = 'ASC' sort.save() model = table.get_model() rows = view_handler.apply_sorting(grid_view, model.objects.all()) row_ids = [row.id for row in rows] assert row_ids == [row_5.id, row_1.id, row_4.id, row_3.id, row_2.id]
def test_move_row(before_send_mock, send_mock, data_fixture): user = data_fixture.create_user() user_2 = data_fixture.create_user() table = data_fixture.create_database_table(name="Car", user=user) handler = RowHandler() row_1 = handler.create_row(user=user, table=table) row_2 = handler.create_row(user=user, table=table) row_3 = handler.create_row(user=user, table=table) with pytest.raises(UserNotInGroup): handler.move_row(user=user_2, table=table, row_id=row_1.id) with pytest.raises(RowDoesNotExist): handler.move_row(user=user, table=table, row_id=99999) handler.move_row(user=user, table=table, row_id=row_1.id) row_1.refresh_from_db() row_2.refresh_from_db() row_3.refresh_from_db() assert row_1.order == Decimal("4.00000000000000000000") assert row_2.order == Decimal("2.00000000000000000000") assert row_3.order == Decimal("3.00000000000000000000") before_send_mock.assert_called_once() assert before_send_mock.call_args[1]["row"].id == row_1.id assert before_send_mock.call_args[1]["user"].id == user.id assert before_send_mock.call_args[1]["table"].id == table.id assert before_send_mock.call_args[1]["model"]._generated_table_model send_mock.assert_called_once() assert send_mock.call_args[1]["row"].id == row_1.id assert send_mock.call_args[1]["user"].id == user.id assert send_mock.call_args[1]["table"].id == table.id assert send_mock.call_args[1]["model"]._generated_table_model assert send_mock.call_args[1][ "before_return"] == before_send_mock.return_value handler.move_row(user=user, table=table, row_id=row_1.id, before=row_3) row_1.refresh_from_db() row_2.refresh_from_db() row_3.refresh_from_db() assert row_1.order == Decimal("2.99999999999999999999") assert row_2.order == Decimal("2.00000000000000000000") assert row_3.order == Decimal("3.00000000000000000000") row_ids = table.get_model().objects.all() assert row_ids[0].id == row_2.id assert row_ids[1].id == row_1.id assert row_ids[2].id == row_3.id
def test_get_row(data_fixture): user = data_fixture.create_user() user_2 = data_fixture.create_user() table = data_fixture.create_database_table(name='Car', user=user) name_field = data_fixture.create_text_field( table=table, name='Name', text_default='Test' ) speed_field = data_fixture.create_number_field( table=table, name='Max speed', number_negative=True ) price_field = data_fixture.create_number_field( table=table, name='Price', number_type='DECIMAL', number_decimal_places=2, number_negative=False ) handler = RowHandler() row = handler.create_row(user=user, table=table, values={ f'field_{name_field.id}': 'Tesla', f'field_{speed_field.id}': 240, f'field_{price_field.id}': Decimal('59999.99') }) with pytest.raises(UserNotInGroupError): handler.get_row(user=user_2, table=table, row_id=row.id) with pytest.raises(RowDoesNotExist): handler.get_row(user=user, table=table, row_id=99999) row_tmp = handler.get_row(user=user, table=table, row_id=row.id) assert row_tmp.id == row.id assert getattr(row_tmp, f'field_{name_field.id}') == 'Tesla' assert getattr(row_tmp, f'field_{speed_field.id}') == 240 assert getattr(row_tmp, f'field_{price_field.id}') == Decimal('59999.99')
def test_link_row_enhance_queryset(data_fixture, django_assert_num_queries): user = data_fixture.create_user() database = data_fixture.create_database_application(user=user, name='Placeholder') example_table = data_fixture.create_database_table(name='Example', database=database) customers_table = data_fixture.create_database_table(name='Customers', database=database) field_handler = FieldHandler() row_handler = RowHandler() link_row_field = field_handler.create_field(user=user, table=example_table, type_name='link_row', link_row_table=customers_table) customers_row_1 = row_handler.create_row(user=user, table=customers_table) customers_row_2 = row_handler.create_row(user=user, table=customers_table) customers_row_3 = row_handler.create_row(user=user, table=customers_table) row = row_handler.create_row(user=user, table=example_table, values={ f'field_{link_row_field.id}': [customers_row_1.id, customers_row_2.id], }) row_2 = row_handler.create_row(user=user, table=example_table, values={ f'field_{link_row_field.id}': [customers_row_1.id], }) row_3 = row_handler.create_row(user=user, table=example_table, values={ f'field_{link_row_field.id}': [customers_row_3.id], }) model = example_table.get_model() rows = list(model.objects.all().enhance_by_fields()) with django_assert_num_queries(0): for row in rows: list(getattr(row, f'field_{link_row_field.id}').all())
def test_delete_row(data_fixture): user = data_fixture.create_user() user_2 = data_fixture.create_user() table = data_fixture.create_database_table(name='Car', user=user) data_fixture.create_text_field(table=table, name='Name', text_default='Test') handler = RowHandler() model = table.get_model() row = handler.create_row(user=user, table=table) handler.create_row(user=user, table=table) with pytest.raises(UserNotInGroupError): handler.delete_row(user=user_2, table=table, row_id=row.id) with pytest.raises(RowDoesNotExist): handler.delete_row(user=user, table=table, row_id=99999) handler.delete_row(user=user, table=table, row_id=row.id) assert model.objects.all().count() == 1
def test_if_xml_duplicate_name_and_value_are_escaped(storage_mock, data_fixture): user = data_fixture.create_user() database = data_fixture.create_database_application(user=user) table = data_fixture.create_database_table(database=database) text = data_fixture.create_text_field(table=table, name="<name>", order=0) data_fixture.create_text_field(table=table, name="name", order=1) data_fixture.create_text_field(table=table, name="Another name", order=2) data_fixture.create_text_field(table=table, name="Another@name", order=3) empty_1 = data_fixture.create_text_field(table=table, name="@", order=4) empty_2 = data_fixture.create_text_field(table=table, name="", order=5) data_fixture.create_text_field(table=table, name="1", order=6) row_handler = RowHandler() row_handler.create_row( user=user, table=table, values={f"field_{text.id}": "<value>"}, ) job, contents = run_export_job_with_mock_storage( table, None, storage_mock, user, {"exporter_type": "xml"} ) assert strip_indents_and_newlines(contents) == strip_indents_and_newlines( f""" <?xml version="1.0" encoding="utf-8" ?> <rows> <row> <id>1</id> <name><value></name> <name-2/> <Another-name/> <Another-name-2/> <field-{empty_1.id}/> <field-{empty_2.id}/> <field-1/> </row> </rows> """ )
def test_delete_row(before_send_mock, send_mock, data_fixture): user = data_fixture.create_user() user_2 = data_fixture.create_user() table = data_fixture.create_database_table(name="Car", user=user) data_fixture.create_text_field(table=table, name="Name", text_default="Test") handler = RowHandler() model = table.get_model() row = handler.create_row(user=user, table=table) handler.create_row(user=user, table=table) with pytest.raises(UserNotInGroup): handler.delete_row(user=user_2, table=table, row_id=row.id) with pytest.raises(RowDoesNotExist): handler.delete_row(user=user, table=table, row_id=99999) row_id = row.id handler.delete_row(user=user, table=table, row_id=row.id) assert model.objects.all().count() == 1 before_send_mock.assert_called_once() assert before_send_mock.call_args[1]["row"] assert before_send_mock.call_args[1]["user"].id == user.id assert before_send_mock.call_args[1]["table"].id == table.id assert before_send_mock.call_args[1]["model"]._generated_table_model send_mock.assert_called_once() assert send_mock.call_args[1]["row_id"] == row_id assert send_mock.call_args[1]["row"] assert send_mock.call_args[1]["user"].id == user.id assert send_mock.call_args[1]["table"].id == table.id assert send_mock.call_args[1]["model"]._generated_table_model assert send_mock.call_args[1][ "before_return"] == before_send_mock.return_value
def test_update_row(data_fixture): user = data_fixture.create_user() user_2 = data_fixture.create_user() table = data_fixture.create_database_table(name='Car', user=user) name_field = data_fixture.create_text_field(table=table, name='Name', text_default='Test') speed_field = data_fixture.create_number_field(table=table, name='Max speed', number_negative=True) price_field = data_fixture.create_number_field(table=table, name='Price', number_type='DECIMAL', number_decimal_places=2, number_negative=False) handler = RowHandler() row = handler.create_row(user=user, table=table) with pytest.raises(UserNotInGroupError): handler.update_row(user=user_2, table=table, row_id=row.id, values={}) with pytest.raises(RowDoesNotExist): handler.update_row(user=user, table=table, row_id=99999, values={}) with pytest.raises(ValidationError): handler.update_row(user=user, table=table, row_id=row.id, values={price_field.id: -10.99}) handler.update_row(user=user, table=table, row_id=row.id, values={ name_field.id: 'Tesla', speed_field.id: 240, f'field_{price_field.id}': 59999.99 }) row.refresh_from_db() assert getattr(row, f'field_{name_field.id}') == 'Tesla' assert getattr(row, f'field_{speed_field.id}') == 240 assert getattr(row, f'field_{price_field.id}') == Decimal('59999.99')
def test_create_row(data_fixture): user = data_fixture.create_user() user_2 = data_fixture.create_user() table = data_fixture.create_database_table(name='Car', user=user) name_field = data_fixture.create_text_field(table=table, name='Name', text_default='Test') speed_field = data_fixture.create_number_field(table=table, name='Max speed', number_negative=True) price_field = data_fixture.create_number_field(table=table, name='Price', number_type='DECIMAL', number_decimal_places=2, number_negative=False) handler = RowHandler() with pytest.raises(UserNotInGroupError): handler.create_row(user=user_2, table=table) row = handler.create_row(user=user, table=table, values={ name_field.id: 'Tesla', speed_field.id: 240, f'field_{price_field.id}': 59999.99, 9999: 'Must not be added' }) assert getattr(row, f'field_{name_field.id}') == 'Tesla' assert getattr(row, f'field_{speed_field.id}') == 240 assert getattr(row, f'field_{price_field.id}') == 59999.99 assert not getattr(row, f'field_9999', None) row.refresh_from_db() assert getattr(row, f'field_{name_field.id}') == 'Tesla' assert getattr(row, f'field_{speed_field.id}') == 240 assert getattr(row, f'field_{price_field.id}') == Decimal('59999.99') assert not getattr(row, f'field_9999', None) row = handler.create_row(user=user, table=table) assert getattr(row, f'field_{name_field.id}') == 'Test' assert not getattr(row, f'field_{speed_field.id}') assert not getattr(row, f'field_{price_field.id}') with pytest.raises(ValidationError): handler.create_row(user=user, table=table, values={price_field.id: -10.22}) model = table.get_model() assert model.objects.all().count() == 2
def test_get_row(data_fixture): user = data_fixture.create_user() user_2 = data_fixture.create_user() table = data_fixture.create_database_table(name="Car", user=user) name_field = data_fixture.create_text_field(table=table, name="Name", text_default="Test") speed_field = data_fixture.create_number_field(table=table, name="Max speed", number_negative=True) price_field = data_fixture.create_number_field( table=table, name="Price", number_type="DECIMAL", number_decimal_places=2, number_negative=False, ) handler = RowHandler() row = handler.create_row( user=user, table=table, values={ f"field_{name_field.id}": "Tesla", f"field_{speed_field.id}": 240, f"field_{price_field.id}": Decimal("59999.99"), }, ) with pytest.raises(UserNotInGroup): handler.get_row(user=user_2, table=table, row_id=row.id) with pytest.raises(RowDoesNotExist): handler.get_row(user=user, table=table, row_id=99999) row_tmp = handler.get_row(user=user, table=table, row_id=row.id) assert row_tmp.id == row.id assert getattr(row_tmp, f"field_{name_field.id}") == "Tesla" assert getattr(row_tmp, f"field_{speed_field.id}") == 240 assert getattr(row_tmp, f"field_{price_field.id}") == Decimal("59999.99")
def test_link_row_field_type_api_row_views(api_client, data_fixture): user, token = data_fixture.create_user_and_token() database = data_fixture.create_database_application(user=user, name='Placeholder') example_table = data_fixture.create_database_table(name='Example', database=database) customers_table = data_fixture.create_database_table(name='Customers', database=database) grid = data_fixture.create_grid_view(table=example_table) example_primary = data_fixture.create_text_field(name='Name', table=example_table, primary=True) customers_primary = data_fixture.create_text_field(name='Customer name', table=customers_table, primary=True) field_handler = FieldHandler() row_handler = RowHandler() link_row_field = field_handler.create_field(user=user, table=example_table, type_name='link_row', link_row_table=customers_table) customers_row_1 = row_handler.create_row( user=user, table=customers_table, values={f'field_{customers_primary.id}': 'John Doe'}) customers_row_2 = row_handler.create_row( user=user, table=customers_table, values={f'field_{customers_primary.id}': 'Jane Doe'}) customers_row_3 = row_handler.create_row(user=user, table=customers_table) response = api_client.post(reverse('api:database:rows:list', kwargs={'table_id': example_table.id}), { f'field_{link_row_field.id}': 'Random', }, format='json', HTTP_AUTHORIZATION=f'JWT {token}') response_json = response.json() assert response.status_code == HTTP_400_BAD_REQUEST assert response_json['error'] == 'ERROR_REQUEST_BODY_VALIDATION' assert (response_json['detail'][f'field_{link_row_field.id}'][0]['code'] == 'not_a_list') response = api_client.post(reverse('api:database:rows:list', kwargs={'table_id': example_table.id}), { f'field_{link_row_field.id}': ['a'], }, format='json', HTTP_AUTHORIZATION=f'JWT {token}') response_json = response.json() assert response.status_code == HTTP_400_BAD_REQUEST assert response_json['error'] == 'ERROR_REQUEST_BODY_VALIDATION' assert (response_json['detail'][f'field_{link_row_field.id}']['0'][0] ['code'] == 'invalid') response = api_client.post(reverse( 'api:database:rows:list', kwargs={'table_id': example_table.id}), { f'field_{link_row_field.id}': [customers_row_1.id, customers_row_2.id, 999], }, format='json', HTTP_AUTHORIZATION=f'JWT {token}') response_json = response.json() row_id = response_json['id'] assert response.status_code == HTTP_200_OK assert len(response_json[f'field_{link_row_field.id}']) == 2 assert response_json[f'field_{link_row_field.id}'][0][ 'id'] == customers_row_1.id assert response_json[f'field_{link_row_field.id}'][0][ 'value'] == 'John Doe' assert response_json[f'field_{link_row_field.id}'][1][ 'id'] == customers_row_2.id assert response_json[f'field_{link_row_field.id}'][1][ 'value'] == 'Jane Doe' model = example_table.get_model() assert model.objects.all().count() == 1 url = reverse('api:database:rows:item', kwargs={ 'table_id': example_table.id, 'row_id': row_id }) response = api_client.patch(url, { f'field_{link_row_field.id}': [], }, format='json', HTTP_AUTHORIZATION=f'JWT {token}') response_json = response.json() assert response.status_code == HTTP_200_OK assert len(response_json[f'field_{link_row_field.id}']) == 0 url = reverse('api:database:rows:item', kwargs={ 'table_id': example_table.id, 'row_id': row_id }) response = api_client.patch(url, { f'field_{link_row_field.id}': [customers_row_2.id, customers_row_3.id], }, format='json', HTTP_AUTHORIZATION=f'JWT {token}') response_json = response.json() assert response.status_code == HTTP_200_OK assert len(response_json[f'field_{link_row_field.id}']) == 2 assert response_json[f'field_{link_row_field.id}'][0][ 'id'] == customers_row_2.id assert response_json[f'field_{link_row_field.id}'][0][ 'value'] == 'Jane Doe' assert response_json[f'field_{link_row_field.id}'][1][ 'id'] == customers_row_3.id assert not response_json[f'field_{link_row_field.id}'][1]['value'] url = reverse('api:database:views:grid:list', kwargs={'view_id': grid.id}) response = api_client.get(url, **{'HTTP_AUTHORIZATION': f'JWT {token}'}) response_json = response.json() assert response.status_code == HTTP_200_OK assert response_json['count'] == 1 assert response_json['results'][0]['id'] == row_id assert len(response_json['results'][0][f'field_{link_row_field.id}']) == 2 url = reverse('api:database:rows:item', kwargs={ 'table_id': example_table.id, 'row_id': row_id }) response = api_client.delete(url, HTTP_AUTHORIZATION=f'JWT {token}') assert response.status_code == HTTP_204_NO_CONTENT assert model.objects.all().count() == 0 response = api_client.post(reverse('api:database:rows:list', kwargs={'table_id': example_table.id}), {}, format='json', HTTP_AUTHORIZATION=f'JWT {token}') response_json = response.json() assert response.status_code == HTTP_200_OK assert len(response_json[f'field_{link_row_field.id}']) == 0
def test_link_row_field_type_rows(data_fixture): user = data_fixture.create_user() database = data_fixture.create_database_application(user=user, name='Placeholder') example_table = data_fixture.create_database_table(name='Example', database=database) customers_table = data_fixture.create_database_table(name='Customers', database=database) users_table = data_fixture.create_database_table(name='Users', database=database) field_handler = FieldHandler() row_handler = RowHandler() link_row_field = field_handler.create_field(user=user, table=example_table, type_name='link_row', link_row_table=customers_table) customers_row_1 = row_handler.create_row(user=user, table=customers_table) customers_row_2 = row_handler.create_row(user=user, table=customers_table) customers_row_3 = row_handler.create_row(user=user, table=customers_table) row = row_handler.create_row(user=user, table=example_table, values={ f'field_{link_row_field.id}': [customers_row_1.id, customers_row_2.id], }) row_2 = row_handler.create_row(user=user, table=example_table, values={ f'field_{link_row_field.id}': [customers_row_1.id], }) example_table.name = 'Example2' example_table.save() customers_table.name = 'Customers2' customers_table.save() row_1_all = getattr(row, f'field_{link_row_field.id}').all() row_2_all = getattr(row_2, f'field_{link_row_field.id}').all() row_1_ids = [i.id for i in row_1_all] row_2_ids = [i.id for i in row_2_all] assert row_1_all.count() == 2 assert row_2_all.count() == 1 assert customers_row_1.id in row_1_ids assert customers_row_2.id in row_1_ids assert customers_row_1.id in row_2_ids row = row_handler.update_row( user=user, table=example_table, row_id=row.id, values={f'field_{link_row_field.id}': [customers_row_3.id]}) row_2 = row_handler.update_row( user=user, table=example_table, row_id=row_2.id, values={ f'field_{link_row_field.id}': [customers_row_2.id, customers_row_1.id] }) row_1_all = getattr(row, f'field_{link_row_field.id}').all() row_2_all = getattr(row_2, f'field_{link_row_field.id}').all() row_1_ids = [i.id for i in row_1_all] row_2_ids = [i.id for i in row_2_all] assert row_1_all.count() == 1 assert row_2_all.count() == 2 assert customers_row_3.id in row_1_ids assert customers_row_1.id in row_2_ids assert customers_row_2.id in row_2_ids # Check if the relations are there via the customers table. customers_table.refresh_from_db() customers_model = customers_table.get_model() related_field = link_row_field.link_row_related_field customer_rows = customers_model.objects.all() assert customer_rows.count() == 3 customers_row_1 = customer_rows[0] customers_row_2 = customer_rows[1] customers_row_3 = customer_rows[2] customer_row_1_all = getattr(customers_row_1, f'field_{related_field.id}').all() customer_row_2_all = getattr(customers_row_2, f'field_{related_field.id}').all() customer_row_3_all = getattr(customers_row_3, f'field_{related_field.id}').all() assert customer_row_1_all.count() == 1 assert customer_row_2_all.count() == 1 assert customer_row_3_all.count() == 1 customers_row_1_ids = [i.id for i in customer_row_1_all] customers_row_2_ids = [i.id for i in customer_row_2_all] customers_row_3_ids = [i.id for i in customer_row_3_all] assert row_2.id in customers_row_1_ids assert row_2.id in customers_row_2_ids assert row.id in customers_row_3_ids # When changing the link row table table all the existing relations should be # deleted. link_row_field = field_handler.update_field(user=user, field=link_row_field, type_name='link_row', link_row_table=users_table) example_table.refresh_from_db() model = example_table.get_model() rows = model.objects.all() row = rows[0] row_2 = rows[1] assert getattr(row, f'field_{link_row_field.id}').all().count() == 0 assert getattr(row_2, f'field_{link_row_field.id}').all().count() == 0 # Just check if the field can be deleted can be deleted. field_handler.delete_field(user=user, field=link_row_field) assert Field.objects.all().count() == 0
def test_link_row_field_type(data_fixture): user = data_fixture.create_user() database = data_fixture.create_database_application(user=user, name='Placeholder') table = data_fixture.create_database_table(name='Example', database=database) customers_table = data_fixture.create_database_table(name='Customers', database=database) cars_table = data_fixture.create_database_table(name='Cars', database=database) unrelated_table_1 = data_fixture.create_database_table(name='Unrelated') field_handler = FieldHandler() row_handler = RowHandler() # Create a primary field and some example data for the customers table. customers_primary_field = field_handler.create_field(user=user, table=customers_table, type_name='text', name='Name', primary=True) customers_row_1 = row_handler.create_row( user=user, table=customers_table, values={f'field_{customers_primary_field.id}': 'John'}) customers_row_2 = row_handler.create_row( user=user, table=customers_table, values={f'field_{customers_primary_field.id}': 'Jane'}) # Create a primary field and some example data for the cars table. cars_primary_field = field_handler.create_field(user=user, table=cars_table, type_name='text', name='Name', primary=True) cars_row_1 = row_handler.create_row( user=user, table=cars_table, values={f'field_{cars_primary_field.id}': 'BMW'}) cars_row_2 = row_handler.create_row( user=user, table=cars_table, values={f'field_{cars_primary_field.id}': 'Audi'}) with pytest.raises(LinkRowTableNotProvided): field_handler.create_field(user=user, table=table, type_name='link_row', name='Without table') with pytest.raises(LinkRowTableNotInSameDatabase): field_handler.create_field(user=user, table=table, type_name='link_row', name='Unrelated', link_row_table=unrelated_table_1) link_field_1 = field_handler.create_field(user=user, table=table, type_name='link_row', name='Customer', link_row_table=customers_table) link_field_2 = field_handler.create_field(user=user, table=table, type_name='link_row', name='Customer', link_row_table=customers_table) assert link_field_1.link_row_related_field.name == 'Example' assert link_field_2.link_row_related_field.name == 'Example' connection = connections['default'] tables = connection.introspection.table_names() assert (link_field_1.through_table_name == link_field_1.link_row_related_field.through_table_name) assert (link_field_2.through_table_name == link_field_2.link_row_related_field.through_table_name) assert link_field_1.through_table_name in tables assert link_field_2.through_table_name in tables model = table.get_model() table_row = model.objects.create() getattr(table_row, f'field_{link_field_1.id}').add(customers_row_1.id) results = getattr(table_row, f'field_{link_field_1.id}').all() assert len(results) == 1 assert getattr(results[0], f'field_{customers_primary_field.id}') == 'John' getattr(table_row, f'field_{link_field_2.id}').add(customers_row_1.id, customers_row_2.id) results = getattr(table_row, f'field_{link_field_2.id}').all() assert len(results) == 2 assert getattr(results[0], f'field_{customers_primary_field.id}') == 'John' assert getattr(results[1], f'field_{customers_primary_field.id}') == 'Jane' table_row_2 = model.objects.create() getattr(table_row_2, f'field_{link_field_1.id}').add(customers_row_2.id) results = getattr(table_row_2, f'field_{link_field_1.id}').all() assert len(results) == 1 assert getattr(results[0], f'field_{customers_primary_field.id}') == 'Jane' # Going to change only the name of the field. This should not result in any errors # of schema changes. link_field_1 = field_handler.update_field(user, link_field_1, name='Customer 2') with pytest.raises(LinkRowTableNotInSameDatabase): field_handler.update_field(user, link_field_1, link_row_table=unrelated_table_1) model = table.get_model() assert model.objects.all().count() == 2 # Change the table, this should destroy all relations. old_link_field_1_relation_id = link_field_1.link_row_relation_id link_field_1 = field_handler.update_field(user, link_field_1, link_row_table=cars_table) model = table.get_model() table_rows = model.objects.all() table_row = table_rows[0] table_row_2 = table_rows[1] assert link_field_1.link_row_table.id == cars_table.id assert link_field_1.link_row_relation_id == old_link_field_1_relation_id assert getattr(table_row, f'field_{link_field_1.id}').all().count() == 0 assert getattr(table_row, f'field_{link_field_2.id}').all().count() == 2 assert getattr(table_row_2, f'field_{link_field_1.id}').all().count() == 0 assert getattr(table_row_2, f'field_{link_field_2.id}').all().count() == 0 link_field_2 = field_handler.update_field(user, link_field_2, new_type_name='text') model = table.get_model() table_row = model.objects.all().first() assert getattr(table_row, f'field_{link_field_2.id}') is None assert LinkRowField.objects.all().count() == 2 setattr(table_row, f'field_{link_field_2.id}', 'Text value') table_row.save() assert getattr(table_row, f'field_{link_field_2.id}') == 'Text value' # Delete the existing field. Alter that the related field should be deleted and # no table named _relation_ should exist. field_handler.delete_field(user, link_field_1) assert LinkRowField.objects.all().count() == 0 for t in connection.introspection.table_names(): if '_relation_' in t: assert False # Change a the text field back into a link row field. link_field_2 = field_handler.update_field(user, link_field_2, new_type_name='link_row', link_row_table=customers_table) assert link_field_2.link_row_related_field.name == 'Example' assert (link_field_2.through_table_name == link_field_2.link_row_related_field.through_table_name) assert link_field_2.through_table_name in connection.introspection.table_names( ) assert LinkRowField.objects.all().count() == 2 model = table.get_model() table_row = model.objects.all().first() getattr(table_row, f'field_{link_field_2.id}').add(customers_row_1.id, customers_row_2.id) results = getattr(table_row, f'field_{link_field_2.id}').all() assert len(results) == 2 assert getattr(results[0], f'field_{customers_primary_field.id}') == 'John' assert getattr(results[1], f'field_{customers_primary_field.id}') == 'Jane'
def test_email_field_type(data_fixture): user = data_fixture.create_user() table = data_fixture.create_database_table(user=user) table_2 = data_fixture.create_database_table(user=user, database=table.database) field = data_fixture.create_text_field(table=table, order=1, name='name') field_handler = FieldHandler() row_handler = RowHandler() field_2 = field_handler.create_field(user=user, table=table, type_name='email', name='email') number = field_handler.create_field(user=user, table=table, type_name='number', name='number') assert len(EmailField.objects.all()) == 1 model = table.get_model(attribute_names=True) with pytest.raises(ValidationError): row_handler.create_row(user=user, table=table, values={'email': 'invalid_email'}, model=model) with pytest.raises(ValidationError): row_handler.create_row(user=user, table=table, values={'email': 'invalid@email'}, model=model) row_0 = row_handler.create_row(user=user, table=table, values={ 'name': '*****@*****.**', 'email': '*****@*****.**', 'number': 5 }, model=model) row_1 = row_handler.create_row(user=user, table=table, values={ 'name': 'someuser', 'email': '*****@*****.**', 'number': 10 }, model=model) row_2 = row_handler.create_row(user=user, table=table, values={ 'name': 'http://www.baserow.io', 'email': '*****@*****.**' }, model=model) row_3 = row_handler.create_row(user=user, table=table, values={ 'name': 'NOT AN EMAIL', 'email': '*****@*****.**' }, model=model) row_4 = row_handler.create_row(user=user, table=table, values={ 'name': '*****@*****.**', 'email': '' }, model=model) row_5 = row_handler.create_row(user=user, table=table, values={ 'email': None, }, model=model) row_6 = row_handler.create_row(user=user, table=table, values={}, model=model) # Convert the text field to a url field so we can check how the conversion of # values went. field_handler.update_field(user=user, field=field, new_type_name='email') field_handler.update_field(user=user, field=number, new_type_name='email') model = table.get_model(attribute_names=True) rows = model.objects.all() assert rows[0].name == '*****@*****.**' assert rows[0].email == '*****@*****.**' assert rows[0].number == '' assert rows[1].name == '' assert rows[1].email == '*****@*****.**' assert rows[1].number == '' assert rows[2].name == '' assert rows[2].email == '*****@*****.**' assert rows[2].number == '' assert rows[3].name == '' assert rows[3].email == '*****@*****.**' assert rows[3].number == '' assert rows[4].name == '*****@*****.**' assert rows[4].email == '' assert rows[4].number == '' assert rows[5].name == '' assert rows[5].email == '' assert rows[5].number == '' assert rows[6].name == '' assert rows[6].email == '' assert rows[6].number == '' field_handler.delete_field(user=user, field=field_2) assert len(EmailField.objects.all()) == 2
def test_date_field_type(data_fixture): user = data_fixture.create_user() table = data_fixture.create_database_table(user=user) field_handler = FieldHandler() row_handler = RowHandler() amsterdam = timezone('Europe/Amsterdam') utc = timezone('utc') date_field_1 = field_handler.create_field(user=user, table=table, type_name='date', name='Date') date_field_2 = field_handler.create_field(user=user, table=table, type_name='date', name='Datetime', date_include_time=True) assert date_field_1.date_include_time == False assert date_field_2.date_include_time == True assert len(DateField.objects.all()) == 2 model = table.get_model(attribute_names=True) row = row_handler.create_row(user=user, table=table, values={}, model=model) assert row.date == None assert row.datetime == None row = row_handler.create_row(user=user, table=table, values={ 'date': '2020-4-1', 'datetime': '2020-4-1 12:30:30' }, model=model) row.refresh_from_db() assert row.date == date(2020, 4, 1) assert row.datetime == datetime(2020, 4, 1, 12, 30, 30, tzinfo=utc) row = row_handler.create_row(user=user, table=table, values={ 'datetime': make_aware( datetime(2020, 4, 1, 12, 30, 30), amsterdam) }, model=model) row.refresh_from_db() assert row.date == None assert row.datetime == datetime(2020, 4, 1, 10, 30, 30, tzinfo=timezone('UTC')) date_field_1 = field_handler.update_field(user=user, field=date_field_1, date_include_time=True) date_field_2 = field_handler.update_field(user=user, field=date_field_2, date_include_time=False) assert date_field_1.date_include_time == True assert date_field_2.date_include_time == False model = table.get_model(attribute_names=True) rows = model.objects.all() assert rows[0].date == None assert rows[0].datetime == None assert rows[1].date == datetime(2020, 4, 1, tzinfo=timezone('UTC')) assert rows[1].datetime == date(2020, 4, 1) assert rows[2].date == None assert rows[2].datetime == date(2020, 4, 1) field_handler.delete_field(user=user, field=date_field_1) field_handler.delete_field(user=user, field=date_field_2) assert len(DateField.objects.all()) == 0
def test_url_field_type(data_fixture): user = data_fixture.create_user() table = data_fixture.create_database_table(user=user) table_2 = data_fixture.create_database_table(user=user, database=table.database) field = data_fixture.create_text_field(table=table, order=1, name='name') field_handler = FieldHandler() row_handler = RowHandler() field_2 = field_handler.create_field(user=user, table=table, type_name='url', name='url') number = field_handler.create_field(user=user, table=table, type_name='number', name='number') assert len(URLField.objects.all()) == 1 model = table.get_model(attribute_names=True) with pytest.raises(ValidationError): row_handler.create_row(user=user, table=table, values={'url': 'invalid_url'}, model=model) with pytest.raises(ValidationError): row_handler.create_row(user=user, table=table, values={'url': 'httpss'}, model=model) with pytest.raises(ValidationError): row_handler.create_row(user=user, table=table, values={'url': 'httpss'}, model=model) row_0 = row_handler.create_row(user=user, table=table, values={ 'name': 'http://test.nl', 'url': 'https://baserow.io', 'number': 5 }, model=model) row_1 = row_handler.create_row(user=user, table=table, values={ 'name': 'http;//', 'url': 'http://localhost', 'number': 10 }, model=model) row_2 = row_handler.create_row(user=user, table=table, values={ 'name': '*****@*****.**', 'url': 'http://www.baserow.io' }, model=model) row_3 = row_handler.create_row( user=user, table=table, values={ 'name': 'NOT A URL', 'url': 'http://www.baserow.io/blog/building-a-database' }, model=model) row_4 = row_handler.create_row( user=user, table=table, values={ 'name': 'ftps://www.complex.website.com?querystring=test&something=else', 'url': '' }, model=model) row_5 = row_handler.create_row(user=user, table=table, values={ 'url': None, }, model=model) row_6 = row_handler.create_row(user=user, table=table, values={}, model=model) # Convert to text field to a url field so we can check how the conversion of values # went. field_handler.update_field(user=user, field=field, new_type_name='url') field_handler.update_field(user=user, field=number, new_type_name='url') model = table.get_model(attribute_names=True) rows = model.objects.all() assert rows[0].name == 'http://test.nl' assert rows[0].url == 'https://baserow.io' assert rows[0].number == '' assert rows[1].name == '' assert rows[1].url == 'http://localhost' assert rows[1].number == '' assert rows[2].name == '' assert rows[2].url == 'http://www.baserow.io' assert rows[2].number == '' assert rows[3].name == '' assert rows[3].url == 'http://www.baserow.io/blog/building-a-database' assert rows[3].number == '' assert (rows[4].name == 'ftps://www.complex.website.com?querystring=test&something=else') assert rows[4].url == '' assert rows[4].number == '' assert rows[5].name == '' assert rows[5].url == '' assert rows[5].number == '' assert rows[6].name == '' assert rows[6].url == '' assert rows[6].number == '' field_handler.delete_field(user=user, field=field_2) assert len(URLField.objects.all()) == 2
def test_single_select_field_type_rows(data_fixture, django_assert_num_queries): user = data_fixture.create_user() database = data_fixture.create_database_application(user=user, name='Placeholder') table = data_fixture.create_database_table(name='Example', database=database) other_select_option = data_fixture.create_select_option() field_handler = FieldHandler() row_handler = RowHandler() field = field_handler.create_field(user=user, table=table, type_name='single_select', select_options=[{ 'value': 'Option 1', 'color': 'red' }, { 'value': 'Option 2', 'color': 'blue' }]) with pytest.raises(ValidationError): row_handler.create_row(user=user, table=table, values={f'field_{field.id}': 999999}) with pytest.raises(ValidationError): row_handler.create_row( user=user, table=table, values={f'field_{field.id}': other_select_option.id}) select_options = field.select_options.all() row = row_handler.create_row( user=user, table=table, values={f'field_{field.id}': select_options[0].id}) assert getattr(row, f'field_{field.id}').id == select_options[0].id assert getattr(row, f'field_{field.id}').value == select_options[0].value assert getattr(row, f'field_{field.id}').color == select_options[0].color assert getattr(row, f'field_{field.id}_id') == select_options[0].id field = field_handler.update_field(user=user, field=field, select_options=[ { 'value': 'Option 3', 'color': 'orange' }, { 'value': 'Option 4', 'color': 'purple' }, ]) select_options = field.select_options.all() row_2 = row_handler.create_row( user=user, table=table, values={f'field_{field.id}': select_options[0].id}) assert getattr(row_2, f'field_{field.id}').id == select_options[0].id assert getattr(row_2, f'field_{field.id}').value == select_options[0].value assert getattr(row_2, f'field_{field.id}').color == select_options[0].color assert getattr(row_2, f'field_{field.id}_id') == select_options[0].id row_3 = row_handler.create_row( user=user, table=table, values={f'field_{field.id}': select_options[1].id}) assert getattr(row_3, f'field_{field.id}').id == select_options[1].id assert getattr(row_3, f'field_{field.id}_id') == select_options[1].id row_4 = row_handler.create_row( user=user, table=table, values={f'field_{field.id}': select_options[0].id}) assert getattr(row_4, f'field_{field.id}').id == select_options[0].id assert getattr(row_4, f'field_{field.id}_id') == select_options[0].id model = table.get_model() with django_assert_num_queries(2): rows = list(model.objects.all().enhance_by_fields()) assert getattr(rows[0], f'field_{field.id}') is None assert getattr(rows[1], f'field_{field.id}').id == select_options[0].id assert getattr(rows[2], f'field_{field.id}').id == select_options[1].id assert getattr(rows[3], f'field_{field.id}').id == select_options[0].id row.refresh_from_db() assert getattr(row, f'field_{field.id}') is None assert getattr(row, f'field_{field.id}_id') is None field = field_handler.update_field(user=user, field=field, new_type_name='text') assert field.select_options.all().count() == 0 model = table.get_model() rows = model.objects.all().enhance_by_fields() assert getattr(rows[0], f'field_{field.id}') is None assert getattr(rows[1], f'field_{field.id}') == 'Option 3' assert getattr(rows[2], f'field_{field.id}') == 'Option 4' assert getattr(rows[3], f'field_{field.id}') == 'Option 3' field = field_handler.update_field(user=user, field=field, new_type_name='single_select', select_options=[ { 'value': 'Option 2', 'color': 'blue' }, { 'value': 'option 3', 'color': 'purple' }, ]) assert field.select_options.all().count() == 2 model = table.get_model() rows = model.objects.all().enhance_by_fields() select_options = field.select_options.all() assert getattr(rows[0], f'field_{field.id}') is None assert getattr(rows[1], f'field_{field.id}').id == select_options[1].id assert getattr(rows[2], f'field_{field.id}') is None assert getattr(rows[3], f'field_{field.id}').id == select_options[1].id row_4 = row_handler.update_row(user=user, table=table, row_id=row_4.id, values={f'field_{field.id}': None}) assert getattr(row_4, f'field_{field.id}') is None assert getattr(row_4, f'field_{field.id}_id') is None field = field_handler.update_field(user=user, field=field, new_type_name='text') assert field.select_options.all().count() == 0 model = table.get_model() rows = model.objects.all().enhance_by_fields() assert getattr(rows[0], f'field_{field.id}') is None assert getattr(rows[1], f'field_{field.id}') == 'option 3' assert getattr(rows[2], f'field_{field.id}') is None assert getattr(rows[3], f'field_{field.id}') is None field = field_handler.update_field(user=user, field=field, new_type_name='single_select') assert field.select_options.all().count() == 0 model = table.get_model() rows = model.objects.all().enhance_by_fields() assert getattr(rows[0], f'field_{field.id}') is None assert getattr(rows[1], f'field_{field.id}') is None assert getattr(rows[2], f'field_{field.id}') is None assert getattr(rows[3], f'field_{field.id}') is None
def test_primary_single_select_field_with_link_row_field( api_client, data_fixture, django_assert_num_queries): """ We expect the relation to a table that has a single select field to work. """ user, token = data_fixture.create_user_and_token() database = data_fixture.create_database_application(user=user, name='Placeholder') example_table = data_fixture.create_database_table(name='Example', database=database) customers_table = data_fixture.create_database_table(name='Customers', database=database) field_handler = FieldHandler() row_handler = RowHandler() data_fixture.create_text_field(name='Name', table=example_table, primary=True) customers_primary = field_handler.create_field(user=user, table=customers_table, type_name='single_select', select_options=[{ 'value': 'Option 1', 'color': 'red' }, { 'value': 'Option 2', 'color': 'blue' }, { 'value': 'Option 3', 'color': 'orange' }], primary=True) link_row_field = field_handler.create_field(user=user, table=example_table, type_name='link_row', link_row_table=customers_table) select_options = customers_primary.select_options.all() customers_row_1 = row_handler.create_row( user=user, table=customers_table, values={f'field_{customers_primary.id}': select_options[0].id}) customers_row_2 = row_handler.create_row( user=user, table=customers_table, values={f'field_{customers_primary.id}': select_options[1].id}) customers_row_3 = row_handler.create_row( user=user, table=customers_table, values={f'field_{customers_primary.id}': select_options[2].id}) row_handler.create_row(user, table=example_table, values={ f'field_{link_row_field.id}': [customers_row_1.id, customers_row_2.id] }) row_handler.create_row( user, table=example_table, values={f'field_{link_row_field.id}': [customers_row_1.id]}) row_handler.create_row( user, table=example_table, values={f'field_{link_row_field.id}': [customers_row_3.id]}) model = example_table.get_model() queryset = model.objects.all().enhance_by_fields() serializer_class = get_row_serializer_class(model, RowSerializer, is_response=True) with django_assert_num_queries(3): serializer = serializer_class(queryset, many=True) serializer.data response = api_client.get(reverse('api:database:rows:list', kwargs={'table_id': example_table.id}), format='json', HTTP_AUTHORIZATION=f'JWT {token}') response_json = response.json() assert (response_json['results'][0][f'field_{link_row_field.id}'][0] ['value'] == 'Option 1') assert (response_json['results'][0][f'field_{link_row_field.id}'][1] ['value'] == 'Option 2') assert (response_json['results'][1][f'field_{link_row_field.id}'][0] ['value'] == 'Option 1') assert (response_json['results'][2][f'field_{link_row_field.id}'][0] ['value'] == 'Option 3')
def test_converting_date_field_value(data_fixture): user = data_fixture.create_user() table = data_fixture.create_database_table(user=user) field_handler = FieldHandler() row_handler = RowHandler() utc = timezone("utc") date_field_eu = data_fixture.create_text_field(table=table) date_field_us = data_fixture.create_text_field(table=table) date_field_iso = data_fixture.create_text_field(table=table) date_field_eu_12 = data_fixture.create_text_field(table=table) date_field_us_12 = data_fixture.create_text_field(table=table) date_field_iso_12 = data_fixture.create_text_field(table=table) date_field_eu_24 = data_fixture.create_text_field(table=table) date_field_us_24 = data_fixture.create_text_field(table=table) date_field_iso_24 = data_fixture.create_text_field(table=table) model = table.get_model() row_handler.create_row( user=user, table=table, model=model, values={ f"field_{date_field_eu.id}": "22/07/2021", f"field_{date_field_us.id}": "07/22/2021", f"field_{date_field_iso.id}": "2021-07-22", f"field_{date_field_eu_12.id}": "22/07/2021 12:45 PM", f"field_{date_field_us_12.id}": "07/22/2021 12:45 PM", f"field_{date_field_iso_12.id}": "2021-07-22 12:45 PM", f"field_{date_field_eu_24.id}": "22/07/2021 12:45", f"field_{date_field_us_24.id}": "07/22/2021 12:45", f"field_{date_field_iso_24.id}": "2021-07-22 12:45", }, ) row_handler.create_row( user=user, table=table, model=model, values={ f"field_{date_field_eu.id}": "22-7-2021", f"field_{date_field_us.id}": "7-22-2021", f"field_{date_field_iso.id}": "2021/7/22", f"field_{date_field_eu_12.id}": "22-7-2021 12:45am", f"field_{date_field_us_12.id}": "7-22-2021 12:45am", f"field_{date_field_iso_12.id}": "2021/7/22 12:45am", f"field_{date_field_eu_24.id}": "22-7-2021 7:45", f"field_{date_field_us_24.id}": "7-22-2021 7:45", f"field_{date_field_iso_24.id}": "2021/7/22 7:45", }, ) row_handler.create_row( user=user, table=table, model=model, values={ f"field_{date_field_eu.id}": "22/07/2021 12:00", f"field_{date_field_us.id}": "07/22/2021 12:00am", f"field_{date_field_iso.id}": "2021-07-22 12:00 PM", f"field_{date_field_eu_12.id}": "INVALID", f"field_{date_field_us_12.id}": "2222-2222-2222", f"field_{date_field_iso_12.id}": "x-7--1", f"field_{date_field_eu_24.id}": "22-7-2021 7:45:12", f"field_{date_field_us_24.id}": "7-22-2021 7:45:23", f"field_{date_field_iso_24.id}": "2021/7/22 7:45:70", }, ) row_handler.create_row( user=user, table=table, model=model, values={ f"field_{date_field_eu.id}": "2018-08-20T13:20:10", f"field_{date_field_us.id}": "2017 Mar 03 05:12:41.211", f"field_{date_field_iso.id}": "19/Apr/2017:06:36:15", f"field_{date_field_eu_12.id}": "Dec 2, 2017 2:39:58 AM", f"field_{date_field_us_12.id}": "Jun 09 2018 15:28:14", f"field_{date_field_iso_12.id}": "Apr 20 00:00:35 2010", f"field_{date_field_eu_24.id}": "Apr 20 00:00:35 2010", f"field_{date_field_us_24.id}": "2018-02-27 15:35:20.311", f"field_{date_field_iso_24.id}": "10-04-19 12:00:17", }, ) date_field_eu = field_handler.update_field(user=user, field=date_field_eu, new_type_name="date", date_format="EU") date_field_us = field_handler.update_field(user=user, field=date_field_us, new_type_name="date", date_format="US") date_field_iso = field_handler.update_field(user=user, field=date_field_iso, new_type_name="date", date_format="ISO") date_field_eu_12 = field_handler.update_field( user=user, field=date_field_eu_12, new_type_name="date", date_format="EU", date_include_time=True, date_time_format="12", ) date_field_us_12 = field_handler.update_field( user=user, field=date_field_us_12, new_type_name="date", date_format="US", date_include_time=True, date_time_format="12", ) date_field_iso_12 = field_handler.update_field( user=user, field=date_field_iso_12, new_type_name="date", date_format="ISO", date_include_time=True, date_time_format="12", ) date_field_eu_24 = field_handler.update_field( user=user, field=date_field_eu_24, new_type_name="date", date_format="EU", date_include_time=True, date_time_format="24", ) date_field_us_24 = field_handler.update_field( user=user, field=date_field_us_24, new_type_name="date", date_format="US", date_include_time=True, date_time_format="24", ) date_field_iso_24 = field_handler.update_field( user=user, field=date_field_iso_24, new_type_name="date", date_format="ISO", date_include_time=True, date_time_format="24", ) model = table.get_model() rows = model.objects.all() assert getattr(rows[0], f"field_{date_field_eu.id}") == date(2021, 7, 22) assert getattr(rows[0], f"field_{date_field_us.id}") == date(2021, 7, 22) assert getattr(rows[0], f"field_{date_field_iso.id}") == date(2021, 7, 22) assert getattr(rows[0], f"field_{date_field_eu_12.id}") == (datetime(2021, 7, 22, 12, 45, 0, tzinfo=utc)) assert getattr(rows[0], f"field_{date_field_us_12.id}") == (datetime(2021, 7, 22, 12, 45, 0, tzinfo=utc)) assert getattr(rows[0], f"field_{date_field_iso_12.id}") == (datetime(2021, 7, 22, 12, 45, 0, tzinfo=utc)) assert getattr(rows[0], f"field_{date_field_eu_24.id}") == (datetime(2021, 7, 22, 12, 45, 0, tzinfo=utc)) assert getattr(rows[0], f"field_{date_field_us_24.id}") == (datetime(2021, 7, 22, 12, 45, 0, tzinfo=utc)) assert getattr(rows[0], f"field_{date_field_iso_24.id}") == (datetime(2021, 7, 22, 12, 45, 0, tzinfo=utc)) assert getattr(rows[1], f"field_{date_field_eu.id}") == date(2021, 7, 22) assert getattr(rows[1], f"field_{date_field_us.id}") == date(2021, 7, 22) assert getattr(rows[1], f"field_{date_field_iso.id}") == date(2021, 7, 22) assert getattr(rows[1], f"field_{date_field_eu_12.id}") == (datetime(2021, 7, 22, 0, 45, 0, tzinfo=utc)) assert getattr(rows[1], f"field_{date_field_us_12.id}") == (datetime(2021, 7, 22, 0, 45, 0, tzinfo=utc)) assert getattr(rows[1], f"field_{date_field_iso_12.id}") == (datetime(2021, 7, 22, 0, 45, 0, tzinfo=utc)) assert getattr(rows[1], f"field_{date_field_eu_24.id}") == (datetime(2021, 7, 22, 7, 45, 0, tzinfo=utc)) assert getattr(rows[1], f"field_{date_field_us_24.id}") == (datetime(2021, 7, 22, 7, 45, 0, tzinfo=utc)) assert getattr(rows[1], f"field_{date_field_iso_24.id}") == (datetime(2021, 7, 22, 7, 45, 0, tzinfo=utc)) assert getattr(rows[2], f"field_{date_field_eu.id}") == date(2021, 7, 22) assert getattr(rows[2], f"field_{date_field_us.id}") == date(2021, 7, 22) assert getattr(rows[2], f"field_{date_field_iso.id}") == date(2021, 7, 22) assert getattr(rows[2], f"field_{date_field_eu_12.id}") is None assert getattr(rows[2], f"field_{date_field_us_12.id}") is None assert getattr(rows[2], f"field_{date_field_iso_12.id}") is None assert getattr(rows[2], f"field_{date_field_eu_24.id}") == (datetime(2021, 7, 22, 7, 45, 0, tzinfo=utc)) assert getattr(rows[2], f"field_{date_field_us_24.id}") == (datetime(2021, 7, 22, 7, 45, 0, tzinfo=utc)) assert getattr(rows[2], f"field_{date_field_iso_24.id}") == (datetime(2021, 7, 22, 7, 45, 0, tzinfo=utc)) """ f'field_{date_field_eu.id}': '2018-08-20T13:20:10', f'field_{date_field_us.id}': '2017 Mar 03 05:12:41.211', f'field_{date_field_iso.id}': '19/Apr/2017:06:36:15', f'field_{date_field_eu_12.id}': 'Dec 2, 2017 2:39:58 AM', f'field_{date_field_us_12.id}': 'Jun 09 2018 15:28:14', f'field_{date_field_iso_12.id}': 'Apr 20 00:00:35 2010', f'field_{date_field_eu_24.id}': 'Apr 20 00:00:35 2010', f'field_{date_field_us_24.id}': '2018-02-27 15:35:20.311', f'field_{date_field_iso_24.id}': '10-04-19 12:00:17' """ assert getattr(rows[3], f"field_{date_field_eu.id}") == date(2018, 8, 20) assert getattr(rows[3], f"field_{date_field_us.id}") == date(2017, 3, 3) assert getattr(rows[3], f"field_{date_field_iso.id}") == date(2017, 4, 19) assert getattr(rows[3], f"field_{date_field_eu_12.id}") == (datetime(2017, 12, 2, 2, 39, 58, tzinfo=utc)) assert getattr(rows[3], f"field_{date_field_us_12.id}") == (datetime(2018, 6, 9, 15, 28, 14, tzinfo=utc)) assert getattr(rows[3], f"field_{date_field_iso_12.id}") == (datetime(2010, 4, 20, 0, 0, 35, tzinfo=utc)) assert getattr(rows[3], f"field_{date_field_eu_24.id}") == (datetime(2010, 4, 20, 0, 0, 35, tzinfo=utc)) assert getattr(rows[3], f"field_{date_field_us_24.id}") == (datetime(2018, 2, 27, 15, 35, 20, 311000, tzinfo=utc)) assert getattr(rows[3], f"field_{date_field_iso_24.id}") == (datetime(10, 4, 19, 12, 0, tzinfo=utc)) date_field_eu = field_handler.update_field(user=user, field=date_field_eu, new_type_name="text") date_field_us = field_handler.update_field(user=user, field=date_field_us, new_type_name="text") date_field_iso = field_handler.update_field(user=user, field=date_field_iso, new_type_name="text") date_field_eu_12 = field_handler.update_field(user=user, field=date_field_eu_12, new_type_name="text") date_field_us_12 = field_handler.update_field(user=user, field=date_field_us_12, new_type_name="text") date_field_iso_12 = field_handler.update_field(user=user, field=date_field_iso_12, new_type_name="text") date_field_eu_24 = field_handler.update_field(user=user, field=date_field_eu_24, new_type_name="text") date_field_us_24 = field_handler.update_field(user=user, field=date_field_us_24, new_type_name="text") date_field_iso_24 = field_handler.update_field(user=user, field=date_field_iso_24, new_type_name="text") model = table.get_model() rows = model.objects.all() assert getattr(rows[0], f"field_{date_field_eu.id}") == "22/07/2021" assert getattr(rows[0], f"field_{date_field_us.id}") == "07/22/2021" assert getattr(rows[0], f"field_{date_field_iso.id}") == "2021-07-22" assert getattr(rows[0], f"field_{date_field_eu_12.id}") == "22/07/2021 12:45PM" assert getattr(rows[0], f"field_{date_field_us_12.id}") == "07/22/2021 12:45PM" assert getattr(rows[0], f"field_{date_field_iso_12.id}") == "2021-07-22 12:45PM" assert getattr(rows[0], f"field_{date_field_eu_24.id}") == "22/07/2021 12:45" assert getattr(rows[0], f"field_{date_field_us_24.id}") == "07/22/2021 12:45" assert getattr(rows[0], f"field_{date_field_iso_24.id}") == "2021-07-22 12:45" assert getattr(rows[2], f"field_{date_field_eu_12.id}") is None
def test_date_field_type(data_fixture): user = data_fixture.create_user() table = data_fixture.create_database_table(user=user) field_handler = FieldHandler() row_handler = RowHandler() amsterdam = timezone("Europe/Amsterdam") utc = timezone("utc") date_field_1 = field_handler.create_field(user=user, table=table, type_name="date", name="Date") date_field_2 = field_handler.create_field( user=user, table=table, type_name="date", name="Datetime", date_include_time=True, ) assert date_field_1.date_include_time is False assert date_field_2.date_include_time is True assert len(DateField.objects.all()) == 2 model = table.get_model(attribute_names=True) row = row_handler.create_row(user=user, table=table, values={}, model=model) assert row.date is None assert row.datetime is None row = row_handler.create_row( user=user, table=table, values={ "date": "2020-4-1", "datetime": "2020-4-1 12:30:30" }, model=model, ) row.refresh_from_db() assert row.date == date(2020, 4, 1) assert row.datetime == datetime(2020, 4, 1, 12, 30, 30, tzinfo=utc) row = row_handler.create_row( user=user, table=table, values={ "datetime": make_aware(datetime(2020, 4, 1, 12, 30, 30), amsterdam) }, model=model, ) row.refresh_from_db() assert row.date is None assert row.datetime == datetime(2020, 4, 1, 10, 30, 30, tzinfo=timezone("UTC")) date_field_1 = field_handler.update_field(user=user, field=date_field_1, date_include_time=True) date_field_2 = field_handler.update_field(user=user, field=date_field_2, date_include_time=False) assert date_field_1.date_include_time is True assert date_field_2.date_include_time is False model = table.get_model(attribute_names=True) rows = model.objects.all() assert rows[0].date is None assert rows[0].datetime is None assert rows[1].date == datetime(2020, 4, 1, tzinfo=timezone("UTC")) assert rows[1].datetime == date(2020, 4, 1) assert rows[2].date is None assert rows[2].datetime == date(2020, 4, 1) field_handler.delete_field(user=user, field=date_field_1) field_handler.delete_field(user=user, field=date_field_2) assert len(DateField.objects.all()) == 0
def test_link_row_field_type_api_row_views(api_client, data_fixture): user, token = data_fixture.create_user_and_token() database = data_fixture.create_database_application(user=user, name="Placeholder") example_table = data_fixture.create_database_table( name="Example", database=database ) customers_table = data_fixture.create_database_table( name="Customers", database=database ) grid = data_fixture.create_grid_view(table=example_table) data_fixture.create_text_field(name="Name", table=example_table, primary=True) customers_primary = data_fixture.create_text_field( name="Customer name", table=customers_table, primary=True ) field_handler = FieldHandler() row_handler = RowHandler() link_row_field = field_handler.create_field( user=user, table=example_table, type_name="link_row", link_row_table=customers_table, ) customers_row_1 = row_handler.create_row( user=user, table=customers_table, values={f"field_{customers_primary.id}": "John Doe"}, ) customers_row_2 = row_handler.create_row( user=user, table=customers_table, values={f"field_{customers_primary.id}": "Jane Doe"}, ) customers_row_3 = row_handler.create_row(user=user, table=customers_table) response = api_client.post( reverse("api:database:rows:list", kwargs={"table_id": example_table.id}), { f"field_{link_row_field.id}": "Random", }, format="json", HTTP_AUTHORIZATION=f"JWT {token}", ) response_json = response.json() assert response.status_code == HTTP_400_BAD_REQUEST assert response_json["error"] == "ERROR_REQUEST_BODY_VALIDATION" assert ( response_json["detail"][f"field_{link_row_field.id}"][0]["code"] == "not_a_list" ) response = api_client.post( reverse("api:database:rows:list", kwargs={"table_id": example_table.id}), { f"field_{link_row_field.id}": ["a"], }, format="json", HTTP_AUTHORIZATION=f"JWT {token}", ) response_json = response.json() assert response.status_code == HTTP_400_BAD_REQUEST assert response_json["error"] == "ERROR_REQUEST_BODY_VALIDATION" assert ( response_json["detail"][f"field_{link_row_field.id}"]["0"][0]["code"] == "invalid" ) response = api_client.post( reverse("api:database:rows:list", kwargs={"table_id": example_table.id}), { f"field_{link_row_field.id}": [customers_row_1.id, customers_row_2.id, 999], }, format="json", HTTP_AUTHORIZATION=f"JWT {token}", ) response_json = response.json() row_id = response_json["id"] assert response.status_code == HTTP_200_OK assert len(response_json[f"field_{link_row_field.id}"]) == 2 assert response_json[f"field_{link_row_field.id}"][0]["id"] == customers_row_1.id assert response_json[f"field_{link_row_field.id}"][0]["value"] == "John Doe" assert response_json[f"field_{link_row_field.id}"][1]["id"] == customers_row_2.id assert response_json[f"field_{link_row_field.id}"][1]["value"] == "Jane Doe" model = example_table.get_model() assert model.objects.all().count() == 1 url = reverse( "api:database:rows:item", kwargs={"table_id": example_table.id, "row_id": row_id}, ) response = api_client.patch( url, { f"field_{link_row_field.id}": [], }, format="json", HTTP_AUTHORIZATION=f"JWT {token}", ) response_json = response.json() assert response.status_code == HTTP_200_OK assert len(response_json[f"field_{link_row_field.id}"]) == 0 url = reverse( "api:database:rows:item", kwargs={"table_id": example_table.id, "row_id": row_id}, ) response = api_client.patch( url, { f"field_{link_row_field.id}": [customers_row_2.id, customers_row_3.id], }, format="json", HTTP_AUTHORIZATION=f"JWT {token}", ) response_json = response.json() assert response.status_code == HTTP_200_OK assert len(response_json[f"field_{link_row_field.id}"]) == 2 assert response_json[f"field_{link_row_field.id}"][0]["id"] == customers_row_2.id assert response_json[f"field_{link_row_field.id}"][0]["value"] == "Jane Doe" assert response_json[f"field_{link_row_field.id}"][1]["id"] == customers_row_3.id assert not response_json[f"field_{link_row_field.id}"][1]["value"] url = reverse("api:database:views:grid:list", kwargs={"view_id": grid.id}) response = api_client.get(url, **{"HTTP_AUTHORIZATION": f"JWT {token}"}) response_json = response.json() assert response.status_code == HTTP_200_OK assert response_json["count"] == 1 assert response_json["results"][0]["id"] == row_id assert len(response_json["results"][0][f"field_{link_row_field.id}"]) == 2 url = reverse( "api:database:rows:item", kwargs={"table_id": example_table.id, "row_id": row_id}, ) response = api_client.delete(url, HTTP_AUTHORIZATION=f"JWT {token}") assert response.status_code == HTTP_204_NO_CONTENT assert model.objects.all().count() == 0 response = api_client.post( reverse("api:database:rows:list", kwargs={"table_id": example_table.id}), {}, format="json", HTTP_AUTHORIZATION=f"JWT {token}", ) response_json = response.json() assert response.status_code == HTTP_200_OK assert len(response_json[f"field_{link_row_field.id}"]) == 0
def test_link_row_field_type_rows(data_fixture): user = data_fixture.create_user() database = data_fixture.create_database_application(user=user, name="Placeholder") example_table = data_fixture.create_database_table( name="Example", database=database ) customers_table = data_fixture.create_database_table( name="Customers", database=database ) data_fixture.create_text_field(name="Name", table=customers_table, primary=True) users_table = data_fixture.create_database_table(name="Users", database=database) field_handler = FieldHandler() row_handler = RowHandler() link_row_field = field_handler.create_field( user=user, table=example_table, type_name="link_row", link_row_table=customers_table, ) customers_row_1 = row_handler.create_row(user=user, table=customers_table) customers_row_2 = row_handler.create_row(user=user, table=customers_table) customers_row_3 = row_handler.create_row(user=user, table=customers_table) row = row_handler.create_row( user=user, table=example_table, values={ f"field_{link_row_field.id}": [customers_row_1.id, customers_row_2.id], }, ) row_2 = row_handler.create_row( user=user, table=example_table, values={ f"field_{link_row_field.id}": [customers_row_1.id], }, ) example_table.name = "Example2" example_table.save() customers_table.name = "Customers2" customers_table.save() row_1_all = getattr(row, f"field_{link_row_field.id}").all() row_2_all = getattr(row_2, f"field_{link_row_field.id}").all() row_1_ids = [i.id for i in row_1_all] row_2_ids = [i.id for i in row_2_all] assert row_1_all.count() == 2 assert row_2_all.count() == 1 assert customers_row_1.id in row_1_ids assert customers_row_2.id in row_1_ids assert customers_row_1.id in row_2_ids row = row_handler.update_row( user=user, table=example_table, row_id=row.id, values={f"field_{link_row_field.id}": [customers_row_3.id]}, ) row_2 = row_handler.update_row( user=user, table=example_table, row_id=row_2.id, values={f"field_{link_row_field.id}": [customers_row_2.id, customers_row_1.id]}, ) row_1_all = getattr(row, f"field_{link_row_field.id}").all() row_2_all = getattr(row_2, f"field_{link_row_field.id}").all() row_1_ids = [i.id for i in row_1_all] row_2_ids = [i.id for i in row_2_all] assert row_1_all.count() == 1 assert row_2_all.count() == 2 assert customers_row_3.id in row_1_ids assert customers_row_1.id in row_2_ids assert customers_row_2.id in row_2_ids # Check if the relations are there via the customers table. customers_table.refresh_from_db() customers_model = customers_table.get_model() related_field = link_row_field.link_row_related_field customer_rows = customers_model.objects.all() assert customer_rows.count() == 3 customers_row_1 = customer_rows[0] customers_row_2 = customer_rows[1] customers_row_3 = customer_rows[2] customer_row_1_all = getattr(customers_row_1, f"field_{related_field.id}").all() customer_row_2_all = getattr(customers_row_2, f"field_{related_field.id}").all() customer_row_3_all = getattr(customers_row_3, f"field_{related_field.id}").all() assert customer_row_1_all.count() == 1 assert customer_row_2_all.count() == 1 assert customer_row_3_all.count() == 1 customers_row_1_ids = [i.id for i in customer_row_1_all] customers_row_2_ids = [i.id for i in customer_row_2_all] customers_row_3_ids = [i.id for i in customer_row_3_all] assert row_2.id in customers_row_1_ids assert row_2.id in customers_row_2_ids assert row.id in customers_row_3_ids # When changing the link row table table all the existing relations should be # deleted. link_row_field = field_handler.update_field( user=user, field=link_row_field, type_name="link_row", link_row_table=users_table, ) example_table.refresh_from_db() model = example_table.get_model() rows = model.objects.all() row = rows[0] row_2 = rows[1] assert getattr(row, f"field_{link_row_field.id}").all().count() == 0 assert getattr(row_2, f"field_{link_row_field.id}").all().count() == 0 # Just check if the field can be deleted can be deleted. field_handler.delete_field(user=user, field=link_row_field) # We expect only the primary field to be left. assert Field.objects.all().count() == 1
def test_converting_date_field_value(data_fixture): user = data_fixture.create_user() table = data_fixture.create_database_table(user=user) field_handler = FieldHandler() row_handler = RowHandler() utc = timezone('utc') date_field_eu = data_fixture.create_text_field(table=table) date_field_us = data_fixture.create_text_field(table=table) date_field_iso = data_fixture.create_text_field(table=table) date_field_eu_12 = data_fixture.create_text_field(table=table) date_field_us_12 = data_fixture.create_text_field(table=table) date_field_iso_12 = data_fixture.create_text_field(table=table) date_field_eu_24 = data_fixture.create_text_field(table=table) date_field_us_24 = data_fixture.create_text_field(table=table) date_field_iso_24 = data_fixture.create_text_field(table=table) model = table.get_model() row_handler.create_row( user=user, table=table, model=model, values={ f'field_{date_field_eu.id}': '22/07/2021', f'field_{date_field_us.id}': '07/22/2021', f'field_{date_field_iso.id}': '2021-07-22', f'field_{date_field_eu_12.id}': '22/07/2021 12:45 PM', f'field_{date_field_us_12.id}': '07/22/2021 12:45 PM', f'field_{date_field_iso_12.id}': '2021-07-22 12:45 PM', f'field_{date_field_eu_24.id}': '22/07/2021 12:45', f'field_{date_field_us_24.id}': '07/22/2021 12:45', f'field_{date_field_iso_24.id}': '2021-07-22 12:45', }) row_handler.create_row( user=user, table=table, model=model, values={ f'field_{date_field_eu.id}': '22-7-2021', f'field_{date_field_us.id}': '7-22-2021', f'field_{date_field_iso.id}': '2021/7/22', f'field_{date_field_eu_12.id}': '22-7-2021 12:45am', f'field_{date_field_us_12.id}': '7-22-2021 12:45am', f'field_{date_field_iso_12.id}': '2021/7/22 12:45am', f'field_{date_field_eu_24.id}': '22-7-2021 7:45', f'field_{date_field_us_24.id}': '7-22-2021 7:45', f'field_{date_field_iso_24.id}': '2021/7/22 7:45', }) row_handler.create_row( user=user, table=table, model=model, values={ f'field_{date_field_eu.id}': '22/07/2021 12:00', f'field_{date_field_us.id}': '07/22/2021 12:00am', f'field_{date_field_iso.id}': '2021-07-22 12:00 PM', f'field_{date_field_eu_12.id}': 'INVALID', f'field_{date_field_us_12.id}': '2222-2222-2222', f'field_{date_field_iso_12.id}': 'x-7--1', f'field_{date_field_eu_24.id}': '22-7-2021 7:45:12', f'field_{date_field_us_24.id}': '7-22-2021 7:45:23', f'field_{date_field_iso_24.id}': '2021/7/22 7:45:70' }) row_handler.create_row( user=user, table=table, model=model, values={ f'field_{date_field_eu.id}': '2018-08-20T13:20:10', f'field_{date_field_us.id}': '2017 Mar 03 05:12:41.211', f'field_{date_field_iso.id}': '19/Apr/2017:06:36:15', f'field_{date_field_eu_12.id}': 'Dec 2, 2017 2:39:58 AM', f'field_{date_field_us_12.id}': 'Jun 09 2018 15:28:14', f'field_{date_field_iso_12.id}': 'Apr 20 00:00:35 2010', f'field_{date_field_eu_24.id}': 'Apr 20 00:00:35 2010', f'field_{date_field_us_24.id}': '2018-02-27 15:35:20.311', f'field_{date_field_iso_24.id}': '10-04-19 12:00:17' }) date_field_eu = field_handler.update_field(user=user, field=date_field_eu, new_type_name='date', date_format='EU') date_field_us = field_handler.update_field(user=user, field=date_field_us, new_type_name='date', date_format='US') date_field_iso = field_handler.update_field(user=user, field=date_field_iso, new_type_name='date', date_format='ISO') date_field_eu_12 = field_handler.update_field(user=user, field=date_field_eu_12, new_type_name='date', date_format='EU', date_include_time=True, date_time_format='12') date_field_us_12 = field_handler.update_field(user=user, field=date_field_us_12, new_type_name='date', date_format='US', date_include_time=True, date_time_format='12') date_field_iso_12 = field_handler.update_field(user=user, field=date_field_iso_12, new_type_name='date', date_format='ISO', date_include_time=True, date_time_format='12') date_field_eu_24 = field_handler.update_field(user=user, field=date_field_eu_24, new_type_name='date', date_format='EU', date_include_time=True, date_time_format='24') date_field_us_24 = field_handler.update_field(user=user, field=date_field_us_24, new_type_name='date', date_format='US', date_include_time=True, date_time_format='24') date_field_iso_24 = field_handler.update_field(user=user, field=date_field_iso_24, new_type_name='date', date_format='ISO', date_include_time=True, date_time_format='24') model = table.get_model() rows = model.objects.all() assert getattr(rows[0], f'field_{date_field_eu.id}') == date(2021, 7, 22) assert getattr(rows[0], f'field_{date_field_us.id}') == date(2021, 7, 22) assert getattr(rows[0], f'field_{date_field_iso.id}') == date(2021, 7, 22) assert getattr(rows[0], f'field_{date_field_eu_12.id}') == (datetime(2021, 7, 22, 12, 45, 0, tzinfo=utc)) assert getattr(rows[0], f'field_{date_field_us_12.id}') == (datetime(2021, 7, 22, 12, 45, 0, tzinfo=utc)) assert getattr(rows[0], f'field_{date_field_iso_12.id}') == (datetime(2021, 7, 22, 12, 45, 0, tzinfo=utc)) assert getattr(rows[0], f'field_{date_field_eu_24.id}') == (datetime(2021, 7, 22, 12, 45, 0, tzinfo=utc)) assert getattr(rows[0], f'field_{date_field_us_24.id}') == (datetime(2021, 7, 22, 12, 45, 0, tzinfo=utc)) assert getattr(rows[0], f'field_{date_field_iso_24.id}') == (datetime(2021, 7, 22, 12, 45, 0, tzinfo=utc)) assert getattr(rows[1], f'field_{date_field_eu.id}') == date(2021, 7, 22) assert getattr(rows[1], f'field_{date_field_us.id}') == date(2021, 7, 22) assert getattr(rows[1], f'field_{date_field_iso.id}') == date(2021, 7, 22) assert getattr(rows[1], f'field_{date_field_eu_12.id}') == (datetime(2021, 7, 22, 0, 45, 0, tzinfo=utc)) assert getattr(rows[1], f'field_{date_field_us_12.id}') == (datetime(2021, 7, 22, 0, 45, 0, tzinfo=utc)) assert getattr(rows[1], f'field_{date_field_iso_12.id}') == (datetime(2021, 7, 22, 0, 45, 0, tzinfo=utc)) assert getattr(rows[1], f'field_{date_field_eu_24.id}') == (datetime(2021, 7, 22, 7, 45, 0, tzinfo=utc)) assert getattr(rows[1], f'field_{date_field_us_24.id}') == (datetime(2021, 7, 22, 7, 45, 0, tzinfo=utc)) assert getattr(rows[1], f'field_{date_field_iso_24.id}') == (datetime(2021, 7, 22, 7, 45, 0, tzinfo=utc)) assert getattr(rows[2], f'field_{date_field_eu.id}') == date(2021, 7, 22) assert getattr(rows[2], f'field_{date_field_us.id}') == date(2021, 7, 22) assert getattr(rows[2], f'field_{date_field_iso.id}') == date(2021, 7, 22) assert getattr(rows[2], f'field_{date_field_eu_12.id}') is None assert getattr(rows[2], f'field_{date_field_us_12.id}') is None assert getattr(rows[2], f'field_{date_field_iso_12.id}') is None assert getattr(rows[2], f'field_{date_field_eu_24.id}') == (datetime(2021, 7, 22, 7, 45, 0, tzinfo=utc)) assert getattr(rows[2], f'field_{date_field_us_24.id}') == (datetime(2021, 7, 22, 7, 45, 0, tzinfo=utc)) assert getattr(rows[2], f'field_{date_field_iso_24.id}') == (datetime(2021, 7, 22, 7, 45, 0, tzinfo=utc)) """ f'field_{date_field_eu.id}': '2018-08-20T13:20:10', f'field_{date_field_us.id}': '2017 Mar 03 05:12:41.211', f'field_{date_field_iso.id}': '19/Apr/2017:06:36:15', f'field_{date_field_eu_12.id}': 'Dec 2, 2017 2:39:58 AM', f'field_{date_field_us_12.id}': 'Jun 09 2018 15:28:14', f'field_{date_field_iso_12.id}': 'Apr 20 00:00:35 2010', f'field_{date_field_eu_24.id}': 'Apr 20 00:00:35 2010', f'field_{date_field_us_24.id}': '2018-02-27 15:35:20.311', f'field_{date_field_iso_24.id}': '10-04-19 12:00:17' """ assert getattr(rows[3], f'field_{date_field_eu.id}') == date(2018, 8, 20) assert getattr(rows[3], f'field_{date_field_us.id}') == date(2017, 3, 3) assert getattr(rows[3], f'field_{date_field_iso.id}') == date(2017, 4, 19) assert getattr(rows[3], f'field_{date_field_eu_12.id}') == (datetime(2017, 12, 2, 2, 39, 58, tzinfo=utc)) assert getattr(rows[3], f'field_{date_field_us_12.id}') == (datetime(2018, 6, 9, 15, 28, 14, tzinfo=utc)) assert getattr(rows[3], f'field_{date_field_iso_12.id}') == (datetime(2010, 4, 20, 0, 0, 35, tzinfo=utc)) assert getattr(rows[3], f'field_{date_field_eu_24.id}') == (datetime(2010, 4, 20, 0, 0, 35, tzinfo=utc)) assert getattr(rows[3], f'field_{date_field_us_24.id}') == (datetime(2018, 2, 27, 15, 35, 20, 311000, tzinfo=utc)) assert getattr(rows[3], f'field_{date_field_iso_24.id}') == (datetime(10, 4, 19, 12, 0, tzinfo=utc)) date_field_eu = field_handler.update_field(user=user, field=date_field_eu, new_type_name='text') date_field_us = field_handler.update_field(user=user, field=date_field_us, new_type_name='text') date_field_iso = field_handler.update_field(user=user, field=date_field_iso, new_type_name='text') date_field_eu_12 = field_handler.update_field(user=user, field=date_field_eu_12, new_type_name='text') date_field_us_12 = field_handler.update_field(user=user, field=date_field_us_12, new_type_name='text') date_field_iso_12 = field_handler.update_field(user=user, field=date_field_iso_12, new_type_name='text') date_field_eu_24 = field_handler.update_field(user=user, field=date_field_eu_24, new_type_name='text') date_field_us_24 = field_handler.update_field(user=user, field=date_field_us_24, new_type_name='text') date_field_iso_24 = field_handler.update_field(user=user, field=date_field_iso_24, new_type_name='text') model = table.get_model() rows = model.objects.all() assert getattr(rows[0], f'field_{date_field_eu.id}') == '22/07/2021' assert getattr(rows[0], f'field_{date_field_us.id}') == '07/22/2021' assert getattr(rows[0], f'field_{date_field_iso.id}') == '2021-07-22' assert getattr(rows[0], f'field_{date_field_eu_12.id}') == '22/07/2021 12:45PM' assert getattr(rows[0], f'field_{date_field_us_12.id}') == '07/22/2021 12:45PM' assert getattr(rows[0], f'field_{date_field_iso_12.id}') == '2021-07-22 12:45PM' assert getattr(rows[0], f'field_{date_field_eu_24.id}') == '22/07/2021 12:45' assert getattr(rows[0], f'field_{date_field_us_24.id}') == '07/22/2021 12:45' assert getattr(rows[0], f'field_{date_field_iso_24.id}') == '2021-07-22 12:45' assert getattr(rows[2], f'field_{date_field_eu_12.id}') is None
def test_exporting_csv_table_writes_file_to_storage(data_fixture, api_client, tmpdir, settings): user, token = data_fixture.create_user_and_token() table = data_fixture.create_database_table(user=user) text_field = data_fixture.create_text_field(table=table, name="text_field", order=0) option_field = data_fixture.create_single_select_field(table=table, name="option_field", order=1) option_a = data_fixture.create_select_option(field=option_field, value="A", color="blue") option_b = data_fixture.create_select_option(field=option_field, value="B", color="red") date_field = data_fixture.create_date_field( table=table, date_include_time=True, date_format="US", name="date_field", order=2, ) grid_view = data_fixture.create_grid_view(table=table) data_fixture.create_view_filter(view=grid_view, field=text_field, type="contains", value="test") data_fixture.create_view_sort(view=grid_view, field=text_field, order="ASC") row_handler = RowHandler() row_handler.create_row( user=user, table=table, values={ text_field.id: "test", date_field.id: "2020-02-01 01:23", option_field.id: option_b.id, }, ) row_handler.create_row( user=user, table=table, values={ text_field.id: "atest", date_field.id: "2020-02-01 01:23", option_field.id: option_a.id, }, ) storage = FileSystemStorage(location=(str(tmpdir)), base_url="http://localhost") with patch("baserow.contrib.database.export.handler.default_storage", new=storage): run_time = make_aware(parse_datetime("2020-02-01 01:00"), timezone=utc) # DRF uses some custom internal date time formatting, use the field itself # so the test doesn't break if we set a different default timezone format etc expected_created_at = DateTimeField().to_representation(run_time) with freeze_time(run_time): with capture_on_commit_callbacks(execute=True): response = api_client.post( reverse( "api:database:export:export_table", kwargs={"table_id": table.id}, ), data={ "view_id": None, "exporter_type": "csv", "export_charset": "utf-8", "csv_include_header": "True", "csv_column_separator": ",", }, format="json", HTTP_AUTHORIZATION=f"JWT {token}", ) response_json = response.json() job_id = response_json["id"] assert response_json == { "id": job_id, "created_at": expected_created_at, "exported_file_name": None, "exporter_type": "csv", "progress_percentage": 0.0, "status": "pending", "table": table.id, "view": None, "url": None, } response = api_client.get( reverse("api:database:export:get", kwargs={"job_id": job_id}), format="json", HTTP_AUTHORIZATION=f"JWT {token}", ) json = response.json() filename = json["exported_file_name"] assert json == { "id": job_id, "created_at": expected_created_at, "exported_file_name": filename, "exporter_type": "csv", "progress_percentage": 1.0, "status": "complete", "table": table.id, "view": None, "url": f"http://localhost:8000/media/export_files/{filename}", } file_path = tmpdir.join(settings.EXPORT_FILES_DIRECTORY, filename) assert file_path.isfile() expected = ("\ufeff" "id,text_field,option_field,date_field\n" "1,test,B,02/01/2020 01:23\n" "2,atest,A,02/01/2020 01:23\n") with open(file_path, "r", encoding="utf-8") as written_file: assert written_file.read() == expected
def test_link_row_field_type(data_fixture): user = data_fixture.create_user() database = data_fixture.create_database_application(user=user, name="Placeholder") table = data_fixture.create_database_table(name="Example", database=database) customers_table = data_fixture.create_database_table( name="Customers", database=database ) cars_table = data_fixture.create_database_table(name="Cars", database=database) unrelated_table_1 = data_fixture.create_database_table(name="Unrelated") field_handler = FieldHandler() row_handler = RowHandler() # Create a primary field and some example data for the customers table. customers_primary_field = field_handler.create_field( user=user, table=customers_table, type_name="text", name="Name", primary=True ) customers_row_1 = row_handler.create_row( user=user, table=customers_table, values={f"field_{customers_primary_field.id}": "John"}, ) customers_row_2 = row_handler.create_row( user=user, table=customers_table, values={f"field_{customers_primary_field.id}": "Jane"}, ) # Create a primary field and some example data for the cars table. cars_primary_field = field_handler.create_field( user=user, table=cars_table, type_name="text", name="Name", primary=True ) row_handler.create_row( user=user, table=cars_table, values={f"field_{cars_primary_field.id}": "BMW"} ) row_handler.create_row( user=user, table=cars_table, values={f"field_{cars_primary_field.id}": "Audi"} ) with pytest.raises(LinkRowTableNotProvided): field_handler.create_field( user=user, table=table, type_name="link_row", name="Without table" ) with pytest.raises(LinkRowTableNotInSameDatabase): field_handler.create_field( user=user, table=table, type_name="link_row", name="Unrelated", link_row_table=unrelated_table_1, ) link_field_1 = field_handler.create_field( user=user, table=table, type_name="link_row", name="Customer", link_row_table=customers_table, ) link_field_2 = field_handler.create_field( user=user, table=table, type_name="link_row", name="Customer", link_row_table=customers_table, ) assert link_field_1.link_row_related_field.name == "Example" assert link_field_2.link_row_related_field.name == "Example" connection = connections["default"] tables = connection.introspection.table_names() assert ( link_field_1.through_table_name == link_field_1.link_row_related_field.through_table_name ) assert ( link_field_2.through_table_name == link_field_2.link_row_related_field.through_table_name ) assert link_field_1.through_table_name in tables assert link_field_2.through_table_name in tables model = table.get_model() table_row = model.objects.create() getattr(table_row, f"field_{link_field_1.id}").add(customers_row_1.id) results = getattr(table_row, f"field_{link_field_1.id}").all() assert len(results) == 1 assert getattr(results[0], f"field_{customers_primary_field.id}") == "John" getattr(table_row, f"field_{link_field_2.id}").add( customers_row_1.id, customers_row_2.id ) results = getattr(table_row, f"field_{link_field_2.id}").all() assert len(results) == 2 assert getattr(results[0], f"field_{customers_primary_field.id}") == "John" assert getattr(results[1], f"field_{customers_primary_field.id}") == "Jane" table_row_2 = model.objects.create() getattr(table_row_2, f"field_{link_field_1.id}").add(customers_row_2.id) results = getattr(table_row_2, f"field_{link_field_1.id}").all() assert len(results) == 1 assert getattr(results[0], f"field_{customers_primary_field.id}") == "Jane" # Going to change only the name of the field. This should not result in any errors # of schema changes. link_field_1 = field_handler.update_field(user, link_field_1, name="Customer 2") with pytest.raises(LinkRowTableNotInSameDatabase): field_handler.update_field(user, link_field_1, link_row_table=unrelated_table_1) model = table.get_model() assert model.objects.all().count() == 2 # Change the table, this should destroy all relations. old_link_field_1_relation_id = link_field_1.link_row_relation_id link_field_1 = field_handler.update_field( user, link_field_1, link_row_table=cars_table ) model = table.get_model() table_rows = model.objects.all() table_row = table_rows[0] table_row_2 = table_rows[1] assert link_field_1.link_row_table.id == cars_table.id assert link_field_1.link_row_relation_id == old_link_field_1_relation_id assert getattr(table_row, f"field_{link_field_1.id}").all().count() == 0 assert getattr(table_row, f"field_{link_field_2.id}").all().count() == 2 assert getattr(table_row_2, f"field_{link_field_1.id}").all().count() == 0 assert getattr(table_row_2, f"field_{link_field_2.id}").all().count() == 0 link_field_2 = field_handler.update_field(user, link_field_2, new_type_name="text") model = table.get_model() table_row = model.objects.all().first() assert getattr(table_row, f"field_{link_field_2.id}") is None assert LinkRowField.objects.all().count() == 2 setattr(table_row, f"field_{link_field_2.id}", "Text value") table_row.save() assert getattr(table_row, f"field_{link_field_2.id}") == "Text value" # Delete the existing field. Alter that the related field should be deleted and # no table named _relation_ should exist. field_handler.delete_field(user, link_field_1) assert LinkRowField.objects.all().count() == 0 for t in connection.introspection.table_names(): if "_relation_" in t: assert False # Change a the text field back into a link row field. link_field_2 = field_handler.update_field( user, link_field_2, new_type_name="link_row", link_row_table=customers_table ) assert link_field_2.link_row_related_field.name == "Example" assert ( link_field_2.through_table_name == link_field_2.link_row_related_field.through_table_name ) assert link_field_2.through_table_name in connection.introspection.table_names() assert LinkRowField.objects.all().count() == 2 model = table.get_model() table_row = model.objects.all().first() getattr(table_row, f"field_{link_field_2.id}").add( customers_row_1.id, customers_row_2.id ) results = getattr(table_row, f"field_{link_field_2.id}").all() assert len(results) == 2 assert getattr(results[0], f"field_{customers_primary_field.id}") == "John" assert getattr(results[1], f"field_{customers_primary_field.id}") == "Jane"
def test_file_field_type(data_fixture): user = data_fixture.create_user() table = data_fixture.create_database_table(user=user) user_file_1 = data_fixture.create_user_file() user_file_2 = data_fixture.create_user_file() user_file_3 = data_fixture.create_user_file() field_handler = FieldHandler() row_handler = RowHandler() file = field_handler.create_field(user=user, table=table, type_name='file', name='File') assert FileField.objects.all().count() == 1 model = table.get_model(attribute_names=True) with pytest.raises(ValidationError): row_handler.create_row(user=user, table=table, values={ 'file': 'not_a_json' }, model=model) with pytest.raises(ValidationError): row_handler.create_row(user=user, table=table, values={ 'file': {} }, model=model) with pytest.raises(ValidationError): row_handler.create_row(user=user, table=table, values={ 'file': [{'no_name': 'test'}] }, model=model) with pytest.raises(InvalidUserFileNameError): row_handler.create_row(user=user, table=table, values={ 'file': [{'name': 'wrongfilename.jpg'}] }, model=model) with pytest.raises(UserFileDoesNotExist): row_handler.create_row(user=user, table=table, values={ 'file': [{'name': 'file_name.jpg'}] }, model=model) row = row_handler.create_row(user=user, table=table, values={ 'file': [{'name': user_file_1.name}] }, model=model) assert row.file[0]['visible_name'] == user_file_1.original_name del row.file[0]['visible_name'] assert row.file[0] == user_file_1.serialize() row = row_handler.create_row(user=user, table=table, values={ 'file': [ {'name': user_file_2.name}, {'name': user_file_1.name}, {'name': user_file_1.name} ] }, model=model) assert row.file[0]['visible_name'] == user_file_2.original_name assert row.file[1]['visible_name'] == user_file_1.original_name assert row.file[2]['visible_name'] == user_file_1.original_name del row.file[0]['visible_name'] del row.file[1]['visible_name'] del row.file[2]['visible_name'] assert row.file[0] == user_file_2.serialize() assert row.file[1] == user_file_1.serialize() assert row.file[2] == user_file_1.serialize() row = row_handler.create_row(user=user, table=table, values={ 'file': [ {'name': user_file_1.name}, {'name': user_file_3.name}, {'name': user_file_2.name} ] }, model=model) assert row.file[0]['visible_name'] == user_file_1.original_name assert row.file[1]['visible_name'] == user_file_3.original_name assert row.file[2]['visible_name'] == user_file_2.original_name del row.file[0]['visible_name'] del row.file[1]['visible_name'] del row.file[2]['visible_name'] assert row.file[0] == user_file_1.serialize() assert row.file[1] == user_file_3.serialize() assert row.file[2] == user_file_2.serialize() row = row_handler.update_row(user=user, table=table, row_id=row.id, values={ 'file': [ {'name': user_file_1.name, 'visible_name': 'not_original.jpg'}, ] }, model=model) assert row.file[0]['visible_name'] == 'not_original.jpg' del row.file[0]['visible_name'] assert row.file[0] == user_file_1.serialize() assert model.objects.all().count() == 3 field_handler.delete_field(user=user, field=file) assert FileField.objects.all().count() == 0 model.objects.all().delete() text = field_handler.create_field(user=user, table=table, type_name='text', name='Text') model = table.get_model(attribute_names=True) row = row_handler.create_row(user=user, table=table, values={ 'text': 'Some random text' }, model=model) row_handler.create_row(user=user, table=table, values={ 'text': '["Not compatible"]' }, model=model) row_handler.create_row(user=user, table=table, values={ 'text': json.dumps(user_file_1.serialize()) }, model=model) file = field_handler.update_field(user=user, table=table, field=text, new_type_name='file', name='File') model = table.get_model(attribute_names=True) results = model.objects.all() assert results[0].file == [] assert results[1].file == [] assert results[2].file == [] row_handler.update_row(user=user, table=table, row_id=row.id, values={ 'file': [ {'name': user_file_1.name, 'visible_name': 'not_original.jpg'}, ] }, model=model) field_handler.update_field(user=user, table=table, field=file, new_type_name='text', name='text') model = table.get_model(attribute_names=True) results = model.objects.all() assert results[0].text is None assert results[1].text is None assert results[2].text is None
def test_import_export_link_row_field(data_fixture, user_tables_in_separate_db): user = data_fixture.create_user() imported_group = data_fixture.create_group(user=user) database = data_fixture.create_database_application(user=user, name="Placeholder") table = data_fixture.create_database_table(name="Example", database=database) customers_table = data_fixture.create_database_table( name="Customers", database=database ) field_handler = FieldHandler() core_handler = CoreHandler() link_row_field = field_handler.create_field( user=user, table=table, type_name="link_row", link_row_table=customers_table ) row_handler = RowHandler() c_row = row_handler.create_row(user=user, table=customers_table, values={}) c_row_2 = row_handler.create_row(user=user, table=customers_table, values={}) row = row_handler.create_row( user=user, table=table, values={f"field_{link_row_field.id}": [c_row.id, c_row_2.id]}, ) exported_applications = core_handler.export_group_applications( database.group, BytesIO() ) imported_applications, id_mapping = core_handler.import_applications_to_group( imported_group, exported_applications, BytesIO(), None ) imported_database = imported_applications[0] imported_tables = imported_database.table_set.all() imported_table = imported_tables[0] imported_customers_table = imported_tables[1] imported_link_row_field = imported_table.field_set.all().first().specific imported_link_row_relation_field = ( imported_customers_table.field_set.all().first().specific ) assert imported_table.id != table.id assert imported_table.name == table.name assert imported_customers_table.id != customers_table.id assert imported_customers_table.name == customers_table.name assert imported_link_row_field.id != link_row_field.id assert imported_link_row_field.name == link_row_field.name assert imported_link_row_field.link_row_table_id == imported_customers_table.id assert imported_link_row_relation_field.link_row_table_id == imported_table.id assert imported_link_row_field.link_row_relation_id == ( imported_link_row_relation_field.link_row_relation_id ) imported_c_row = row_handler.get_row( user=user, table=imported_customers_table, row_id=c_row.id ) imported_c_row_2 = row_handler.get_row( user=user, table=imported_customers_table, row_id=c_row_2.id ) imported_row = row_handler.get_row(user=user, table=imported_table, row_id=row.id) assert imported_row.id == row.id assert imported_c_row.id == c_row.id assert imported_c_row_2.id == c_row_2.id assert [ r.id for r in getattr(imported_row, f"field_{imported_link_row_field.id}").all() ] == [imported_c_row.id, imported_c_row_2.id]
def test_phone_number_field_type(data_fixture): user = data_fixture.create_user() table = data_fixture.create_database_table(user=user) data_fixture.create_database_table(user=user, database=table.database) field_handler = FieldHandler() row_handler = RowHandler() text_field = field_handler.create_field(user=user, table=table, order=1, type_name='text', name='name') phone_number_field = field_handler.create_field(user=user, table=table, type_name='phone_number', name='phonenumber') email_field = field_handler.create_field(user=user, table=table, type_name='email', name='email') number_field = data_fixture.create_number_field(table=table, order=1, number_negative=True, name="number") assert len(PhoneNumberField.objects.all()) == 1 model = table.get_model(attribute_names=True) with pytest.raises(ValidationError): row_handler.create_row(user=user, table=table, values={ 'phonenumber': 'invalid phone number' }, model=model) with pytest.raises(ValidationError): row_handler.create_row(user=user, table=table, values={ 'phonenumber': 'Phone: 2312321 2349432 ' }, model=model) with pytest.raises(ValidationError): row_handler.create_row(user=user, table=table, values={ 'phonenumber': '1' * (PhoneNumberFieldType.MAX_PHONE_NUMBER_LENGTH+1) }, model=model) max_length_phone_number = '1' * PhoneNumberFieldType.MAX_PHONE_NUMBER_LENGTH row_handler.create_row(user=user, table=table, values={ 'name': '+45(1424) 322314 324234', 'phonenumber': max_length_phone_number, 'number': 1234534532, 'email': '*****@*****.**' }, model=model) row_handler.create_row(user=user, table=table, values={ 'name': 'some text which should be blanked out after conversion', 'phonenumber': '1234567890 NnXx,+._*()#=;/ -', 'number': 0 }, model=model) row_handler.create_row(user=user, table=table, values={ 'name': max_length_phone_number, 'phonenumber': '', 'number': -10230450, }, model=model) row_handler.create_row(user=user, table=table, values={ 'phonenumber': None, 'name': '1' * (PhoneNumberFieldType.MAX_PHONE_NUMBER_LENGTH+1) }, model=model) row_handler.create_row(user=user, table=table, values={}, model=model) # No actual database type change occurs here as a phone number field is also a text # field. Instead the after_update hook is being used to clear out invalid # phone numbers. field_handler.update_field(user=user, field=text_field, new_type_name='phone_number') field_handler.update_field(user=user, field=number_field, new_type_name='phone_number') field_handler.update_field(user=user, field=email_field, new_type_name='phone_number') model = table.get_model(attribute_names=True) rows = model.objects.all() assert rows[0].name == '+45(1424) 322314 324234' assert rows[0].phonenumber == max_length_phone_number assert rows[0].number == '1234534532' assert rows[0].email == '' assert rows[1].name == '' assert rows[1].phonenumber == '1234567890 NnXx,+._*()#=;/ -' assert rows[1].number == '0' assert rows[2].name == max_length_phone_number assert rows[2].phonenumber == '' assert rows[2].number == '-10230450' assert rows[3].name == '' assert rows[3].phonenumber == '' assert rows[3].number == '' field_handler.delete_field(user=user, field=phone_number_field) assert len(PhoneNumberField.objects.all()) == 3