Skip to content

Commit

Permalink
Add schema.org tests
Browse files Browse the repository at this point in the history
  • Loading branch information
protoroto committed Aug 28, 2023
1 parent e11a495 commit 0ce663b
Show file tree
Hide file tree
Showing 7 changed files with 235 additions and 72 deletions.
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,8 @@
# texinfo_show_urls = 'footnote'

# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
# texinfo_no_detailmenu = False

intersphinx_mapping = {
'django': ('https://django.readthedocs.io/en/latest/', None),
"django": ("https://django.readthedocs.io/en/latest/", None),
}
19 changes: 1 addition & 18 deletions meta/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import contextlib
import warnings
from copy import copy

Expand Down Expand Up @@ -133,14 +132,7 @@ def process_value(item):

if value:
try:
attr = getattr(self, value)
if callable(attr):
try:
return attr(field)
except TypeError:
return attr()
else:
return attr
return process_value(getattr(self, value))
except (AttributeError, TypeError):
return value

Expand Down Expand Up @@ -182,15 +174,6 @@ def schema(self):
schema[field] = self._get_meta_value(field, value)
return schema

@contextlib.contextmanager
def _set_request(self, request):
"""
Context processor that sets the request on the current instance
"""
self._request = request
yield
delattr(self, "_request")

def get_request(self):
"""
Retrieve request from current instance
Expand Down
8 changes: 4 additions & 4 deletions meta/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ def get_domain(self):

def get_protocol(self):
"""
Discover the current website protocol from :ref:`META_SITE_PROTOCOL`
Discover the current website protocol from :ref:`META_SITE_PROTOCOL`
:return: domain URL
:return: http or https depending on :ref:`META_SITE_PROTOCOL`
"""
if not get_setting("SITE_PROTOCOL"):
raise ImproperlyConfigured("META_SITE_PROTOCOL is not set")
Expand Down Expand Up @@ -225,7 +225,7 @@ def schema(self):
* dates as isoformat
* iterables and dicts are processed depth-first to process their items
If no type is set :py:attr:`~meta.views.Meta.gplus_type` is used
If no type is set :py:attr:`~meta.views.Meta.schemaorg_type` is used
:return: dict
"""
Expand Down Expand Up @@ -257,7 +257,7 @@ def process_item(item):
for key, val in self._schema.items():
schema[key] = process_item(val)
if "@type" not in schema:
schema["@type"] = self.gplus_type
schema["@type"] = self.schemaorg_type
# after generating the full schema, we can save it in the local cache for future uses
if isinstance(self._obj, ModelMeta):
visited[self._obj._local_key] = schema
Expand Down
86 changes: 39 additions & 47 deletions tests/example_app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,44 +13,37 @@


class Publisher(ModelMeta, models.Model):
name = models.CharField(_('name'), max_length=255)
name = models.CharField(_("name"), max_length=255)

_schema = {
'@type': 'Organization',
'name': 'name',
'logo': 'static_logo',
"@type": "Organization",
"name": "name",
"logo": "static_logo",
}

class Meta:
verbose_name = _('publisher')
verbose_name_plural = _('publishers')
verbose_name = _("publisher")
verbose_name_plural = _("publishers")

def __str__(self):
return self.name

@property
def static_logo(self):
return Meta(schema={
'@type': 'ImageObject',
'url': self.build_absolute_uri('/some/logo.png')
})
return Meta(schema={"@type": "ImageObject", "url": self.build_absolute_uri("/some/logo.png")})


class Comment(ModelMeta, models.Model):
body = models.CharField(_('comment'), max_length=255)
body = models.CharField(_("comment"), max_length=255)
post = models.ForeignKey(
'example_app.Post', on_delete=models.CASCADE, verbose_name=_('post'), related_name='comments'
"example_app.Post", on_delete=models.CASCADE, verbose_name=_("post"), related_name="comments"
)

_schema = {
'@type': 'Comment',
'parentItem': 'post',
'text': 'body'
}
_schema = {"@type": "Comment", "text": "body"}

class Meta:
verbose_name = _('comment')
verbose_name_plural = _('comments')
verbose_name = _("comment")
verbose_name_plural = _("comments")

def __str__(self):
return self.body[:10]
Expand Down Expand Up @@ -79,10 +72,9 @@ class Post(ModelMeta, models.Model):
text = models.TextField(verbose_name=_("Post text"), blank=True, default="")
image_url = models.CharField(max_length=200, null=True, blank=True)
publisher = models.ForeignKey(
'example_app.Publisher', on_delete=models.CASCADE, verbose_name=_('publisher'), related_name='posts',
null=True
"example_app.Publisher", on_delete=models.CASCADE, verbose_name=_("publisher"), related_name="posts", null=True
)
related_posts = models.ManyToManyField('example_app.Post', verbose_name=_('related posts'), blank=True)
related_posts = models.ManyToManyField("example_app.Post", verbose_name=_("related posts"), blank=True)

_metadata_default = ModelMeta._metadata_default.copy() # purely for testing purposes
_metadata_default["locale"] = "dummy_locale"
Expand All @@ -109,7 +101,7 @@ class Post(ModelMeta, models.Model):
"twitter_site": "@FooBlag",
"twitter_author": "get_author_twitter",
"schemaorg_type": "Article",
"published_time": "date_published",
"published_time": "get_date",
"modified_time": "get_date",
"expiration_time": "get_date",
"url": "get_full_url",
Expand All @@ -121,25 +113,25 @@ class Post(ModelMeta, models.Model):
}

_schema = {
'image': 'get_image_full_url',
'articleBody': 'text',
'articleSection': 'get_categories',
'author': 'get_schema_author',
'copyrightYear': 'copyright_year',
'dateCreated': 'get_date',
'dateModified': 'get_date',
'datePublished': 'date_published',
'expires': 'get_date',
'headline': 'headline',
'keywords': 'get_keywords',
'description': 'get_description',
'name': 'title',
'url': 'get_full_url',
'mainEntityOfPage': 'mainEntityOfPage',
'publisher': 'publisher',
'comment': 'comments',
'commentCount': 'comments_count',
'citation': 'related_posts',
"image": "get_image_full_url",
"articleBody": "text",
"articleSection": "get_categories",
"author": "get_schema_author",
"copyrightYear": "copyright_year",
"dateCreated": "get_date",
"dateModified": "get_date",
"datePublished": "get_date",
"expires": "get_date",
"headline": "headline",
"keywords": "get_keywords",
"description": "get_description",
"name": "title",
"url": "get_full_url",
"mainEntityOfPage": "mainEntityOfPage",
"publisher": "publisher",
"comment": "comments",
"commentCount": "comments_count",
"citation": "related_posts",
}

class Meta:
Expand Down Expand Up @@ -174,7 +166,7 @@ def comments_count(self):
return self.comments.count()

def get_keywords(self):
return self.meta_keywords.strip().split(',')
return self.meta_keywords.strip().split(",")

def get_description(self):
description = self.meta_description
Expand Down Expand Up @@ -225,13 +217,13 @@ def get_false_prop(self):

def get_custom_props(self):
return [("custom1", "custom_name1", "custom_val1"), ("custom2", "custom_name2", "custom_val2")]

def get_categories(self):
return ['category 1', 'category 2']
return ["category 1", "category 2"]

def get_schema_author(self):
author = self.get_author()
return {
'@type': 'Person',
'name': author.get_full_name(),
"@type": "Person",
"name": author.get_full_name(),
}
37 changes: 37 additions & 0 deletions tests/test_meta.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
from copy import copy

from django.contrib.sites.models import Site
Expand All @@ -13,6 +14,7 @@
META_USE_OG_PROPERTIES=False,
META_USE_TWITTER_PROPERTIES=False,
META_USE_SCHEMAORG_PROPERTIES=False,
META_USE_JSON_LD_SCHEMA=False,
)
class MetaObjectTestCase(TestCase):
def test_defaults(self):
Expand Down Expand Up @@ -41,9 +43,11 @@ def test_defaults(self):
self.assertEqual(m.use_twitter, False)
self.assertEqual(m.use_facebook, False)
self.assertEqual(m.use_schemaorg, False)
self.assertEqual(m.use_json_ld, False)
self.assertEqual(m.fb_pages, "")
self.assertEqual(m.og_app_id, "")
self.assertEqual(m.use_title_tag, False)
self.assertEqual(m.schema, {"@type": m.schemaorg_type})

def test_set_keywords(self):
m = Meta(keywords=["foo", "bar"])
Expand Down Expand Up @@ -74,6 +78,11 @@ def test_set_keywords_no_duplicate(self):
self.assertEqual(m.keywords[0], "foo")
self.assertEqual(len(m.keywords), 1)

@override_settings(META_USE_JSON_LD_SCHEMA=True)
def test_use_json_ld(self):
m = Meta()
self.assertEqual(m.use_json_ld, True)

@override_settings(META_FB_APPID="appid", META_FB_PAGES="fbpages")
def test_pages_appid(self):
m = Meta()
Expand Down Expand Up @@ -127,6 +136,18 @@ def test_get_full_url_with_fdqn_original_url(self):
m = Meta(request=request)
self.assertEqual(m.get_full_url("https://example.com/foo/bar"), "https://example.com/foo/bar")

def test_get_protocol_without_site_protocol_will_raise(self):
m = Meta()
with self.assertRaises(ImproperlyConfigured):
m.get_protocol()

def test_get_protocol(self):
m = Meta()
with override_settings(META_SITE_PROTOCOL="http"):
self.assertEqual(m.get_protocol(), "http")
with override_settings(META_SITE_PROTOCOL="https"):
self.assertEqual(m.get_protocol(), "https")

def test_get_full_url_without_protocol_without_schema_will_raise(self):
m = Meta()
with self.assertRaises(ImproperlyConfigured):
Expand Down Expand Up @@ -236,3 +257,19 @@ def test_set_image_with_default_image_url(self):
def test_set_image_with_defaults(self):
m = Meta()
self.assertEqual(m.image, "https://foo.com/static/img/image.gif")

def test_schema_org(self):
m = Meta(schema={"foo": "bar", "list": [{"fuu": "baz", "test": "schema"}]})
self.assertEqual(
m.schema,
{"foo": "bar", "list": [{"fuu": "baz", "test": "schema"}], "@type": m.schemaorg_type},
)

def test_as_json_ld(self):
m = Meta(schema={"foo": "bar", "list": [{"fuu": "baz", "test": "schema"}]})
data = m.schema
data["@context"] = "http://schema.org"
self.assertEqual(
m.as_json_ld(),
json.dumps(data),
)
5 changes: 5 additions & 0 deletions tests/test_metadata_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
META_USE_OG_PROPERTIES=False,
META_USE_TWITTER_PROPERTIES=False,
META_USE_SCHEMAORG_PROPERTIES=False,
META_USE_JSON_LD_SCHEMA=False,
)
class MetadataMixinTestCase(TestCase):
def test_get_meta_class(self):
Expand Down Expand Up @@ -200,6 +201,10 @@ def test_get_meta_twitter_type(self):
self.assertEqual(m.get_meta_twitter_type(), "summary")
assert len(w) == 0

def test_no_schema_org(self):
m = MetadataMixin()
self.assertEqual(m.schema, {})

def test_get_meta_facebook_app_id(self):
m = MetadataMixin()
self.assertEqual(m.get_meta_facebook_app_id(), None)
Expand Down
Loading

0 comments on commit 0ce663b

Please sign in to comment.