class UpdateMenuItemSchema(Schema): item_id = fields.Integer() item_name = fields.Str() description = fields.Str() price = fields.Decimal()
class ProfitPercentRange(Schema): """攒钱助手收益率 (百分比) 范围.""" min = fields.Decimal(places=2) max = fields.Decimal(places=2)
class CommentSchema(Schema): id = fields.Integer() text = fields.Str() score = fields.Decimal() opportunity_id = fields.Integer() user_id = fields.Integer()
class ExampleSchema(Schema): id = fields.UUID(missing=lambda: str(uuid.uuid4())) name = fields.String() price = fields.Decimal(required=True) quantity = fields.Integer(missing=1)
class ConnectionsConnectSchema(BaseSchema): funds = IntegerToStringField(required=True) initial_channel_target = IntegerToStringField( missing=DEFAULT_INITIAL_CHANNEL_TARGET) joinable_funds_target = fields.Decimal( missing=DEFAULT_JOINABLE_FUNDS_TARGET)
class OrderItemSchema(Schema): item = fields.UUID(required=True, dump_only=True, attribute='item.uuid') quantity = fields.Integer(as_string=False) subtotal = fields.Decimal(required=True, dump_only=True)
class ResultsSchema(Schema): id = fields.Str(required=True) projectId = fields.Int(required=False) publicationDate = fields.Str(required=True) deliveryDate = fields.Str(required=False) title = fields.Str(required=True) closingYear = fields.Int(required=False) operationType = fields.Int(required=True) operationTypeName = fields.Str(required=True) operationTypeAlias = fields.Str(required=True) propertyType = fields.Int(required=True) propertyTypeName = fields.Str(required=True) propertyTypeAlias = fields.Str(required=True) location = fields.Int(required=True) propertySubtype = fields.Int(required=False) propertySubtypeName = fields.Str(required=False) propertySubtypeAlias = fields.Str(required=False) departmentId = fields.Int(required=True) provinceId = fields.Int(required=True) districtId = fields.Int(required=True) urbanizationId = fields.Int(required=False) roadName = fields.Str(required=True) departmentName = fields.Str(required=True) departmentAlias = fields.Str(required=True) departmentGroup = fields.Str(required=True) provinceName = fields.Str(required=True) provinceAlias = fields.Str(required=True) provinceGroup = fields.Str(required=True) districtName = fields.Str(required=True) districtAlias = fields.Str(required=True) districtGroup = fields.Str(required=True) urbanizationAlias = fields.Str(required=False) urbanizationName = fields.Str(required=False) urbanizationGroup = fields.Str(required=False) urbanizationOrBeachName = fields.Str(required=False) urbanizationOrBeachAlias = fields.Str(required=False) urbanizationOrBeachGroup = fields.Str(required=False) latitude = fields.Int(required=True) latitudeStr = fields.Str(required=True) longitude = fields.Int(required=True) longitudeStr = fields.Str(required=True) geo = fields.Str(required=True) geoRpt = fields.List(fields.Str(required=True)) hasImages = fields.Int(required=True) totalImages = fields.Int(required=True) totalVideo = fields.Int(required=True) alias = fields.Str(required=True) services = fields.List(fields.Str(required=True)) additionals = fields.List(fields.Str(required=True)) commonAreas = fields.List(fields.Str(required=True)) landArea = fields.Int(required=False) totalArea = fields.List(fields.Int(required=True)) description = fields.Str(required=True) promotion = fields.Int(required=False) promotionTitle = fields.Str(required=False) constructionStage = fields.Int(required=False) constructionStageName = fields.Str(required=False) founded = fields.List(fields.Int(required=True)) bankName = fields.List(fields.Str(required=True)) publicationType = fields.Int(required=True) typeAdvertiser = fields.Int(required=True) priceCurrency = fields.Int(required=False) priceAmountPen = fields.List(fields.Int(required=True)) priceAmountUsd = fields.List(fields.Int(required=True)) label = fields.Str(required=False) highlight = fields.Int(required=True) storeId = fields.Int(required=False) storeEmail = fields.Str(required=False) businessName = fields.Str(required=False) tradeName = fields.Str(required=False) storeLogo = fields.Str(required=False) storeAlias = fields.Str(required=False) storeType = fields.Str(required=False) typeAnnouncement = fields.Int(required=True) origin = fields.Int(required=True) centricDistrict = fields.Int(required=False) userId = fields.Int(required=True) version = fields.Int(required=True) profileId = fields.Int(required=True) score = fields.Int(required=True) priceAmount = fields.List(fields.Decimal(required=True))
class TradeRequest(BaseSerializer): coinId = fields.Int(required=True, as_string=True) coinAmount = fields.Decimal(required=True, as_string=True)
class GameProfileResponse(BaseSerializer): cash = fields.Decimal(required=True, as_string=True) net_worth = fields.Decimal(required=True, as_string=True)
class TransactionSchema(Schema): id = fields.Integer() amount = fields.Decimal(as_string=True)
class GameCreateRequest(BaseSerializer): activeCoins = fields.List(fields.Dict(), required=True) endsOn = fields.DateTime(required=True) startingCash = fields.Decimal(required=True, as_string=True) title = fields.Str(required=True, validate=title_length_validator)
class ModelSchema(Schema): id = fields.Str(attribute="id") createdAt = fields.Decimal(attribute="created_at", as_string=True) updatedAt = fields.Decimal(attribute="updated_at", as_string=True)
class TransactionCreateSchema(StrictSchema): value = fields.Decimal(required=True) on_date = fields.Date(required=False, allow_none=True)
class TestPostgreSqlJSONB: @pytest.fixture() def mock_self_nested(self, schema): mock_self_nested = MagicMock() mock_self_nested.schema = schema mock_self_nested.name = 'test_schema' mock_self_nested.value = 123 mock_self_nested.operator = '__eq__' mock_self_nested.filter_ = {'name': 'test_schema.name', 'op': 'eq'} mock_self_nested.sort_ = {'field': ''} return mock_self_nested @pytest.fixture() def mock__create_filter(self): with mock.patch.object(PostgreSqlJSONB, '_create_filter') as mocked: yield mocked @pytest.mark.parametrize('field', (fields.Email(), fields.Dict(), fields.Decimal(), fields.Url())) def test_get_property_type__without_schema(self, plugin, field): assert plugin.get_property_type(field) is plugin.mapping_ma_field_to_type[type(field)] def test_get_property_type__with_schema(self, plugin): class FakeType(dict): pass class SomeClass: pass mock_schema = mock.Mock() mock_schema.TYPE_MAPPING = {FakeType: SomeClass} assert plugin.get_property_type(SomeClass(), mock_schema) is FakeType def test_add_mapping_field_to_python_type(self, plugin): class FakeType(dict): pass plugin.add_mapping_field_to_python_type(fields.String, FakeType) assert plugin.mapping_ma_field_to_type[fields.String] is FakeType def test_before_data_layers_sorting_alchemy_nested_resolve(self, plugin, schema): mock_self_nested = Mock() mock_self_nested.sort_ = {'field': f'test_schema{SPLIT_REL}name', 'order': 'asc'} mock_self_nested.name = 'test_schema' mock_self_nested.schema = schema plugin._create_sort = Mock() plugin._create_sort.return_value = True res = plugin.before_data_layers_sorting_alchemy_nested_resolve(mock_self_nested) assert res == (True, [],) def test_before_data_layers_filtering_alchemy_nested_resolve(self, plugin, mock_self_nested, mock__create_filter): mock__create_filter.return_value = 'filter', 'joins' result = plugin.before_data_layers_filtering_alchemy_nested_resolve(mock_self_nested) assert result == mock__create_filter.return_value mock__create_filter.assert_called_once_with( mock_self_nested, marshmallow_field=mock_self_nested.schema._declared_fields[mock_self_nested.name], model_column=mock_self_nested.column, operator=mock_self_nested.filter_['op'], value=mock_self_nested.value ) def test_before_data_layers_filtering_alchemy_nested_resolve__not_splitted_name(self, plugin, mock_self_nested, mock__create_filter): mock_self_nested.filter_['name'] = 'not_splitted_name' result = plugin.before_data_layers_filtering_alchemy_nested_resolve(mock_self_nested) assert result is None mock__create_filter.assert_not_called() @pytest.mark.parametrize('filter_', ('or', 'and', 'not')) def test_before_data_layers_filtering_alchemy_nested_resolve__or_and_not_filters(self, plugin, mock_self_nested, mock__create_filter, filter_): mock_self_nested.filter_[filter_] = '' result = plugin.before_data_layers_filtering_alchemy_nested_resolve(mock_self_nested) assert result is None mock__create_filter.assert_not_called() @pytest.mark.parametrize('filter_name, result', ( pytest.param('test_schema.lvl1', True, id='jsonb field'), pytest.param('string_field', False, id='not jsonb field'), pytest.param('related_schema.jsonb_field.name', True, id='jsonb field of related schema'), pytest.param('related_schema.string_field', False, id='not jsonb field of related schema'), )) def test__isinstance_jsonb(self, schema, filter_name, result): assert PostgreSqlJSONB._isinstance_jsonb(schema, filter_name) is result @pytest.mark.parametrize('filter_name', ( 'test_schema', 'related_schema.jsonb_field' )) def test__isinstance__invalid_filters(self, schema, filter_name): with pytest.raises(InvalidFilters) as e: PostgreSqlJSONB._isinstance_jsonb(schema, filter_name) assert e.value.detail == f'Invalid JSONB filter: {filter_name}' @mock.patch('combojsonapi.postgresql_jsonb.plugin.cast', autospec=True) def test_custom_mapping(self, mock_cast, plugin, schema, custom_field): mock_self_nested = Mock() mock_operator = 'eq' mock_value = 1 mock_self_nested.filter_ = { 'name': f'test_schema{SPLIT_REL}type_test', 'op': mock_operator, 'val': mock_value, } mock_self_nested.schema = schema() mock_self_nested.operator = mock_operator mock_marshmallow_field = schema().fields['test_schema'] mock_model_column = Mock() plugin.add_mapping_field_to_python_type(custom_field, int) mock_cast.eq = Mock(return_value=True) assert True, [] == plugin._create_filter( self_nested=mock_self_nested, marshmallow_field=mock_marshmallow_field, model_column=mock_model_column, operator=mock_operator, value=mock_value ) def test__create_sort(self, plugin, schema): mock_self_nested = Mock() mock_self_nested.sort_ = {'field': f'test_schema{SPLIT_REL}lvl1{SPLIT_REL}name', 'order': 'asc'} mock_self_nested.name = 'test_schema' mock_self_nested.schema = schema mock_marshmallow_field = schema().fields['test_schema'] mock_model_column = Mock() plugin._create_sort( self_nested=mock_self_nested, marshmallow_field=mock_marshmallow_field, model_column=mock_model_column, order='asc') mock_model_column.op("->").assert_called_once() def test__create_sort_with_custom_sort(self, plugin, schema): mock_self_nested = Mock() mock_self_nested.sort_ = {'field': f'test_schema{SPLIT_REL}lvl1{SPLIT_REL}name', 'order': 'desc'} mock_self_nested.name = 'test_schema' mock_self_nested.schema = schema mock_marshmallow_field = schema().fields['test_schema'] mock_model_column = Mock() res = plugin._create_sort( self_nested=mock_self_nested, marshmallow_field=mock_marshmallow_field, model_column=mock_model_column, order='desc') mock_model_column.op("->").assert_called_once() assert res is True def test_create_sort__not_jsonb_field(self, plugin, schema, mock_self_nested): with pytest.raises(InvalidFilters): plugin._create_sort( self_nested=mock_self_nested, marshmallow_field=schema._declared_fields['string_field'], model_column=Mock(), order='desc' ) def test_create_sort__wrong_fields_path(self, plugin, schema, mock_self_nested): mock_self_nested.sort_ = {'field': 'spam.eggs'} with pytest.raises(InvalidFilters): plugin._create_sort( self_nested=mock_self_nested, marshmallow_field=schema._declared_fields['test_schema'], model_column=Mock(), order='desc' ) def test_create_sort__through_related_schema(self, schema, mock_self_nested): mock_self_nested.sort_['field'] = 'related_schema.jsonb_field.name' mock_self = Mock() mock_model_column = Mock() result = PostgreSqlJSONB._create_sort( mock_self, self_nested=mock_self_nested, marshmallow_field=schema._declared_fields['related_schema'], model_column=mock_model_column, order='asc' ) assert result == mock_self._create_sort.return_value # check that func was called recursively mock_self._create_sort.assert_called_once_with( mock_self_nested, schema._declared_fields['related_schema'].schema._declared_fields['jsonb_field'], mock_model_column.mapper.class_.jsonb_field, 'asc' ) def test__create_filter(self, plugin, schema): mock_operator = 'eq' mock_value = 'string' mock_self_nested = Mock() mock_self_nested.filter_ = { 'name': f'test_schema{SPLIT_REL}lvl1{SPLIT_REL}name', 'op': mock_operator, 'val': mock_value, } mock_self_nested.operator = '__eq__' mock_self_nested.name = 'test_schema' mock_self_nested.name = 'test_schema' mock_self_nested.schema = schema mock_marshmallow_field = schema().fields['test_schema'] mock_model_column = Mock() plugin._create_filter( self_nested=mock_self_nested, marshmallow_field=mock_marshmallow_field, model_column=mock_model_column, operator=mock_operator, value=mock_value) mock_model_column.op("->").assert_called_once() def test__create_filter_with_custom_op(self, plugin, schema): mock_operator = 'ilike' mock_value = 'string' mock_self_nested = Mock() mock_self_nested.filter_ = { 'name': f'test_schema{SPLIT_REL}lvl1{SPLIT_REL}list', 'op': mock_operator, 'val': mock_value, } mock_self_nested.operator = '__ilike__' mock_self_nested.name = 'test_schema' mock_self_nested.schema = schema mock_marshmallow_field = schema().fields['test_schema'] mock_model_column = Mock() plugin._create_filter( self_nested=mock_self_nested, marshmallow_field=mock_marshmallow_field, model_column=mock_model_column, operator=mock_operator, value=mock_value) mock_model_column.op("->").assert_called_once() def test_create_filter__not_jsonb_field(self, plugin, schema, mock_self_nested): with pytest.raises(InvalidFilters): plugin._create_filter( self_nested=mock_self_nested, marshmallow_field=schema._declared_fields['string_field'], model_column=Mock(), operator=mock_self_nested.operator, value=mock_self_nested.value ) def test_create_filter__wrong_field_path(self, plugin, schema, mock_self_nested): mock_self_nested.filter_['name'] = 'spam.eggs' with pytest.raises(InvalidFilters): plugin._create_filter( self_nested=mock_self_nested, marshmallow_field=schema._declared_fields['test_schema'], model_column=Mock(), operator=mock_self_nested.operator, value=mock_self_nested.value ) def test_create_filter__through_related_schema(self, schema, mock_self_nested): mock_self_nested.filter_['name'] = 'related_schema.jsonb_field.name' mock_self = Mock() mock_self._create_filter.return_value = 'filter', [] mock_model_column = Mock() result = PostgreSqlJSONB._create_filter( mock_self, self_nested=mock_self_nested, marshmallow_field=schema._declared_fields['related_schema'], model_column=mock_model_column, operator=mock_self_nested.operator, value=mock_self_nested.value ) assert result[0] == mock_self._create_filter.return_value[0] assert result[1] == mock_self._create_filter.return_value[1] + [[mock_model_column]] # check that func was called recursively mock_self._create_filter.assert_called_once_with( mock_self_nested, schema._declared_fields['related_schema'].schema._declared_fields['jsonb_field'], mock_model_column.mapper.class_.jsonb_field, mock_self_nested.operator, mock_self_nested.value )
def decimal_converter(_converter: BaseConverter, _subtypes: Any, opts: Dict[str, Any]) -> fields.Field: """Decimal field factory that always sets as_string.""" return fields.Decimal(as_string=True, **opts)
class GameCoinsResponse(CoinsResponse): number = fields.Decimal(required=True, as_string=True)
class LocationSchema(Schema): id = fields.String() name = fields.String() latitude = fields.Decimal() longitude = fields.Decimal()
class TickerResponse(BaseSerializer): price = fields.Decimal(as_string=True) captured_at = fields.DateTime() price_change_day_pct = fields.Decimal(as_string=True)
class OrderSchema(Schema): uuid = fields.UUID(required=True, dump_only=True) total_price = fields.Decimal(required=True) user = fields.Nested(UserSchema, only=["uuid"]) items = fields.Nested(OrderItemSchema, many=True, attribute='order_items')
class Cash(BaseSerializer): cash = fields.Decimal(required=True, as_string=True)
class LinesSchema(Schema): id = fields.String() name = fields.String() color = fields.Decimal()
class TradeResponse(BaseSerializer): new_amount = fields.Decimal(required=True, as_string=True) new_cash = fields.Decimal(required=True, as_string=True)
class OrderDetailSchema(Schema): id = fields.Int(required=True) product_id = fields.Str(required=True) price = fields.Decimal(as_string=True) quantity = fields.Int()
class PieChartSchema(Schema): name = fields.Str() y = fields.Decimal()
def test_missing_data_are_skipped(self, marshal): assert marshal({}, {'foo': fields.Field()}) == {} assert marshal({}, {'foo': fields.Str()}) == {} assert marshal({}, {'foo': fields.Int()}) == {} assert marshal({}, {'foo': fields.Int(as_string=True)}) == {} assert marshal({}, {'foo': fields.Decimal(as_string=True)}) == {}
class BalanceSchema(Schema): currency = fields.Nested(CurrencySchema) exchange = fields.Nested(ExchangeSchema) total = fields.Decimal() target = fields.Decimal() btc_rate = fields.Decimal()
class QuoteData(Schema): class Meta: ordered = True code = fields.String() name = fields.String() latest_price = fields.Decimal(places=2) average_price = fields.Decimal(places=2) change = fields.Decimal(places=2) change_percent = fields.Decimal(places=2) open = fields.Decimal(places=2) high = fields.Decimal(places=2) low = fields.Decimal(places=2) pre_close = fields.Decimal(places=2) volume_size = fields.Integer() volume_amount = extfields.CnNumberInt() turnover_rate = fields.Decimal(places=2) minute_volume_ratio = fields.Decimal(places=2) bid_ask_ratio = fields.Decimal(places=2) bid_ask_diff = fields.Integer() update_time = fields.DateTime(format='%Y-%m-%d %H:%M:%S')
class AssetSchema(Schema): asset = fields.Str() percent = fields.Decimal()
class PositionSchema(FieldSchema): x = fields.Decimal() y = fields.Decimal() z = fields.Decimal() w = fields.Decimal()
class AddMenuItemSchema(Schema): item_name = fields.Str() description = fields.Str() restaurant_id = fields.Integer() price = fields.Decimal()