6840 : meta tags update (#6998)
* Adds a new metadata helper and methods to PostPresenter to have metas on post pages. * Adds tests to post controller to check correctness of metas * Add methods to PersonPresenter to have metas on profile pages * Correct meta data helper test * Update PersonPresenter, add test to PeopleController * Creates TagPresenter. Display tag metas on tag index page * Updata meta data helper spec * Not displaying bio as the description meta on profile page for now. Privacy concerns to be cleared. * Set meta info as hashes in presenters * Move original hardcoded metas info to config/defaults.yml * metas_tags include by default the general metas, update views * Update code style, clean views * Renames TagPresenter StreamTagPresenter, updates TagController spec * Add a default_metas entry to diaspora.yml.example * Align metas hash in presenters, refactor meta data helper * Use bio as description meta if user has a public profile * Rename StreamTagPresenter to TagStreamPresenter
This commit is contained in:
parent
96489e3ce0
commit
bcace2def2
23 changed files with 371 additions and 142 deletions
|
|
@ -69,27 +69,26 @@ class PeopleController < ApplicationController
|
|||
# renders the persons user profile page
|
||||
def show
|
||||
mark_corresponding_notifications_read if user_signed_in?
|
||||
|
||||
@person_json = PersonPresenter.new(@person, current_user).as_json
|
||||
@presenter = PersonPresenter.new(@person, current_user)
|
||||
|
||||
respond_to do |format|
|
||||
format.all do
|
||||
if user_signed_in?
|
||||
@contact = current_user.contact_for(@person)
|
||||
end
|
||||
gon.preloads[:person] = @person_json
|
||||
gon.preloads[:person] = @presenter.as_json
|
||||
gon.preloads[:photos_count] = Photo.visible(current_user, @person).count(:all)
|
||||
gon.preloads[:contacts_count] = Contact.contact_contacts_for(current_user, @person).count(:all)
|
||||
respond_with @person, layout: "with_header"
|
||||
respond_with @presenter, layout: "with_header"
|
||||
end
|
||||
|
||||
format.mobile do
|
||||
@post_type = :all
|
||||
person_stream
|
||||
respond_with @person
|
||||
respond_with @presenter
|
||||
end
|
||||
|
||||
format.json { render json: @person_json }
|
||||
format.json { render json: @presenter.as_json }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -20,13 +20,14 @@ class PhotosController < ApplicationController
|
|||
@post_type = :photos
|
||||
@person = Person.find_by_guid(params[:person_id])
|
||||
authenticate_user! if @person.try(:remote?) && !user_signed_in?
|
||||
@presenter = PersonPresenter.new(@person, current_user)
|
||||
|
||||
if @person
|
||||
@contact = current_user.contact_for(@person) if user_signed_in?
|
||||
@posts = Photo.visible(current_user, @person, :all, max_time)
|
||||
respond_to do |format|
|
||||
format.all do
|
||||
gon.preloads[:person] = PersonPresenter.new(@person, current_user).as_json
|
||||
gon.preloads[:person] = @presenter.as_json
|
||||
gon.preloads[:photos_count] = Photo.visible(current_user, @person).count(:all)
|
||||
gon.preloads[:contacts_count] = Contact.contact_contacts_for(current_user, @person).count(:all)
|
||||
render "people/show", layout: "with_header"
|
||||
|
|
|
|||
|
|
@ -19,14 +19,15 @@ class PostsController < ApplicationController
|
|||
def show
|
||||
post = post_service.find!(params[:id])
|
||||
post_service.mark_user_notifications(post.id)
|
||||
presenter = PostPresenter.new(post, current_user)
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
gon.post = PostPresenter.new(post, current_user)
|
||||
render locals: {post: post}
|
||||
}
|
||||
format.html do
|
||||
gon.post = presenter
|
||||
render locals: {post: presenter}
|
||||
end
|
||||
format.mobile { render locals: {post: post} }
|
||||
format.xml { render xml: DiasporaFederation::Salmon::XmlPayload.pack(Diaspora::Federation::Entities.post(post)) }
|
||||
format.json { render json: PostPresenter.new(post, current_user) }
|
||||
format.json { render json: presenter }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -37,9 +37,15 @@ class TagsController < ApplicationController
|
|||
if user_signed_in?
|
||||
gon.preloads[:tagFollowings] = tags
|
||||
end
|
||||
@stream = Stream::Tag.new(current_user, params[:name], :max_time => max_time, :page => params[:page])
|
||||
stream = Stream::Tag.new(current_user, params[:name], max_time: max_time, page: params[:page])
|
||||
@stream = TagStreamPresenter.new(stream)
|
||||
respond_with do |format|
|
||||
format.json { render :json => @stream.stream_posts.map { |p| LastThreeCommentsDecorator.new(PostPresenter.new(p, current_user)) }}
|
||||
format.json do
|
||||
posts = stream.stream_posts.map do |p|
|
||||
LastThreeCommentsDecorator.new(PostPresenter.new(p, current_user))
|
||||
end
|
||||
render json: posts
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
53
app/helpers/meta_data_helper.rb
Normal file
53
app/helpers/meta_data_helper.rb
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
module MetaDataHelper
|
||||
include ActionView::Helpers::AssetUrlHelper
|
||||
include ActionView::Helpers::TagHelper
|
||||
|
||||
def og_prefix
|
||||
'og: http://ogp.me/ns# article: http://ogp.me/ns/article# profile: http://ogp.me/ns/profile#'
|
||||
end
|
||||
|
||||
def site_url
|
||||
AppConfig.environment.url
|
||||
end
|
||||
|
||||
def default_image_url
|
||||
asset_url "assets/branding/logos/asterisk.png"
|
||||
end
|
||||
|
||||
def default_author_name
|
||||
AppConfig.settings.pod_name
|
||||
end
|
||||
|
||||
def default_description
|
||||
AppConfig.settings.default_metas.description
|
||||
end
|
||||
|
||||
def default_title
|
||||
AppConfig.settings.default_metas.title
|
||||
end
|
||||
|
||||
def general_metas
|
||||
{
|
||||
description: {name: "description", content: default_description},
|
||||
og_description: {property: "description", content: default_description},
|
||||
og_site_name: {property: "og:site_name", content: default_title},
|
||||
og_url: {property: "og:url", content: site_url},
|
||||
og_image: {property: "og:image", content: default_image_url},
|
||||
og_type: {property: "og:type", content: "website"}
|
||||
}
|
||||
end
|
||||
|
||||
def metas_tags(attributes_list={}, with_general_metas=true)
|
||||
attributes_list = general_metas.merge(attributes_list) if with_general_metas
|
||||
attributes_list.map {|_, attributes| meta_tag attributes }.join("\n").html_safe
|
||||
end
|
||||
|
||||
# recursively calls itself if attribute[:content] is an array
|
||||
# (metas such as og:image or og:tag can be present multiple times with different values)
|
||||
def meta_tag(attributes)
|
||||
return "" if attributes.empty?
|
||||
return tag(:meta, attributes) unless attributes[:content].respond_to?(:to_ary)
|
||||
items = attributes.delete(:content)
|
||||
items.map {|item| meta_tag(attributes.merge(content: item)) }.join("\n")
|
||||
end
|
||||
end
|
||||
|
|
@ -1,79 +1,4 @@
|
|||
module OpenGraphHelper
|
||||
def og_title(title)
|
||||
meta_tag_with_property('og:title', title)
|
||||
end
|
||||
|
||||
def og_type(post)
|
||||
meta_tag_with_property('og:type', 'article')
|
||||
end
|
||||
|
||||
def og_url(url)
|
||||
meta_tag_with_property('og:url', url)
|
||||
end
|
||||
|
||||
def og_image(post=nil)
|
||||
tags = []
|
||||
tags = post.photos.map{|x| meta_tag_with_property('og:image', x.url(:thumb_large))} if post
|
||||
tags << meta_tag_with_property('og:image', default_image_url) if tags.empty?
|
||||
tags.join(' ')
|
||||
end
|
||||
|
||||
def og_description(description)
|
||||
meta_tag_with_property('og:description', description)
|
||||
end
|
||||
|
||||
def og_type(type='website')
|
||||
meta_tag_with_property('og:type', type)
|
||||
end
|
||||
|
||||
def og_namespace
|
||||
AppConfig.services.facebook.open_graph_namespace
|
||||
end
|
||||
|
||||
def og_site_name
|
||||
meta_tag_with_property('og:site_name', AppConfig.settings.pod_name)
|
||||
end
|
||||
|
||||
def og_common_tags
|
||||
[og_site_name]
|
||||
end
|
||||
|
||||
def og_general_tags
|
||||
[
|
||||
*og_common_tags,
|
||||
og_type,
|
||||
og_title('diaspora* social network'),
|
||||
og_image,
|
||||
og_url(AppConfig.environment.url),
|
||||
og_description('diaspora* is the online social world where you are in control.')
|
||||
].join("\n").html_safe
|
||||
end
|
||||
|
||||
def og_page_post_tags(post)
|
||||
tags = og_common_tags
|
||||
|
||||
if post.message
|
||||
tags.concat [
|
||||
*tags,
|
||||
og_type("#{og_namespace}:frame"),
|
||||
og_title(post_page_title(post, :length => 140)),
|
||||
og_url(post_url(post)),
|
||||
og_image(post),
|
||||
og_description(post.message.plain_text_without_markdown truncate: 1000)
|
||||
]
|
||||
end
|
||||
|
||||
tags.join("\n").html_safe
|
||||
end
|
||||
|
||||
def og_prefix
|
||||
"og: http://ogp.me/ns# #{og_namespace}: https://diasporafoundation.org/ns/joindiaspora#"
|
||||
end
|
||||
|
||||
def meta_tag_with_property(name, content)
|
||||
tag(:meta, :property => name, :content => content)
|
||||
end
|
||||
|
||||
def og_html(cache)
|
||||
"<a href=\"#{cache.url}\" target=\"_blank\">" +
|
||||
" <div>" +
|
||||
|
|
@ -91,14 +16,4 @@ module OpenGraphHelper
|
|||
def oembed_image_tag(cache, prefix)
|
||||
image_tag(cache.data["#{prefix}url"], cache.options_hash(prefix))
|
||||
end
|
||||
private
|
||||
|
||||
# This method compensates for hosting assets off of s3
|
||||
def default_image_url
|
||||
if image_path("branding/logos/asterisk.png").include?("http")
|
||||
image_path("branding/logos/asterisk.png")
|
||||
else
|
||||
"#{root_url.chop}#{image_path('branding/logos/asterisk.png')}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
class BasePresenter
|
||||
attr_reader :current_user
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
class << self
|
||||
def new(*args)
|
||||
|
|
@ -26,4 +27,10 @@ class BasePresenter
|
|||
nil
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def default_url_options
|
||||
{host: AppConfig.pod_uri.host, port: AppConfig.pod_uri.port}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -25,6 +25,21 @@ class PersonPresenter < BasePresenter
|
|||
base_hash_with_contact.merge(profile: ProfilePresenter.new(profile).for_hovercard)
|
||||
end
|
||||
|
||||
def metas_attributes
|
||||
{
|
||||
keywords: {name: "keywords", content: comma_separated_tags},
|
||||
description: {name: "description", content: description},
|
||||
og_title: {property: "og:title", content: title},
|
||||
og_description: {property: "og:title", content: description},
|
||||
og_url: {property: "og:url", content: url},
|
||||
og_image: {property: "og:image", content: image_url},
|
||||
og_type: {property: "og:type", content: "profile"},
|
||||
og_profile_username: {property: "og:profile:username", content: name},
|
||||
og_profile_firstname: {property: "og:profile:first_name", content: first_name},
|
||||
og_profile_lastname: {property: "og:profile:last_name", content: last_name}
|
||||
}
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def own_profile?
|
||||
|
|
@ -88,4 +103,25 @@ class PersonPresenter < BasePresenter
|
|||
def is_blocked?
|
||||
current_user_person_block.present?
|
||||
end
|
||||
|
||||
def title
|
||||
name
|
||||
end
|
||||
|
||||
def comma_separated_tags
|
||||
profile.tags.map(&:name).join(", ") if profile.tags
|
||||
end
|
||||
|
||||
def url
|
||||
url_for(@presentable)
|
||||
end
|
||||
|
||||
def description
|
||||
public_details? ? bio : ""
|
||||
end
|
||||
|
||||
def image_url
|
||||
return AppConfig.url_to @presentable.image_url if @presentable.image_url[0] == "/"
|
||||
@presentable.image_url
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,15 +1,36 @@
|
|||
class PostPresenter < BasePresenter
|
||||
include PostsHelper
|
||||
include MetaDataHelper
|
||||
|
||||
attr_accessor :post
|
||||
|
||||
def initialize(post, current_user=nil)
|
||||
@post = post
|
||||
@current_user = current_user
|
||||
def initialize(presentable, current_user=nil)
|
||||
@post = presentable
|
||||
super
|
||||
end
|
||||
|
||||
def as_json(_options={})
|
||||
@post.as_json(only: directly_retrieved_attributes).merge(non_directly_retrieved_attributes)
|
||||
@post.as_json(only: directly_retrieved_attributes)
|
||||
.merge(non_directly_retrieved_attributes)
|
||||
end
|
||||
|
||||
def metas_attributes
|
||||
{
|
||||
keywords: {name: "keywords", content: comma_separated_tags},
|
||||
description: {name: "description", content: description},
|
||||
og_url: {property: "og:url", content: url},
|
||||
og_title: {property: "og:title", content: title},
|
||||
og_image: {property: "og:image", content: images},
|
||||
og_description: {property: "og:description", content: description},
|
||||
og_article_tag: {property: "og:article:tag", content: tags},
|
||||
og_article_author: {property: "og:article:author", content: author_name},
|
||||
og_article_modified: {property: "og:article:modified_time", content: modified_time_iso8601},
|
||||
og_article_published: {property: "og:article:published_time", content: published_time_iso8601}
|
||||
}
|
||||
end
|
||||
|
||||
def page_title
|
||||
post_page_title @post
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -38,6 +59,10 @@ class PostPresenter < BasePresenter
|
|||
}
|
||||
end
|
||||
|
||||
def title
|
||||
@post.message.present? ? @post.message.title : I18n.t("posts.presenter.title", name: @post.author_name)
|
||||
end
|
||||
|
||||
def build_text
|
||||
if @post.message
|
||||
@post.message.plain_text_for_json
|
||||
|
|
@ -58,10 +83,6 @@ class PostPresenter < BasePresenter
|
|||
@post.photos.map {|p| p.as_api_response(:backbone) }
|
||||
end
|
||||
|
||||
def title
|
||||
@post.message.present? ? @post.message.title : I18n.t("posts.presenter.title", name: @post.author_name)
|
||||
end
|
||||
|
||||
def root
|
||||
if @post.respond_to?(:absolute_root) && @post.absolute_root.present?
|
||||
PostPresenter.new(@post.absolute_root, current_user).as_json
|
||||
|
|
@ -103,4 +124,34 @@ class PostPresenter < BasePresenter
|
|||
def person
|
||||
current_user.person
|
||||
end
|
||||
|
||||
def images
|
||||
photos.any? ? photos.map(&:url) : default_image_url
|
||||
end
|
||||
|
||||
def published_time_iso8601
|
||||
created_at.to_time.iso8601
|
||||
end
|
||||
|
||||
def modified_time_iso8601
|
||||
updated_at.to_time.iso8601
|
||||
end
|
||||
|
||||
def tags
|
||||
tags = @post.is_a?(Reshare) ? @post.root.tags : @post.tags
|
||||
return tags.map(&:name) if tags
|
||||
[]
|
||||
end
|
||||
|
||||
def comma_separated_tags
|
||||
tags.join(", ")
|
||||
end
|
||||
|
||||
def url
|
||||
post_url @post
|
||||
end
|
||||
|
||||
def description
|
||||
message.plain_text_without_markdown(truncate: 1000)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
25
app/presenters/tag_stream_presenter.rb
Normal file
25
app/presenters/tag_stream_presenter.rb
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
class TagStreamPresenter < BasePresenter
|
||||
def title
|
||||
@presentable.display_tag_name
|
||||
end
|
||||
|
||||
def metas_attributes
|
||||
{
|
||||
keywords: {name: "keywords", content: tag_name},
|
||||
description: {name: "description", content: description},
|
||||
og_url: {property: "og:url", content: url},
|
||||
og_title: {property: "og:title", content: title},
|
||||
og_description: {property: "og:description", content: description}
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def description
|
||||
I18n.t("streams.tags.title", tags: tag_name)
|
||||
end
|
||||
|
||||
def url
|
||||
tag_url tag_name
|
||||
end
|
||||
end
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
- if @post.present?
|
||||
%link{:rel => 'alternate', :type => "application/json+oembed", :href => "#{oembed_url(:url => post_url(@post))}"}
|
||||
= og_page_post_tags(@post)
|
||||
- else
|
||||
= og_general_tags
|
||||
|
|
@ -4,20 +4,17 @@
|
|||
|
||||
!!!
|
||||
%html{lang: I18n.locale.to_s, dir: (rtl?) ? 'rtl' : 'ltr'}
|
||||
%head{prefix: og_prefix}
|
||||
%head{prefix: og_prefix}
|
||||
%title
|
||||
= page_title yield(:page_title)
|
||||
|
||||
%meta{charset: 'utf-8'}/
|
||||
%meta{"http-equiv" => "Content-Type", :content=>"text/html; charset=utf-8"}/
|
||||
%meta{name: "description", content: "diaspora*"}/
|
||||
%meta{name: "author", content: "diaspora* contributors"}/
|
||||
%meta{name: "viewport", content: "width=device-width, initial-scale=1"}/
|
||||
= content_for?(:meta_data) ? yield(:meta_data) : metas_tags
|
||||
|
||||
%link{rel: 'shortcut icon', href: "#{image_path('favicon.png')}" }
|
||||
|
||||
= render 'layouts/open_graph'
|
||||
|
||||
= chartbeat_head_block
|
||||
= include_mixpanel
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
!!!
|
||||
%html{:lang => I18n.locale.to_s, :dir => (rtl?) ? 'rtl' : 'ltr'}
|
||||
%head{:prefix => og_prefix}
|
||||
%head
|
||||
%title
|
||||
= pod_name
|
||||
|
||||
|
|
@ -30,8 +30,7 @@
|
|||
/ NOTE(we will enable these once we don't have to rely on back/forward buttons anymore)
|
||||
/%meta{:name => "apple-mobile-web-app-capable", :content => "yes"}
|
||||
/%link{:rel => "apple-touch-startup-image", :href => "/images/apple-splash.png"}
|
||||
|
||||
= render 'layouts/open_graph'
|
||||
= yield :meta_data
|
||||
|
||||
= chartbeat_head_block
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,10 @@
|
|||
-# the COPYRIGHT file.
|
||||
|
||||
- content_for :page_title do
|
||||
= @person.name
|
||||
= @presenter.name
|
||||
|
||||
- content_for :meta_data do
|
||||
= metas_tags @presenter.metas_attributes
|
||||
|
||||
.container-fluid#profile_container
|
||||
.row
|
||||
|
|
|
|||
|
|
@ -3,7 +3,10 @@
|
|||
-# the COPYRIGHT file.
|
||||
|
||||
- content_for :page_title do
|
||||
= post_page_title post
|
||||
= post.page_title
|
||||
|
||||
- content_for :meta_data do
|
||||
= metas_tags post.metas_attributes
|
||||
|
||||
- content_for :content do
|
||||
#container.container-fluid
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@
|
|||
- content_for :page_title do
|
||||
= @stream.display_tag_name
|
||||
|
||||
- content_for :meta_data do
|
||||
= metas_tags @stream.metas_attributes
|
||||
|
||||
.container-fluid#tags_show
|
||||
.row
|
||||
.col-md-3.hidden-xs
|
||||
|
|
|
|||
|
|
@ -144,6 +144,9 @@ defaults:
|
|||
limit_removals_to_per_day: 100
|
||||
source_url:
|
||||
default_color_theme: "original"
|
||||
default_metas:
|
||||
title: 'diaspora* social network'
|
||||
description: 'diaspora* is the online social world where you are in control.'
|
||||
services:
|
||||
facebook:
|
||||
enable: false
|
||||
|
|
|
|||
|
|
@ -539,6 +539,15 @@ configuration: ## Section
|
|||
## ("original" for the theme in "app/assets/stylesheets/color_themes/original/", for
|
||||
## example).
|
||||
#default_color_theme: "original"
|
||||
|
||||
## Default meta tags
|
||||
## You can change here the default meta tags content included on the pages of your pod.
|
||||
## Title will be used for the opengraph og:site_name property while description will be used
|
||||
## for description and og:description.
|
||||
default_metas:
|
||||
#title: 'diaspora* social network'
|
||||
#description: 'diaspora* is the online social world where you are in control.'
|
||||
|
||||
## Posting from Diaspora to external services (all are disabled by default).
|
||||
services: ## Section
|
||||
|
||||
|
|
|
|||
|
|
@ -146,6 +146,11 @@ describe PeopleController, :type => :controller do
|
|||
end
|
||||
|
||||
describe '#show' do
|
||||
before do
|
||||
@person = FactoryGirl.create(:user).person
|
||||
@presenter = PersonPresenter.new(@person, @user)
|
||||
end
|
||||
|
||||
it "404s if the id is invalid" do
|
||||
get :show, :id => 'delicious'
|
||||
expect(response.code).to eq("404")
|
||||
|
|
@ -161,9 +166,15 @@ describe PeopleController, :type => :controller do
|
|||
expect(response.code).to eq("404")
|
||||
end
|
||||
|
||||
it "returns a person presenter" do
|
||||
expect(PersonPresenter).to receive(:new).with(@person, @user).and_return(@presenter)
|
||||
get :show, username: @person.username
|
||||
expect(assigns(:presenter).to_json).to eq(@presenter.to_json)
|
||||
end
|
||||
|
||||
it 'finds a person via username' do
|
||||
get :show, username: @user.username
|
||||
expect(assigns(:person)).to eq(@user.person)
|
||||
get :show, username: @person.username
|
||||
expect(assigns(:presenter).to_json).to eq(@presenter.to_json)
|
||||
end
|
||||
|
||||
it "404s if no person is found via diaspora handle" do
|
||||
|
|
@ -172,8 +183,8 @@ describe PeopleController, :type => :controller do
|
|||
end
|
||||
|
||||
it 'finds a person via diaspora handle' do
|
||||
get :show, username: @user.diaspora_handle
|
||||
expect(assigns(:person)).to eq(@user.person)
|
||||
get :show, username: @person.diaspora_handle
|
||||
expect(assigns(:presenter).to_json).to eq(@presenter.to_json)
|
||||
end
|
||||
|
||||
it 'redirects home for closed account' do
|
||||
|
|
@ -216,8 +227,8 @@ describe PeopleController, :type => :controller do
|
|||
end
|
||||
|
||||
it "assigns the right person" do
|
||||
get :show, :id => @user.person.to_param
|
||||
expect(assigns(:person)).to eq(@user.person)
|
||||
get :show, id: @person.to_param
|
||||
expect(assigns(:presenter).id).to eq(@presenter.id)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -249,6 +260,27 @@ describe PeopleController, :type => :controller do
|
|||
get :show, id: @person.to_param
|
||||
expect(response.body).not_to include(@person.profile.bio)
|
||||
end
|
||||
|
||||
it "includes the correct meta tags" do
|
||||
presenter = PersonPresenter.new(@person)
|
||||
methods_properties = {
|
||||
comma_separated_tags: {html_attribute: "name", name: "keywords"},
|
||||
url: {html_attribute: "property", name: "og:url"},
|
||||
title: {html_attribute: "property", name: "og:title"},
|
||||
image_url: {html_attribute: "property", name: "og:image"},
|
||||
first_name: {html_attribute: "property", name: "og:profile:first_name"},
|
||||
last_name: {html_attribute: "property", name: "og:profile:last_name"}
|
||||
}
|
||||
|
||||
get :show, id: @person.to_param
|
||||
|
||||
methods_properties.each do |method, property|
|
||||
value = presenter.send(method)
|
||||
expect(response.body).to include(
|
||||
"<meta #{property[:html_attribute]}=\"#{property[:name]}\" content=\"#{value}\" />"
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when the person is a contact of the current user" do
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ describe PostsController, type: :controller do
|
|||
context "user not signed in" do
|
||||
context "given a public post" do
|
||||
let(:public) { alice.post(:status_message, text: "hello", public: true) }
|
||||
let(:public_with_tags) { alice.post(:status_message, text: "#hi #howareyou", public: true) }
|
||||
|
||||
it "shows a public post" do
|
||||
get :show, id: public.id
|
||||
|
|
@ -81,6 +82,35 @@ describe PostsController, type: :controller do
|
|||
expected_xml = DiasporaFederation::Salmon::XmlPayload.pack(Diaspora::Federation::Entities.post(public)).to_xml
|
||||
expect(response.body).to eq(expected_xml)
|
||||
end
|
||||
|
||||
it "includes the correct uniques meta tags" do
|
||||
presenter = PostPresenter.new(public)
|
||||
methods_properties = {
|
||||
comma_separated_tags: {html_attribute: "name", name: "keywords"},
|
||||
description: {html_attribute: "name", name: "description"},
|
||||
url: {html_attribute: "property", name: "og:url"},
|
||||
title: {html_attribute: "property", name: "og:title"},
|
||||
published_time_iso8601: {html_attribute: "property", name: "og:article:published_time"},
|
||||
modified_time_iso8601: {html_attribute: "property", name: "og:article:modified_time"},
|
||||
author_name: {html_attribute: "property", name: "og:article:author"}
|
||||
}
|
||||
|
||||
get :show, id: public.id, format: :html
|
||||
|
||||
methods_properties.each do |method, property|
|
||||
value = presenter.send(method)
|
||||
expect(response.body).to include(
|
||||
"<meta #{property[:html_attribute]}=\"#{property[:name]}\" content=\"#{value}\" />"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
it "includes the correct multiple meta tags" do
|
||||
get :show, id: public_with_tags.id, format: :html
|
||||
|
||||
expect(response.body).to include('<meta property="og:article:tag" content="hi" />')
|
||||
expect(response.body).to include('<meta property="og:article:tag" content="howareyou" />')
|
||||
end
|
||||
end
|
||||
|
||||
context "given a limited post" do
|
||||
|
|
|
|||
|
|
@ -120,6 +120,26 @@ describe TagsController, :type => :controller do
|
|||
expect(JSON.parse(response.body).first["guid"]).to eq(post2.guid)
|
||||
end
|
||||
end
|
||||
|
||||
it "includes the correct meta tags" do
|
||||
tag_url = tag_url "yes", host: AppConfig.pod_uri.host, port: AppConfig.pod_uri.port
|
||||
|
||||
get :show, name: "yes"
|
||||
|
||||
expect(response.body).to include('<meta name="keywords" content="yes" />')
|
||||
expect(response.body).to include(
|
||||
%(<meta property="og:url" content="#{tag_url}" />)
|
||||
)
|
||||
expect(response.body).to include(
|
||||
'<meta property="og:title" content="#yes" />'
|
||||
)
|
||||
expect(response.body).to include(
|
||||
%(<meta name="description" content="#{I18n.t('streams.tags.title', tags: 'yes')}" />)
|
||||
)
|
||||
expect(response.body).to include(
|
||||
%(<meta property="og:description" content=\"#{I18n.t('streams.tags.title', tags: 'yes')}" />)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
55
spec/helpers/meta_data_helper_spec.rb
Normal file
55
spec/helpers/meta_data_helper_spec.rb
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
require "spec_helper"
|
||||
|
||||
describe MetaDataHelper, type: :helper do
|
||||
describe "#meta_tag" do
|
||||
it "returns an empty string if passed an empty hash" do
|
||||
expect(meta_tag({})).to eq("")
|
||||
end
|
||||
|
||||
it "returns a meta tag with the passed attributes" do
|
||||
attributes = {name: "test", content: "foo"}
|
||||
expect(meta_tag(attributes)).to eq('<meta name="test" content="foo" />')
|
||||
end
|
||||
|
||||
it "returns a list of the same meta type if the value for :content in the passed attribute is an array" do
|
||||
attributes = {property: "og:tag", content: %w(tag_1 tag_2)}
|
||||
expect(meta_tag(attributes)).to eq(
|
||||
%(<meta property="og:tag" content="tag_1" />\n) +
|
||||
%(<meta property="og:tag" content="tag_2" />)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#metas_tags' do
|
||||
before do
|
||||
@attributes = {
|
||||
description: {name: "description", content: "i am a test"},
|
||||
og_website: {property: "og:website", content: "http://www.test2.com"}
|
||||
}
|
||||
default_attributes = {
|
||||
description: {name: "description", content: "default description"},
|
||||
og_url: {property: "og:url", content: "http://www.defaulturl.com"}
|
||||
}
|
||||
allow(helper).to receive(:general_metas).and_return(default_attributes)
|
||||
end
|
||||
|
||||
it "returns the default meta datas if passed nothing" do
|
||||
metas_html = %(<meta name="description" content="default description" />\n) +
|
||||
%(<meta property="og:url" content="http://www.defaulturl.com" />)
|
||||
expect(helper.metas_tags).to eq(metas_html)
|
||||
end
|
||||
|
||||
it "combines by default the general meta datas with the passed attributes" do
|
||||
metas_html = %(<meta name="description" content="i am a test" />\n) +
|
||||
%(<meta property="og:url" content="http://www.defaulturl.com" />\n) +
|
||||
%(<meta property="og:website" content="http://www.test2.com" />)
|
||||
expect(helper.metas_tags(@attributes)).to eq(metas_html)
|
||||
end
|
||||
|
||||
it "does not combines the general meta datas with the passed attributes if option is disabled" do
|
||||
default_metas_html = %(<meta name="description" content="default description" />\n) +
|
||||
%(<meta property="og:url" content="http://www.defaulturl.com" />)
|
||||
expect(helper.metas_tags(@attributes, false)).not_to include(default_metas_html)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,20 +1,6 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe OpenGraphHelper, :type => :helper do
|
||||
describe 'og_page_post_tags' do
|
||||
it 'handles a reshare of a deleted post' do
|
||||
reshare = FactoryGirl.build(:reshare, root: nil, id: 123)
|
||||
|
||||
expect {
|
||||
helper.og_page_post_tags(reshare)
|
||||
}.to_not raise_error
|
||||
end
|
||||
|
||||
it 'handles a normal post' do
|
||||
post = FactoryGirl.create(:status_message)
|
||||
expect(helper.og_page_post_tags(post)).to include helper.og_url(post_url(post))
|
||||
end
|
||||
end
|
||||
|
||||
describe 'og_html' do
|
||||
scenarios = {
|
||||
|
|
|
|||
Loading…
Reference in a new issue