Skip to content

Commit

Permalink
Merge pull request #73 from SBillion/dev
Browse files Browse the repository at this point in the history
Fix compatibility marshmallow>=3.0.0b7
  • Loading branch information
sloria committed Apr 29, 2018
2 parents 7208b90 + 33f0f02 commit 3d4673a
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 41 deletions.
8 changes: 7 additions & 1 deletion flask_marshmallow/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
import flask
import marshmallow as ma

from flask_marshmallow.compat import _MARSHMALLOW_VERSION_INFO

sentinel = object()


class Schema(ma.Schema):
"""Base serializer with which to define custom serializers.
Expand Down Expand Up @@ -32,5 +35,8 @@ def jsonify(self, obj, many=sentinel, *args, **kwargs):
"""
if many is sentinel:
many = self.many
data = self.dump(obj, many=many).data
if _MARSHMALLOW_VERSION_INFO[0] >= 3:
data = self.dump(obj, many=many)
else:
data = self.dump(obj, many=many).data
return flask.jsonify(data, *args, **kwargs)
31 changes: 21 additions & 10 deletions tests/test_core.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
# -*- coding: utf-8 -*-
import json

from flask import Flask, url_for
from werkzeug.wrappers import BaseResponse
from flask_marshmallow import Marshmallow

from flask_marshmallow import Marshmallow
from tests.markers import flask_1_req
from tests.utils import get_dump_data


def test_deferred_initialization():
app = Flask(__name__)
Expand All @@ -13,17 +16,22 @@ def test_deferred_initialization():

assert 'flask-marshmallow' in app.extensions


def test_schema(app, schemas, mockauthor):
s = schemas.AuthorSchema()
result = s.dump(mockauthor)
assert result.data['id'] == mockauthor.id
assert result.data['name'] == mockauthor.name
assert result.data['absolute_url'] == url_for('author',
id=mockauthor.id, _external=True)
links = result.data['links']
result = get_dump_data(s, mockauthor)
assert result['id'] == mockauthor.id
assert result['name'] == mockauthor.name
assert result['absolute_url'] == url_for(
'author',
id=mockauthor.id,
_external=True
)
links = result['links']
assert links['self'] == url_for('author', id=mockauthor.id)
assert links['collection'] == url_for('authors')


def test_jsonify_instance(app, schemas, mockauthor):
s = schemas.AuthorSchema()
resp = s.jsonify(mockauthor)
Expand All @@ -32,6 +40,7 @@ def test_jsonify_instance(app, schemas, mockauthor):
obj = json.loads(resp.get_data(as_text=True))
assert isinstance(obj, dict)


@flask_1_req
def test_jsonify_collection(app, schemas, mockauthorlist):
s = schemas.AuthorSchema()
Expand All @@ -41,6 +50,7 @@ def test_jsonify_collection(app, schemas, mockauthorlist):
obj = json.loads(resp.get_data(as_text=True))
assert isinstance(obj, list)


@flask_1_req
def test_jsonify_collection_via_schema_attr(app, schemas, mockauthorlist):
s = schemas.AuthorSchema(many=True)
Expand All @@ -50,10 +60,11 @@ def test_jsonify_collection_via_schema_attr(app, schemas, mockauthorlist):
obj = json.loads(resp.get_data(as_text=True))
assert isinstance(obj, list)


def test_links_within_nested_object(app, schemas, mockbook):
s = schemas.BookSchema()
result = s.dump(mockbook)
assert result.data['title'] == mockbook.title
author = result.data['author']
result = get_dump_data(s, mockbook)
assert result['title'] == mockbook.title
author = result['author']
assert author['links']['self'] == url_for('author', id=mockbook.author.id)
assert author['links']['collection'] == url_for('authors')
69 changes: 39 additions & 30 deletions tests/test_sqla.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
# -*- coding: utf-8 -*-
import pytest
from flask import Flask, url_for
from flask_marshmallow import Marshmallow
from flask_marshmallow.sqla import HyperlinkRelated
from flask_sqlalchemy import SQLAlchemy
from werkzeug.wrappers import BaseResponse
import pytest

from flask_marshmallow import Marshmallow
from flask_marshmallow.sqla import HyperlinkRelated
from tests.conftest import Bunch
from tests.markers import marshmallow_2_req
from tests.utils import get_dump_data, get_load_data


@marshmallow_2_req
Expand Down Expand Up @@ -99,15 +100,16 @@ class Meta:
db.session.add(book)
db.session.commit()

author_result = author_schema.dump(author)
assert 'id' in author_result.data
assert 'name' in author_result.data
assert author_result.data['name'] == 'Chuck Paluhniuk'
assert author_result.data['books'][0] == book.id
author_result = get_dump_data(author_schema, author)

assert 'id' in author_result
assert 'name' in author_result
assert author_result['name'] == 'Chuck Paluhniuk'
assert author_result['books'][0] == book.id
book_result = get_dump_data(book_schema, book)

book_result = book_schema.dump(book)
assert 'id' in book_result.data
assert book_result.data['author'] == author.id
assert 'id' in book_result
assert book_result['author'] == author.id

resp = author_schema.jsonify(author)
assert isinstance(resp, BaseResponse)
Expand All @@ -116,6 +118,7 @@ def test_hyperlink_related_field(self, extma, models, db, extapp):
class BookSchema(extma.ModelSchema):
class Meta:
model = models.Book

author = extma.HyperlinkRelated('author')

book_schema = BookSchema()
Expand All @@ -126,16 +129,18 @@ class Meta:
db.session.add(book)
db.session.flush()

book_result = book_schema.dump(book)
assert book_result.data['author'] == author.url
book_result = get_dump_data(book_schema, book)

assert book_result['author'] == author.url

deserialized = book_schema.load(book_result.data)
assert deserialized.data.author == author
deserialized, errors = get_load_data(book_schema, book_result)
assert deserialized.author == author

def test_hyperlink_related_field_errors(self, extma, models, db, extapp):
class BookSchema(extma.ModelSchema):
class Meta:
model = models.Book

author = HyperlinkRelated('author')

book_schema = BookSchema()
Expand All @@ -147,21 +152,23 @@ class Meta:
db.session.flush()

# Deserialization fails on bad endpoint
book_result = book_schema.dump(book)
book_result.data['author'] = book.url
deserialized = book_schema.load(book_result.data)
assert 'expected "author"' in deserialized.errors['author'][0]
book_result = get_dump_data(book_schema, book)
book_result['author'] = book.url
deserialized, errors = get_load_data(book_schema, book_result)
print(errors)
assert 'expected "author"' in errors['author'][0]

# Deserialization fails on bad URL key
book_result = book_schema.dump(book)
book_result = get_dump_data(book_schema, book)
book_schema.fields['author'].url_key = 'pk'
deserialized = book_schema.load(book_result.data)
assert 'URL pattern "pk" not found' in deserialized.errors['author'][0]
deserialized, errors = get_load_data(book_schema, book_result)
assert 'URL pattern "pk" not found' in errors['author'][0]

def test_hyperlink_related_field_external(self, extma, models, db, extapp):
class BookSchema(extma.ModelSchema):
class Meta:
model = models.Book

author = HyperlinkRelated('author', external=True)

book_schema = BookSchema()
Expand All @@ -172,16 +179,18 @@ class Meta:
db.session.add(book)
db.session.flush()

book_result = book_schema.dump(book)
assert book_result.data['author'] == author.absolute_url
book_result = get_dump_data(book_schema, book)

assert book_result['author'] == author.absolute_url

deserialized = book_schema.load(book_result.data)
assert deserialized.data.author == author
deserialized, errors = get_load_data(book_schema, book_result)
assert deserialized.author == author

def test_hyperlink_related_field_list(self, extma, models, db, extapp):
class AuthorSchema(extma.ModelSchema):
class Meta:
model = models.Author

books = extma.List(HyperlinkRelated('book'))

author_schema = AuthorSchema()
Expand All @@ -192,8 +201,8 @@ class Meta:
db.session.add(book)
db.session.flush()

author_result = author_schema.dump(author)
assert author_result.data['books'][0] == book.url
author_result = get_dump_data(author_schema, author)
assert author_result['books'][0] == book.url

deserialized = author_schema.load(author_result.data)
assert deserialized.data.books[0] == book
deserialized, errors = get_load_data(author_schema, author_result)
assert deserialized.books[0] == book
20 changes: 20 additions & 0 deletions tests/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from marshmallow import ValidationError

from flask_marshmallow.compat import _MARSHMALLOW_VERSION_INFO


def get_dump_data(schema, obj):
if _MARSHMALLOW_VERSION_INFO[0] >= 3:
return schema.dump(obj)

return schema.dump(obj).data


def get_load_data(schema, obj):
if _MARSHMALLOW_VERSION_INFO[0] >= 3:
try:
return schema.load(obj), None
except ValidationError as err:
return None, err.normalized_messages()

return schema.load(obj).data, schema.load(obj).errors

0 comments on commit 3d4673a

Please sign in to comment.