Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

schema.org markup fixed, unittest added #1633

Merged
merged 1 commit into from Jan 12, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 6 additions & 5 deletions root/inc/breadcrumbs.html
Expand Up @@ -28,14 +28,16 @@
<% END %>


<div class="breadcrumbs" itemscope itemtype="http://schema.org/SoftwareApplication">
<a data-keyboard-shortcut="g a" rel="author" itemprop="author" itemscope itemtype="http://schema.org/Person" href="/author/<% IF module; module.author; ELSE; release.author; END %>" title="<% author.asciiname %>" class="author-name"><% author.name %></a>
<div class="breadcrumbs">
<span <% IF schema_org %>itemprop="author" itemscope itemtype="http://schema.org/Person"<% END %> >
<a <% IF schema_org %>itemprop="url" <% END %> data-keyboard-shortcut="g a" rel="author" href="/author/<% IF module; module.author; ELSE; release.author; END %>" title="<% author.asciiname %>" class="author-name"><span <% IF schema_org %>itemprop="name"<% END %> ><% author.name %></span></a>
</span>
<span>&nbsp;/&nbsp;</span>
<div class="release status-<% release.status %> maturity-<% release.maturity %><% IF mark_unauthorized_releases && NOT release.authorized %> unauthorized<% END %>">
<span class="dropdown"><b class="caret"></b></span>
<select class="<% module ? "" : "extend" %>" onchange="document.location.href=this.value"><% PROCESS version_dropdown %></select>
<% IF module %>
<a data-keyboard-shortcut="g d" class="release-name" itemprop="name" href="/release/<% IF release.status == 'latest'; release.distribution; ELSE; [module.author, module.release].join('/'); END %>"><% release.name %></a>
<a data-keyboard-shortcut="g d" class="release-name" href="/release/<% IF release.status == 'latest'; release.distribution; ELSE; [module.author, module.release].join('/'); END %>"><% release.name %></a>
<% ELSE %>
<span class="release-name"><% release.name %></span>
<% END %>
Expand All @@ -48,7 +50,6 @@
<%- END; END; %>
<div class="inline"><%- INCLUDE inc/favorite.html module = module || release %></div>
<%- IF module %>
<span>&nbsp;/&nbsp;
<% module.documentation or module.module.0.name %></span>
&nbsp;/&nbsp;<span <% IF schema_org %>itemprop="name"<% END %> ><% module.documentation or module.module.0.name %></span>
<%- END %>
</div>
6 changes: 4 additions & 2 deletions root/inc/rating.html
@@ -1,2 +1,4 @@
<a href="http://cpanratings.perl.org/rate/?distribution=<% distribution %>"><% prefix | none %><span class="rating-<% (rating.mean * 2).fmt('%.0f') / 2 * 10 %>"></span></a>
(<a href="http://cpanratings.perl.org/dist/<% distribution %>"><% rating.count %> review<% IF rating.count > 1; 's'; END %></a>)
<% stars = (rating.mean * 2).fmt('%.0f') / 2 %>
<span <% IF schema_org %>itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating"<% END %> >
<a href="http://cpanratings.perl.org/rate/?distribution=<% distribution %>"><% prefix | none %><span class="rating-<% stars * 10 %>"></a><span class="invisible" <% IF schema_org %>itemprop="ratingValue"<% END %> ><% stars %></span>(<a href="http://cpanratings.perl.org/dist/<% distribution %>"><span <% IF schema_org %>itemprop="reviewCount"<% END %> ><% rating.count %></span> review<% IF rating.count > 1; 's'; END %></a>)
</span>
12 changes: 8 additions & 4 deletions root/inc/release-tools.html
@@ -1,9 +1,13 @@
<li class="nav-header">Tools</li>
<% INCLUDE inc/perlybook.html %>
<li>
<a href="<% release.download_url.replace('cpan\.cpantesters\.org', 'cpan.metacpan.org').replace('^http://', 'https://') %>">
<i class="fa fa-download fa-fw black"></i>Download (<% release.stat.size | format_bytes %>b)
</a>
<a <% IF schema_org %>itemprop="downloadUrl"<% END %> href="<% release.download_url.replace('cpan\.cpantesters\.org', 'cpan.metacpan.org').replace('^http://', 'https://') %>">
<i class="fa fa-download fa-fw black"></i>Download (<span <% IF schema_org %>itemprop="fileSize"<% END %> ><% release.stat.size | format_bytes %>b</span>)</a>
<% IF schema_org %>
<span class="invisible" itemprop="offers" itemscope itemtype="http://schema.org/Offer">
<span itemprop="price">0</span>
</span>
<% END %>
</li>
<li>
<a href="https://explorer.metacpan.org/?url=<% ("/" _ ( module ? ['module', module.author, module.release, module.path].join("/") : ['release', release.author, release.name].join("/") ) ) | uri %>">
Expand Down Expand Up @@ -60,7 +64,7 @@
</li>
<%- IF canonical %>
<li>
<a href="<% canonical %>">Latest version</a>
<a <% IF schema_org %>itemprop="url"<% END %> href="<% canonical %>">Latest version</a>
</li>
<li class="nav-header">S.C.O</li>
<li>
Expand Down
94 changes: 49 additions & 45 deletions root/pod.html
Expand Up @@ -8,51 +8,55 @@
rss = 'distribution/' _ module.distribution
%>

<% INCLUDE inc/breadcrumbs.html %>
<div itemscope itemtype="http://schema.org/SoftwareApplication">
<% INCLUDE inc/breadcrumbs.html schema_org = 1 %>

<ul class="nav-list slidepanel" itemscope itemtype="http://schema.org/SoftwareApplication">
<li class="visible-xs">
<% INCLUDE mobile/toolbar-search-form.html %>
</li>
<li class="nav-header"><span class="relatize"><% module.date.dt_http %></span></li>
<% IF documented_module.version %>
<li>
Module version: <% documented_module.version | html %>
</li>
<% END %>
<li>
<a data-keyboard-shortcut="g s" href="/source/<% module.author %>/<% module.release %>/<% module.path %>"><i class="fa fa-fw fa-file-code-o black"></i>Source</a>
(<a href="<% api_external_secure %>/source/<% module.author %>/<% module.release %>/<% module.path %>">raw</a>)
</li>
<li>
<a data-keyboard-shortcut="g b" href="/source/<% module.author %>/<% module.release %>/<% module.path.split("/").splice(0,-1).join("/") %>"><i class="fa fa-fw fa-folder-open black"></i>Browse</a>
(<a href="<% api_external_secure %>/source/<% module.author %>/<% module.release %>/">raw</a>)
</li>
<% PROCESS inc/release-info.html %>
<li class="nav-header">Activity</li>
<li><% INCLUDE inc/activity.html query = 'distribution=' _ release.distribution %></li>
<% INCLUDE inc/release-tools.html %>
</ul>
<ul class="nav-list slidepanel">
<li class="visible-xs">
<% INCLUDE mobile/toolbar-search-form.html %>
</li>
<li class="nav-header">
<time class="relatize" itemprop="dateModified" datetime="<% module.date.dt_date_common %>"><% module.date.dt_http %></time>
</li>
<% IF documented_module.version %>
<li>
Module version: <span itemprop="softwareVersion"><% documented_module.version | html %></span>
</li>
<% END %>
<li>
<a data-keyboard-shortcut="g s" href="/source/<% module.author %>/<% module.release %>/<% module.path %>"><i class="fa fa-fw fa-file-code-o black"></i>Source</a>
(<a href="<% api_external_secure %>/source/<% module.author %>/<% module.release %>/<% module.path %>">raw</a>)
</li>
<li>
<a data-keyboard-shortcut="g b" href="/source/<% module.author %>/<% module.release %>/<% module.path.split("/").splice(0,-1).join("/") %>"><i class="fa fa-fw fa-folder-open black"></i>Browse</a>
(<a href="<% api_external_secure %>/source/<% module.author %>/<% module.release %>/">raw</a>)
</li>
<% PROCESS inc/release-info.html schema_org = 1 %>
<li class="nav-header">Activity</li>
<li><% INCLUDE inc/activity.html query = 'distribution=' _ release.distribution %></li>
<% INCLUDE inc/release-tools.html schema_org = 1 %>
</ul>

<button id="right-panel-toggle" class="btn-link" onclick="togglePanel('right'); return false;"><span class="panel-hidden">Show</span><span class="panel-visible">Hide</span> Right Panel</button>
<div id="right-panel" class="pull-right">
<div class="box-right">
<% INCLUDE inc/author-pic.html author = author %>
<% INCLUDE inc/contributors.html contributors = contributors %>
</div>
<% INCLUDE inc/dependencies.html dependencies = release.dependency %>
</div>
<a name="___pod"></a>
<div class="pod content anchors">
<% IF pod %>
<% pod | none %>
<% ELSIF pod_error %>
<p class="pod-error">Error rendering POD for <code><% module.name %></code> - <% pod_error %></p>
<% ELSE %>
<p class="pod-error">
No POD found for <code><% module.name %></code>.
Time to <a href="/source/<% module.author %>/<% module.release %>/<% module.path %>">read the source</a>?
</p>
<% END %>
<% INCLUDE inc/module-install.html %>
<button id="right-panel-toggle" class="btn-link" onclick="togglePanel('right'); return false;"><span class="panel-hidden">Show</span><span class="panel-visible">Hide</span> Right Panel</button>
<div id="right-panel" class="pull-right">
<div class="box-right">
<% INCLUDE inc/author-pic.html author = author %>
<% INCLUDE inc/contributors.html contributors = contributors %>
</div>
<% INCLUDE inc/dependencies.html dependencies = release.dependency %>
</div>
<a name="___pod"></a>
<div class="pod content anchors">
<% IF pod %>
<% pod | none %>
<% ELSIF pod_error %>
<p class="pod-error">Error rendering POD for <code><% module.name %></code> - <% pod_error %></p>
<% ELSE %>
<p class="pod-error">
No POD found for <code><% module.name %></code>.
Time to <a href="/source/<% module.author %>/<% module.release %>/<% module.path %>">read the source</a>?
</p>
<% END %>
<% INCLUDE inc/module-install.html %>
</div>
</div>
76 changes: 76 additions & 0 deletions t/schema_org.t
@@ -0,0 +1,76 @@
use strict;
use warnings;
use Test::More;
use MetaCPAN::Web::Test;

sub check_author {
my ($tx) = @_;
$tx->ok( '@itemscope', 'root node needs an itemscope' );
$tx->is( '@itemtype', 'http://schema.org/Person',
'author has correct type' );
$tx->ok( './/a[@itemprop="url"]', 'author\'s URL found' );
$tx->ok( './/span[@itemprop="name"]', 'author\'s name found' );
}

sub check_rating {
my ($tx) = @_;
$tx->ok( '@itemscope', 'root node needs an itemscope' );
$tx->is(
'@itemtype',
'http://schema.org/AggregateRating',
'rating has correct type'
);
$tx->ok( './/span[@itemprop="ratingValue"]', 'rating found' );
$tx->ok( './/span[@itemprop="reviewCount"]', 'review count found' );
}

sub check_offer {
my ($tx) = @_;
$tx->ok( '@itemscope', 'root node needs an itemscope' );
$tx->is( '@itemtype', 'http://schema.org/Offer',
'offer has correct type' );
$tx->is( './/span[@itemprop="price"]', '0', 'price is correct' );
}

sub check_application {
my ($tx) = @_;
$tx->ok( '@itemscope', 'root node needs an itemscope' );
$tx->ok( './/span[@itemprop="name" and text()="DBI"]',
'name found and correct' );
$tx->ok( './/span[@itemprop="softwareVersion"]',
'software version found' );
$tx->ok( './/a[@itemprop="downloadUrl"]', 'download URL found' );
$tx->ok( './/span[@itemprop="fileSize"]', 'file size found' );
$tx->ok( './/a[@itemprop="url"]', 'URL found' );

$tx->ok( './/span[@itemprop="author"]', \&check_author,
'author node found' );
$tx->ok( './/span[@itemprop="aggregateRating"]',
\&check_rating, 'rating found' );
$tx->ok( './/span[@itemprop="offers"]', \&check_offer, 'offers found' );
}

test_psgi app, sub {
my $cb = shift;

ok( my $res = $cb->( GET '/pod/DBI' ), 'GET a pod' );
is( $res->code, 200, 'code 200' );
my $tx = tx($res);
$tx->ok( '//div[@itemtype="http://schema.org/SoftwareApplication"]',
\&check_application, 'found SoftwareApplication' );

ok( $res = $cb->( GET '/release/DBI' ), 'GET a release' );
is( $res->code, 200, 'code 200' );
$tx = tx($res);
$tx->not_ok( '//*[@itemtype or @itemscope or @itemname]',
'no schema.org attributes found' );

ok( $res = $cb->( GET '/search?q=DBI' ), 'GET a search' );
is( $res->code, 200, 'code 200' );
$tx = tx($res);
$tx->not_ok( '//*[@itemtype or @itemscope or @itemname]',
'no schema.org attributes found' );

};

done_testing;