def test_create_filter(send_mock, data_fixture): user = data_fixture.create_user() user_2 = data_fixture.create_user() grid_view = data_fixture.create_grid_view(user=user) text_field = data_fixture.create_text_field(table=grid_view.table) other_field = data_fixture.create_text_field() handler = ViewHandler() with pytest.raises(UserNotInGroupError): handler.create_filter(user=user_2, view=grid_view, field=text_field, type_name='equal', value='test') grid_view_type = view_type_registry.get('grid') grid_view_type.can_filter = False with pytest.raises(ViewFilterNotSupported): handler.create_filter(user=user, view=grid_view, field=text_field, type_name='equal', value='test') grid_view_type.can_filter = True with pytest.raises(ViewFilterTypeDoesNotExist): handler.create_filter(user=user, view=grid_view, field=text_field, type_name='NOT_EXISTS', value='test') equal_filter_type = view_filter_type_registry.get('equal') allowed = equal_filter_type.compatible_field_types equal_filter_type.compatible_field_types = [] with pytest.raises(ViewFilterTypeNotAllowedForField): handler.create_filter(user=user, view=grid_view, field=text_field, type_name='equal', value='test') equal_filter_type.compatible_field_types = allowed with pytest.raises(FieldNotInTable): handler.create_filter(user=user, view=grid_view, field=other_field, type_name='equal', value='test') view_filter = handler.create_filter(user=user, view=grid_view, field=text_field, type_name='equal', value='test') send_mock.assert_called_once() assert send_mock.call_args[1]['view_filter'].id == view_filter.id assert send_mock.call_args[1]['user'].id == user.id assert ViewFilter.objects.all().count() == 1 first = ViewFilter.objects.all().first() assert view_filter.id == first.id assert view_filter.view_id == grid_view.id assert view_filter.field_id == text_field.id assert view_filter.type == 'equal' assert view_filter.value == 'test' tmp_field = Field.objects.get(pk=text_field.id) view_filter_2 = handler.create_filter(user=user, view=grid_view, field=tmp_field, type_name='equal', value='test') assert view_filter_2.view_id == grid_view.id assert view_filter_2.field_id == text_field.id assert view_filter_2.type == 'equal' assert view_filter_2.value == 'test'
def test_update_filter(send_mock, data_fixture): user = data_fixture.create_user() user_2 = data_fixture.create_user() grid_view = data_fixture.create_grid_view(user=user) text_field = data_fixture.create_text_field(table=grid_view.table) long_text_field = data_fixture.create_long_text_field( table=grid_view.table) other_field = data_fixture.create_text_field() equal_filter = data_fixture.create_view_filter(view=grid_view, field=long_text_field, type="equal", value="test1") handler = ViewHandler() with pytest.raises(UserNotInGroup): handler.update_filter(user=user_2, view_filter=equal_filter) with pytest.raises(ViewFilterTypeDoesNotExist): handler.update_filter(user=user, view_filter=equal_filter, type_name="NOT_EXISTS") equal_filter_type = view_filter_type_registry.get("equal") allowed = equal_filter_type.compatible_field_types equal_filter_type.compatible_field_types = [] with pytest.raises(ViewFilterTypeNotAllowedForField): handler.update_filter(user=user, view_filter=equal_filter, field=text_field) equal_filter_type.compatible_field_types = allowed with pytest.raises(FieldNotInTable): handler.update_filter(user=user, view_filter=equal_filter, field=other_field) updated_filter = handler.update_filter(user=user, view_filter=equal_filter, value="test2") send_mock.assert_called_once() assert send_mock.call_args[1]["view_filter"].id == updated_filter.id assert send_mock.call_args[1]["user"].id == user.id assert updated_filter.value == "test2" assert updated_filter.field_id == long_text_field.id assert updated_filter.type == "equal" assert updated_filter.view_id == grid_view.id updated_filter = handler.update_filter( user=user, view_filter=equal_filter, value="test3", field=text_field, type_name="not_equal", ) assert updated_filter.value == "test3" assert updated_filter.field_id == text_field.id assert updated_filter.type == "not_equal" assert updated_filter.view_id == grid_view.id
def test_update_filter(data_fixture): user = data_fixture.create_user() user_2 = data_fixture.create_user() grid_view = data_fixture.create_grid_view(user=user) text_field = data_fixture.create_text_field(table=grid_view.table) long_text_field = data_fixture.create_long_text_field( table=grid_view.table) other_field = data_fixture.create_text_field() equal_filter = data_fixture.create_view_filter(view=grid_view, field=long_text_field, type='equal', value='test1') handler = ViewHandler() with pytest.raises(UserNotInGroupError): handler.update_filter(user=user_2, view_filter=equal_filter) with pytest.raises(ViewFilterTypeDoesNotExist): handler.update_filter(user=user, view_filter=equal_filter, type_name='NOT_EXISTS') equal_filter_type = view_filter_type_registry.get('equal') allowed = equal_filter_type.compatible_field_types equal_filter_type.compatible_field_types = [] with pytest.raises(ViewFilterTypeNotAllowedForField): handler.update_filter(user=user, view_filter=equal_filter, field=text_field) equal_filter_type.compatible_field_types = allowed with pytest.raises(FieldNotInTable): handler.update_filter(user=user, view_filter=equal_filter, field=other_field) updated_filter = handler.update_filter(user=user, view_filter=equal_filter, value='test2') assert updated_filter.value == 'test2' assert updated_filter.field_id == long_text_field.id assert updated_filter.type == 'equal' assert updated_filter.view_id == grid_view.id updated_filter = handler.update_filter(user=user, view_filter=equal_filter, value='test3', field=text_field, type_name='not_equal') assert updated_filter.value == 'test3' assert updated_filter.field_id == text_field.id assert updated_filter.type == 'not_equal' assert updated_filter.view_id == grid_view.id
def filter_by_fields_object(self, filter_object, filter_type=FILTER_TYPE_AND): """ Filters the query by the provided filters in the filter_object. The following format `filter__field_{id}__{view_filter_type}` is expected as key and multiple values can be provided as a list containing strings. Only the view filter types are allowed. Example: { 'filter__field_{id}__{view_filter_type}': {value}. } :param filter_object: The object containing the field and filter type as key and the filter value as value. :type filter_object: object :param filter_type: Indicates if the provided filters are in an AND or OR statement. :type filter_type: str :raises ValueError: Raised when the provided filer_type isn't AND or OR. :raises FilterFieldNotFound: Raised when the provided field isn't found in the model. :raises ViewFilterTypeDoesNotExist: when the view filter type doesn't exist. :raises ViewFilterTypeNotAllowedForField: when the view filter type isn't compatible with field type. :return: The filtered queryset. :rtype: QuerySet """ if filter_type not in [FILTER_TYPE_AND, FILTER_TYPE_OR]: raise ValueError(f'Unknown filter type {filter_type}.') filter_builder = FilterBuilder(filter_type=filter_type) for key, values in filter_object.items(): matches = deconstruct_filter_key_regex.match(key) if not matches: continue field_id = int(matches[1]) if field_id not in self.model._field_objects: raise FilterFieldNotFound( field_id, f'Field {field_id} does not exist.' ) field_object = self.model._field_objects[field_id] field_name = field_object['name'] field_type = field_object['type'].type model_field = self.model._meta.get_field(field_name) view_filter_type = view_filter_type_registry.get(matches[2]) if field_type not in view_filter_type.compatible_field_types: raise ViewFilterTypeNotAllowedForField( matches[2], field_type, ) if not isinstance(values, list): values = [values] for value in values: filter_builder.filter( view_filter_type.get_filter( field_name, value, model_field, field_object['field'] ) ) return filter_builder.apply_to_queryset(self)
def test_update_view_filter(api_client, data_fixture): user, token = data_fixture.create_user_and_token() filter_1 = data_fixture.create_view_filter(user=user, value="test") filter_2 = data_fixture.create_view_filter() field_1 = data_fixture.create_text_field(table=filter_1.view.table) field_2 = data_fixture.create_text_field() response = api_client.patch( reverse( "api:database:views:filter_item", kwargs={"view_filter_id": filter_2.id} ), {"value": "test"}, format="json", HTTP_AUTHORIZATION=f"JWT {token}", ) assert response.status_code == HTTP_400_BAD_REQUEST assert response.json()["error"] == "ERROR_USER_NOT_IN_GROUP" response = api_client.patch( reverse("api:database:views:filter_item", kwargs={"view_filter_id": 9999}), {"value": "test"}, format="json", HTTP_AUTHORIZATION=f"JWT {token}", ) assert response.status_code == HTTP_404_NOT_FOUND assert response.json()["error"] == "ERROR_VIEW_FILTER_DOES_NOT_EXIST" response = api_client.patch( reverse( "api:database:views:filter_item", kwargs={"view_filter_id": filter_1.id} ), { "field": 9999999, "type": "NOT_EXISTING", }, 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"]["field"][0]["code"] == "does_not_exist" assert response_json["detail"]["type"][0]["code"] == "invalid_choice" response = api_client.patch( reverse( "api:database:views:filter_item", kwargs={"view_filter_id": filter_1.id} ), {"field": field_2.id}, format="json", HTTP_AUTHORIZATION=f"JWT {token}", ) response_json = response.json() assert response.status_code == HTTP_400_BAD_REQUEST assert response_json["error"] == "ERROR_FIELD_NOT_IN_TABLE" equal_filter_type = view_filter_type_registry.get("not_equal") allowed = equal_filter_type.compatible_field_types equal_filter_type.compatible_field_types = [] grid_view_type = view_type_registry.get("grid") grid_view_type.can_filter = False response = api_client.patch( reverse( "api:database:views:filter_item", kwargs={"view_filter_id": filter_1.id} ), {"type": "not_equal"}, format="json", HTTP_AUTHORIZATION=f"JWT {token}", ) grid_view_type.can_filter = True response_json = response.json() assert response.status_code == HTTP_400_BAD_REQUEST assert response_json["error"] == "ERROR_VIEW_FILTER_TYPE_UNSUPPORTED_FIELD" equal_filter_type.compatible_field_types = allowed response = api_client.patch( reverse( "api:database:views:filter_item", kwargs={"view_filter_id": filter_1.id} ), {"field": field_1.id, "type": "not_equal", "value": "test 2"}, format="json", HTTP_AUTHORIZATION=f"JWT {token}", ) response_json = response.json() assert response.status_code == HTTP_200_OK assert ViewFilter.objects.all().count() == 2 first = ViewFilter.objects.get(pk=filter_1.id) assert first.field_id == field_1.id assert first.type == "not_equal" assert first.value == "test 2" assert response_json["id"] == first.id assert response_json["view"] == first.view_id assert response_json["field"] == field_1.id assert response_json["type"] == "not_equal" assert response_json["value"] == "test 2" response = api_client.patch( reverse( "api:database:views:filter_item", kwargs={"view_filter_id": filter_1.id} ), {"type": "equal"}, format="json", HTTP_AUTHORIZATION=f"JWT {token}", ) response_json = response.json() assert response.status_code == HTTP_200_OK first = ViewFilter.objects.get(pk=filter_1.id) assert first.field_id == field_1.id assert first.type == "equal" assert first.value == "test 2" assert response_json["id"] == first.id assert response_json["field"] == field_1.id assert response_json["type"] == "equal" assert response_json["value"] == "test 2" response = api_client.patch( reverse( "api:database:views:filter_item", kwargs={"view_filter_id": filter_1.id} ), {"value": "test 3"}, format="json", HTTP_AUTHORIZATION=f"JWT {token}", ) response_json = response.json() assert response.status_code == HTTP_200_OK first = ViewFilter.objects.get(pk=filter_1.id) assert first.field_id == field_1.id assert first.type == "equal" assert first.value == "test 3" assert response_json["id"] == first.id assert response_json["view"] == first.view_id assert response_json["field"] == field_1.id assert response_json["type"] == "equal" assert response_json["value"] == "test 3" response = api_client.patch( reverse( "api:database:views:filter_item", kwargs={"view_filter_id": filter_1.id} ), {"value": ""}, format="json", HTTP_AUTHORIZATION=f"JWT {token}", ) response_json = response.json() assert response.status_code == HTTP_200_OK first = ViewFilter.objects.get(pk=filter_1.id) assert first.value == "" assert response_json["value"] == ""
def test_update_view_filter(api_client, data_fixture): user, token = data_fixture.create_user_and_token() filter_1 = data_fixture.create_view_filter(user=user, value='test') filter_2 = data_fixture.create_view_filter() field_1 = data_fixture.create_text_field(table=filter_1.view.table) field_2 = data_fixture.create_text_field() response = api_client.patch( reverse( 'api:database:views:filter_item', kwargs={'view_filter_id': filter_2.id} ), {'value': 'test'}, format='json', HTTP_AUTHORIZATION=f'JWT {token}' ) assert response.status_code == HTTP_400_BAD_REQUEST assert response.json()['error'] == 'ERROR_USER_NOT_IN_GROUP' response = api_client.patch( reverse( 'api:database:views:filter_item', kwargs={'view_filter_id': 9999} ), {'value': 'test'}, format='json', HTTP_AUTHORIZATION=f'JWT {token}' ) assert response.status_code == HTTP_404_NOT_FOUND assert response.json()['error'] == 'ERROR_VIEW_FILTER_DOES_NOT_EXIST' response = api_client.patch( reverse( 'api:database:views:filter_item', kwargs={'view_filter_id': filter_1.id} ), { 'field': 9999999, 'type': 'NOT_EXISTING', }, 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']['field'][0]['code'] == 'does_not_exist' assert response_json['detail']['type'][0]['code'] == 'invalid_choice' response = api_client.patch( reverse( 'api:database:views:filter_item', kwargs={'view_filter_id': filter_1.id} ), {'field': field_2.id}, format='json', HTTP_AUTHORIZATION=f'JWT {token}' ) response_json = response.json() assert response.status_code == HTTP_400_BAD_REQUEST assert response_json['error'] == 'ERROR_FIELD_NOT_IN_TABLE' equal_filter_type = view_filter_type_registry.get('not_equal') allowed = equal_filter_type.compatible_field_types equal_filter_type.compatible_field_types = [] grid_view_type = view_type_registry.get('grid') grid_view_type.can_filter = False response = api_client.patch( reverse( 'api:database:views:filter_item', kwargs={'view_filter_id': filter_1.id} ), {'type': 'not_equal'}, format='json', HTTP_AUTHORIZATION=f'JWT {token}' ) response_json = response.json() assert response.status_code == HTTP_400_BAD_REQUEST assert response_json['error'] == 'ERROR_VIEW_FILTER_TYPE_NOT_ALLOWED_FOR_FIELD' equal_filter_type.compatible_field_types = allowed response = api_client.patch( reverse( 'api:database:views:filter_item', kwargs={'view_filter_id': filter_1.id} ), { 'field': field_1.id, 'type': 'not_equal', 'value': 'test 2' }, format='json', HTTP_AUTHORIZATION=f'JWT {token}' ) response_json = response.json() assert response.status_code == HTTP_200_OK assert ViewFilter.objects.all().count() == 2 first = ViewFilter.objects.get(pk=filter_1.id) assert first.field_id == field_1.id assert first.type == 'not_equal' assert first.value == 'test 2' assert response_json['id'] == first.id assert response_json['view'] == first.view_id assert response_json['field'] == field_1.id assert response_json['type'] == 'not_equal' assert response_json['value'] == 'test 2' response = api_client.patch( reverse( 'api:database:views:filter_item', kwargs={'view_filter_id': filter_1.id} ), {'type': 'equal'}, format='json', HTTP_AUTHORIZATION=f'JWT {token}' ) response_json = response.json() assert response.status_code == HTTP_200_OK first = ViewFilter.objects.get(pk=filter_1.id) assert first.field_id == field_1.id assert first.type == 'equal' assert first.value == 'test 2' assert response_json['id'] == first.id assert response_json['field'] == field_1.id assert response_json['type'] == 'equal' assert response_json['value'] == 'test 2' response = api_client.patch( reverse( 'api:database:views:filter_item', kwargs={'view_filter_id': filter_1.id} ), {'value': 'test 3'}, format='json', HTTP_AUTHORIZATION=f'JWT {token}' ) response_json = response.json() assert response.status_code == HTTP_200_OK first = ViewFilter.objects.get(pk=filter_1.id) assert first.field_id == field_1.id assert first.type == 'equal' assert first.value == 'test 3' assert response_json['id'] == first.id assert response_json['view'] == first.view_id assert response_json['field'] == field_1.id assert response_json['type'] == 'equal' assert response_json['value'] == 'test 3' response = api_client.patch( reverse( 'api:database:views:filter_item', kwargs={'view_filter_id': filter_1.id} ), {'value': ''}, format='json', HTTP_AUTHORIZATION=f'JWT {token}' ) response_json = response.json() assert response.status_code == HTTP_200_OK first = ViewFilter.objects.get(pk=filter_1.id) assert first.value == '' assert response_json['value'] == ''
def test_create_view_filter(api_client, data_fixture): user, token = data_fixture.create_user_and_token() table_1 = data_fixture.create_database_table(user=user) table_2 = data_fixture.create_database_table() field_1 = data_fixture.create_text_field(table=table_1) field_2 = data_fixture.create_text_field(table=table_2) view_1 = data_fixture.create_grid_view(table=table_1) view_2 = data_fixture.create_grid_view(table=table_2) response = api_client.post( reverse('api:database:views:list_filters', kwargs={'view_id': view_2.id}), { 'field': field_2.id, 'type': 'equal', 'value': 'test' }, format='json', HTTP_AUTHORIZATION=f'JWT {token}' ) assert response.status_code == HTTP_400_BAD_REQUEST assert response.json()['error'] == 'ERROR_USER_NOT_IN_GROUP' response = api_client.post( reverse('api:database:views:list_filters', kwargs={'view_id': 99999}), { 'field': field_1.id, 'type': 'equal', 'value': 'test' }, format='json', HTTP_AUTHORIZATION=f'JWT {token}' ) assert response.status_code == HTTP_404_NOT_FOUND assert response.json()['error'] == 'ERROR_VIEW_DOES_NOT_EXIST' response = api_client.post( reverse('api:database:views:list_filters', kwargs={'view_id': view_1.id}), { 'field': 9999999, 'type': 'NOT_EXISTING', 'not_value': 'test' }, 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']['field'][0]['code'] == 'does_not_exist' assert response_json['detail']['type'][0]['code'] == 'invalid_choice' response = api_client.post( reverse('api:database:views:list_filters', kwargs={'view_id': view_1.id}), { 'field': field_2.id, 'type': 'equal', 'value': 'test' }, format='json', HTTP_AUTHORIZATION=f'JWT {token}' ) response_json = response.json() assert response.status_code == HTTP_400_BAD_REQUEST assert response_json['error'] == 'ERROR_FIELD_NOT_IN_TABLE' grid_view_type = view_type_registry.get('grid') grid_view_type.can_filter = False response = api_client.post( reverse('api:database:views:list_filters', kwargs={'view_id': view_1.id}), { 'field': field_1.id, 'type': 'equal', 'value': 'test' }, format='json', HTTP_AUTHORIZATION=f'JWT {token}' ) response_json = response.json() assert response.status_code == HTTP_400_BAD_REQUEST assert response_json['error'] == 'ERROR_VIEW_FILTER_NOT_SUPPORTED' grid_view_type.can_filter = True equal_filter_type = view_filter_type_registry.get('equal') allowed = equal_filter_type.compatible_field_types equal_filter_type.compatible_field_types = [] response = api_client.post( reverse('api:database:views:list_filters', kwargs={'view_id': view_1.id}), { 'field': field_1.id, 'type': 'equal', 'value': 'test' }, format='json', HTTP_AUTHORIZATION=f'JWT {token}' ) response_json = response.json() assert response.status_code == HTTP_400_BAD_REQUEST assert response_json['error'] == 'ERROR_VIEW_FILTER_TYPE_NOT_ALLOWED_FOR_FIELD' equal_filter_type.compatible_field_types = allowed response = api_client.post( reverse('api:database:views:list_filters', kwargs={'view_id': view_1.id}), { 'field': field_1.id, 'type': 'equal', 'value': 'test' }, format='json', HTTP_AUTHORIZATION=f'JWT {token}' ) response_json = response.json() assert response.status_code == HTTP_200_OK assert ViewFilter.objects.all().count() == 1 first = ViewFilter.objects.all().first() assert response_json['id'] == first.id assert response_json['view'] == view_1.id assert response_json['field'] == field_1.id assert response_json['type'] == 'equal' assert response_json['value'] == 'test' response = api_client.post( reverse('api:database:views:list_filters', kwargs={'view_id': view_1.id}), { 'field': field_1.id, 'type': 'equal', 'value': '' }, format='json', HTTP_AUTHORIZATION=f'JWT {token}' ) response_json = response.json() assert response.status_code == HTTP_200_OK assert response_json['value'] == '' response = api_client.post( reverse('api:database:views:list_filters', kwargs={'view_id': view_1.id}), { 'field': field_1.id, 'type': 'equal' }, format='json', HTTP_AUTHORIZATION=f'JWT {token}' ) response_json = response.json() assert response.status_code == HTTP_200_OK assert response_json['value'] == ''