From 8a1be65dea5b6df9a8122f498e2a82cb8ef9ff38 Mon Sep 17 00:00:00 2001 From: Braulio Bhavamitra Date: Sun, 1 Feb 2015 17:56:32 -0300 Subject: [PATCH] metadata: Support key attr specification (fix tests) --- app/helpers/layout_helper.rb | 3 --- app/views/layouts/application-ng.html.erb | 5 ----- plugins/metadata/lib/ext/article.rb | 57 ++++++++++++++++++++++++++++++++++----------------------- plugins/metadata/lib/ext/community.rb | 6 +++--- plugins/metadata/lib/ext/enterprise.rb | 26 ++++++++++++++------------ plugins/metadata/lib/ext/environment.rb | 12 ++++++------ plugins/metadata/lib/ext/person.rb | 6 +++--- plugins/metadata/lib/ext/product.rb | 37 +++++++++++++++++++------------------ plugins/metadata/lib/ext/profile.rb | 33 ++++++++++++++++++--------------- plugins/metadata/lib/ext/uploaded_file.rb | 14 +++++++------- plugins/metadata/lib/metadata_plugin.rb | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------- plugins/metadata/lib/metadata_plugin/spec.rb | 29 ----------------------------- plugins/metadata/lib/metadata_plugin/specs.rb | 22 ++++++++++++++++++++++ plugins/metadata/test/functional/content_viewer_controller_test.rb | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ test/functional/content_viewer_controller_test.rb | 24 ------------------------ 15 files changed, 233 insertions(+), 163 deletions(-) delete mode 100644 plugins/metadata/lib/metadata_plugin/spec.rb create mode 100644 plugins/metadata/lib/metadata_plugin/specs.rb create mode 100644 plugins/metadata/test/functional/content_viewer_controller_test.rb diff --git a/app/helpers/layout_helper.rb b/app/helpers/layout_helper.rb index eb98c22..d47fb2a 100644 --- a/app/helpers/layout_helper.rb +++ b/app/helpers/layout_helper.rb @@ -116,8 +116,5 @@ module LayoutHelper end end - def meta_description_tag(article=nil) - article ? CGI.escapeHTML(truncate(strip_tags(article.body.to_s), :length => 200)) : environment.name - end end diff --git a/app/views/layouts/application-ng.html.erb b/app/views/layouts/application-ng.html.erb index 23530a0..9ce1af3 100644 --- a/app/views/layouts/application-ng.html.erb +++ b/app/views/layouts/application-ng.html.erb @@ -7,11 +7,6 @@ - - - - - diff --git a/plugins/metadata/lib/ext/article.rb b/plugins/metadata/lib/ext/article.rb index ecd3a58..1a0aa83 100644 --- a/plugins/metadata/lib/ext/article.rb +++ b/plugins/metadata/lib/ext/article.rb @@ -2,31 +2,42 @@ require_dependency 'article' class Article - Metadata = { - 'og:type' => MetadataPlugin.og_types[:article], - 'og:url' => proc{ |a, c| c.og_url_for a.url }, - 'og:title' => proc{ |a, c| a.title }, - 'og:image' => proc do |a, c| - result = a.body_images_paths - result = "#{a.profile.environment.top_url}#{a.profile.image.public_filename}" if a.profile.image if result.blank? - result = MetadataPlugin.config[:open_graph][:environment_logo] if result.blank? - result - end, - 'og:see_also' => [], - 'og:site_name' => proc{ |a, c| a.profile.name }, - 'og:updated_time' => proc{ |a, c| a.updated_at.iso8601 }, - 'og:locale:locale' => proc{ |a, c| a.environment.default_language }, - 'og:locale:alternate' => proc{ |a, c| a.environment.languages - [a.environment.default_language] }, - 'twitter:image' => proc{ |a, c| a.body_images_paths }, - 'article:expiration_time' => "", # In the future we might want to populate this - 'article:modified_time' => proc{ |a, c| a.updated_at.iso8601 }, - 'article:published_time' => proc{ |a, c| a.published_at.iso8601 }, - 'article:section' => "", # In the future we might want to populate this - 'article:tag' => proc{ |a, c| a.tags.map &:name }, - 'og:description' => proc{ |a, c| ActionView::Base.full_sanitizer.sanitize a.body }, - 'og:rich_attachment' => "", + metadata_spec namespace: :og, key_attr: :property, tags: { + type: MetadataPlugin.og_types[:article] || :article, + url: proc{ |a, plugin| plugin.og_url_for a.url }, + title: proc{ |a, plugin| "#{a.title} - #{a.profile.name}" }, + image: proc do |a, plugin| + result = a.body_images_paths + result = "#{a.profile.environment.top_url}#{a.profile.image.public_filename}" if a.profile.image if result.blank? + result ||= MetadataPlugin.config[:open_graph][:environment_logo] rescue nil if result.blank? + result + end, + see_also: [], + site_name: proc{ |a, c| a.profile.name }, + updated_time: proc{ |a, c| a.updated_at.iso8601 }, + 'locale:locale' => proc{ |a, c| a.environment.default_language }, + 'locale:alternate' => proc{ |a, c| a.environment.languages - [a.environment.default_language] }, + + description: proc{ |a, plugin| ActionView::Base.full_sanitizer.sanitize a.body }, + rich_attachment: "", } + metadata_spec namespace: :twitter, key_attr: :name, tags: { + card: 'summary', + description: proc do |a, plugin| + description = a.body.to_s || a.environment.name + CGI.escapeHTML(plugin.helpers.truncate(plugin.helpers.strip_tags(description), length: 200)) + end, + title: proc{ |a, plugin| "#{a.title} - #{a.profile.name}" }, + image: proc{ |a, plugin| a.body_images_paths }, + } + metadata_spec namespace: :article, key_attr: :property, tags: { + expiration_time: "", # In the future we might want to populate this + modified_time: proc{ |a, plugin| a.updated_at.iso8601 }, + published_time: proc{ |a, plugin| a.published_at.iso8601 }, + section: "", # In the future we might want to populate this + tag: proc{ |a, plugin| a.tags.map &:name }, + } end diff --git a/plugins/metadata/lib/ext/community.rb b/plugins/metadata/lib/ext/community.rb index e550b46..e5dbb0d 100644 --- a/plugins/metadata/lib/ext/community.rb +++ b/plugins/metadata/lib/ext/community.rb @@ -3,8 +3,8 @@ require_dependency "#{File.dirname __FILE__}/profile" class Community - Metadata = Metadata.merge({ - 'og:type' => MetadataPlugin.og_types[:community], - }) + metadata_spec namespace: :og, tags: { + type: MetadataPlugin.og_types[:community] || :community, + } end diff --git a/plugins/metadata/lib/ext/enterprise.rb b/plugins/metadata/lib/ext/enterprise.rb index 2fa565c..ae43783 100644 --- a/plugins/metadata/lib/ext/enterprise.rb +++ b/plugins/metadata/lib/ext/enterprise.rb @@ -3,16 +3,18 @@ require_dependency "#{File.dirname __FILE__}/profile" class Enterprise - Metadata = Metadata.merge({ - 'og:type' => MetadataPlugin.og_types[:enterprise], - 'business:contact_data:email' => proc{ |e, c| e.contact_email }, - 'business:contact_data:phone_number' => proc{ |e, c| e.contact_phone }, - 'business:contact_data:street_address' => proc{ |e, c| e.address }, - 'business:contact_data:locality' => proc{ |e, c| e.city }, - 'business:contact_data:region' => proc{ |e, c| e.state }, - 'business:contact_data:postal_code' => proc{ |e, c| e.zip_code }, - 'business:contact_data:country_name' => proc{ |e| e.country }, - 'place:location:latitude' => proc{ |e, c| p.lat }, - 'place:location:longitude' => proc{ |e, c| p.lng }, - }) + metadata_spec namespace: :og, tags: { + type: MetadataPlugin.og_types[:enterprise] || :enterprise, + } + + metadata_spec namespace: 'business:contact_data', tags: { + email: proc{ |e, plugin| e.contact_email }, + phone_number: proc{ |e, plugin| e.contact_phone }, + street_address: proc{ |e, plugin| e.address }, + locality: proc{ |e, plugin| e.city }, + region: proc{ |e, plugin| e.state }, + postal_code: proc{ |e, plugin| e.zip_code }, + country_name: proc{ |e, plugin| e.country }, + } + end diff --git a/plugins/metadata/lib/ext/environment.rb b/plugins/metadata/lib/ext/environment.rb index 67498c1..55fb380 100644 --- a/plugins/metadata/lib/ext/environment.rb +++ b/plugins/metadata/lib/ext/environment.rb @@ -2,12 +2,12 @@ require_dependency 'environment' class Environment - Metadata = { - 'og:site_name' => proc{ |e, c| e.name }, - 'og:description' => proc{ |e, c| e.name }, - 'og:url' => proc{ |e, c| e.top_url }, - 'og:locale:locale' => proc{ |e, c| e.default_language }, - 'og:locale:alternate' => proc{ |e, c| e.languages - [e.default_language] } + metadata_spec namespace: :og, tags: { + site_name: proc{ |e, plugin| e.name }, + description: proc{ |e, plugin| e.name }, + url: proc{ |e, plugin| e.top_url }, + 'locale:locale' => proc{ |e, plugin| e.default_language }, + 'locale:alternate' => proc{ |e, plugin| e.languages - [e.default_language] }, } end diff --git a/plugins/metadata/lib/ext/person.rb b/plugins/metadata/lib/ext/person.rb index 2b93a98..f3f8600 100644 --- a/plugins/metadata/lib/ext/person.rb +++ b/plugins/metadata/lib/ext/person.rb @@ -3,8 +3,8 @@ require_dependency "#{File.dirname __FILE__}/profile" class Person - Metadata = Metadata.merge({ - 'og:type' => MetadataPlugin.og_types[:person], - }) + metadata_spec namespace: :og, tags: { + type: MetadataPlugin.og_types[:person] || :person, + } end diff --git a/plugins/metadata/lib/ext/product.rb b/plugins/metadata/lib/ext/product.rb index ac3b95f..547bc74 100644 --- a/plugins/metadata/lib/ext/product.rb +++ b/plugins/metadata/lib/ext/product.rb @@ -2,24 +2,25 @@ require_dependency 'product' class Product - Metadata = { - 'og:type' => MetadataPlugin.og_types[:product], - 'og:url' => proc{ |p, c| c.og_url_for p.url }, - 'og:gr_hascurrencyvalue' => proc{ |p, c| p.price.to_f }, - 'og:gr_hascurrency' => proc{ |p, c| p.environment.currency_unit }, - 'og:title' => proc{ |p, c| p.name }, - 'og:description' => proc{ |p, c| ActionView::Base.full_sanitizer.sanitize p.description }, - 'og:image' => proc{ |p, c| "#{p.environment.top_url}#{p.image.public_filename}" if p.image }, - 'og:image:type' => proc{ |p, c| p.image.content_type if p.image }, - 'og:image:height' => proc{ |p, c| p.image.height if p.image }, - 'og:image:width' => proc{ |p, c| p.image.width if p.image }, - 'og:see_also' => [], - 'og:site_name' => proc{ |p, c| c.og_url_for p.profile.url }, - 'og:updated_time' => proc{ |p, c| p.updated_at.iso8601 }, - 'og:locale:locale' => proc{ |p, c| p.environment.default_language }, - 'og:locale:alternate' => proc{ |p, c| p.environment.languages - [p.environment.default_language] }, - } + metadata_spec namespace: :og, tags: { + type: MetadataPlugin.og_types[:product] || :product, + url: proc{ |p, plugin| plugin.og_url_for p.url }, + gr_hascurrencyvalue: proc{ |p, plugin| p.price.to_f }, + gr_hascurrency: proc{ |p, plugin| p.environment.currency_unit }, + title: proc{ |a, plugin| "#{p.name} - #{p.profile.name}" }, + description: proc{ |p, plugin| ActionView::Base.full_sanitizer.sanitize p.description }, + + image: proc{ |p, plugin| "#{p.environment.top_url}#{p.image.public_filename}" if p.image }, + 'image:type' => proc{ |p, plugin| p.image.content_type if p.image }, + 'image:height' => proc{ |p, plugin| p.image.height if p.image }, + 'image:width' => proc{ |p, plugin| p.image.width if p.image }, - protected + see_also: [], + site_name: proc{ |p, plugin| plugin.og_url_for p.profile.url }, + updated_time: proc{ |p, plugin| p.updated_at.iso8601 }, + + 'locale:locale' => proc{ |p, plugin| p.environment.default_language }, + 'locale:alternate' => proc{ |p, plugin| p.environment.languages - [p.environment.default_language] if p.environment.languages }, + } end diff --git a/plugins/metadata/lib/ext/profile.rb b/plugins/metadata/lib/ext/profile.rb index f378e25..016ae09 100644 --- a/plugins/metadata/lib/ext/profile.rb +++ b/plugins/metadata/lib/ext/profile.rb @@ -2,23 +2,26 @@ require_dependency 'profile' class Profile - Metadata = { - 'og:type' => MetadataPlugin.og_types[:profile], - 'og:image' => proc{ |p, c| "#{p.environment.top_url}#{p.image.public_filename}" if p.image }, - 'og:title' => proc{ |p, c| p.short_name nil }, - 'og:url' => proc do |p, c| + metadata_spec namespace: :og, tags: { + type: MetadataPlugin.og_types[:profile] || :profile, + image: proc{ |p, plugin| "#{p.environment.top_url}#{p.image.public_filename}" if p.image }, + title: proc{ |p, plugin| p.nickname || p.name }, + url: proc do |p, plugin| #force profile identifier for custom domains and fixed host. see og_url_for - c.og_url_for p.url.merge(profile: p.identifier) + plugin.og_url_for p.url.merge(profile: p.identifier) end, - 'og:description' => proc{ |p, c| p.description }, - 'og:updated_time' => proc{ |p, c| p.updated_at.iso8601 }, - 'place:location:latitude' => proc{ |p, c| p.lat }, - 'place:location:longitude' => proc{ |p, c| p.lng }, - 'og:locale:locale' => proc{ |p, c| p.environment.default_language }, - 'og:locale:alternate' => proc{ |p, c| p.environment.languages - [p.environment.default_language] }, - 'og:site_name' => "", - 'og:see_also' => "", - 'og:rich_attachment' => "", + description: proc{ |p, plugin| p.description }, + updated_time: proc{ |p, plugin| p.updated_at.iso8601 }, + 'locale:locale' => proc{ |p, plugin| p.environment.default_language }, + 'locale:alternate' => proc{ |p, plugin| p.environment.languages - [p.environment.default_language] if p.environment.languages }, + site_name: "", + see_also: "", + rich_attachment: "", + } + + metadata_spec namespace: 'place:location', tags: { + latitude: proc{ |p, plugin| p.lat }, + longitude: proc{ |p, plugin| p.lng }, } end diff --git a/plugins/metadata/lib/ext/uploaded_file.rb b/plugins/metadata/lib/ext/uploaded_file.rb index 86acc2b..399eec2 100644 --- a/plugins/metadata/lib/ext/uploaded_file.rb +++ b/plugins/metadata/lib/ext/uploaded_file.rb @@ -3,15 +3,15 @@ require_dependency "#{File.dirname __FILE__}/article" class UploadedFile - Metadata = { - 'og:type' => proc do |u, c| + metadata_spec namespace: :og, tags: { + type: proc do |u, plugin| type = if u.image? then :image else :uploaded_file end - MetadataPlugin.og_types[type] + MetadataPlugin.og_types[type] || type end, - 'og:url' => proc{ |u, c| c.og_url_for u.url.merge(view: true) }, - 'og:title' => proc{ |u, c| u.title }, - 'og:image' => proc{ |u, c| "#{u.environment.top_url}#{u.public_filename}" if u.image? }, - 'og:description' => proc{ |u, c| u.abstract || u.title }, + url: proc{ |u, plugin| plugin.og_url_for u.url.merge(view: true) }, + title: proc{ |u, plugin| u.title }, + image: proc{ |u, plugin| "#{u.environment.top_url}#{u.public_filename}" if u.image? }, + description: proc{ |u, plugin| u.abstract || u.title }, } end diff --git a/plugins/metadata/lib/metadata_plugin.rb b/plugins/metadata/lib/metadata_plugin.rb index 69d79f4..b23be30 100644 --- a/plugins/metadata/lib/metadata_plugin.rb +++ b/plugins/metadata/lib/metadata_plugin.rb @@ -17,30 +17,64 @@ class MetadataPlugin < Noosfero::Plugin @og_types ||= self.config[:open_graph][:types] rescue {} end + Controllers = { + manage_products: { + variable: :@product, + }, + content_viewer: { + variable: proc do + if profile and profile.home_page_id == @page.id + @profile + elsif @page.respond_to? :encapsulated_file + @page.encapsulated_file + else + @page + end + end, + }, + profile: { + variable: :@profile, + }, + # fallback + environment: { + variable: :@environment, + }, + } + def head_ending plugin = self lambda do - options = MetadataPlugin::Spec::Controllers[controller.controller_path.to_sym] - options ||= MetadataPlugin::Spec::Controllers[:profile] if controller.is_a? ProfileController - options ||= MetadataPlugin::Spec::Controllers[:environment] + options = MetadataPlugin::Controllers[controller.controller_path.to_sym] + options ||= MetadataPlugin::Controllers[:profile] if controller.is_a? ProfileController + options ||= MetadataPlugin::Controllers[:environment] return unless options return unless object = case variable = options[:variable] when Proc then instance_exec(&variable) rescue nil else instance_variable_get variable end - return unless metadata = (object.class.const_get(:Metadata) rescue nil) - - metadata.map do |property, contents| - contents = contents.call(object, plugin) rescue nil if contents.is_a? Proc - next if contents.blank? - - Array(contents).map do |content| - content = content.call(object, plugin) rescue nil if content.is_a? Proc - next if content.blank? - tag 'meta', property: property, content: content - end.join - end.join + return unless specs = (object.class.metadata_specs rescue nil) + + r = [] + specs.each do |namespace, spec| + namespace = "#{namespace}:" if namespace.present? + key_attr = spec[:key_attr] || :property + value_attr = spec[:value_attr] || :content + tags = spec[:tags] + + tags.each do |key, values| + key = "#{namespace}#{key}" + values = values.call(object, plugin) rescue nil if values.is_a? Proc + next if values.blank? + + Array(values).each do |value| + value = value.call(object, plugin) rescue nil if value.is_a? Proc + next if value.blank? + r << tag(:meta, key_attr => key, value_attr => value) + end + end + end + r.join end end @@ -51,9 +85,16 @@ class MetadataPlugin < Noosfero::Plugin Noosfero::Application.routes.url_helpers.url_for options end + def helpers + self.context.class.helpers + end + protected end ActiveSupport.run_load_hooks :metadata_plugin, MetadataPlugin +ActiveSupport.on_load :active_record do + ActiveRecord::Base.extend MetadataPlugin::Specs::ClassMethods +end diff --git a/plugins/metadata/lib/metadata_plugin/spec.rb b/plugins/metadata/lib/metadata_plugin/spec.rb deleted file mode 100644 index af67ece..0000000 --- a/plugins/metadata/lib/metadata_plugin/spec.rb +++ /dev/null @@ -1,29 +0,0 @@ - -class MetadataPlugin::Spec - - Controllers = { - manage_products: { - variable: :@product, - }, - content_viewer: { - variable: proc do - if profile and profile.home_page_id == @page.id - @profile - elsif @page.respond_to? :encapsulated_file - @page.encapsulated_file - else - @page - end - end, - }, - # fallback - profile: { - variable: :@profile, - }, - # last fallback - environment: { - variable: :@environment, - }, - } - -end diff --git a/plugins/metadata/lib/metadata_plugin/specs.rb b/plugins/metadata/lib/metadata_plugin/specs.rb new file mode 100644 index 0000000..04ebdd5 --- /dev/null +++ b/plugins/metadata/lib/metadata_plugin/specs.rb @@ -0,0 +1,22 @@ +module MetadataPlugin::Specs + + module ClassMethods + + def self.extended base + base.class_attribute :metadata_specs + base.metadata_specs ||= {} + end + + def metadata_spec spec = {} + namespace = spec[:namespace] + # setters are used to avoid propagation to super classes, see http://apidock.com/rails/Class/class_attribute + if _spec = self.metadata_specs[namespace] + self.metadata_specs = self.metadata_specs.deep_merge(namespace => _spec.deep_merge(spec)) + else + self.metadata_specs = self.metadata_specs.deep_merge(namespace => spec) + end + end + + end + +end diff --git a/plugins/metadata/test/functional/content_viewer_controller_test.rb b/plugins/metadata/test/functional/content_viewer_controller_test.rb new file mode 100644 index 0000000..1c7787c --- /dev/null +++ b/plugins/metadata/test/functional/content_viewer_controller_test.rb @@ -0,0 +1,51 @@ +require 'test_helper' +require 'content_viewer_controller' + +# Re-raise errors caught by the controller. +class ContentViewerController; def rescue_action(e) raise e end; end + +class ContentViewerControllerTest < ActionController::TestCase + + def setup + @controller = ContentViewerController.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + + @profile = create_user('testinguser').person + @environment = @profile.environment + @environment.enabled_plugins += ['MetadataPlugin'] + @environment.save! + end + + attr_reader :profile, :environment + + should 'produce meta tags for profile if on homepage' do + get :view_page, profile: profile.identifier, page: [] + assert_tag tag: 'meta', attributes: {property: 'og:title', content: profile.name} + end + + should 'add meta tags with article info' do + a = TinyMceArticle.create(name: 'Article to be shared', body: 'This article should be shared with all social networks', profile: profile) + + get :view_page, profile: profile.identifier, page: [ a.name.to_slug ] + + assert_tag tag: 'meta', attributes: { name: 'twitter:title', content: /#{a.name} - #{a.profile.name}/ } + assert_tag tag: 'meta', attributes: { name: 'twitter:description', content: a.body } + assert_no_tag tag: 'meta', attributes: { name: 'twitter:image' } + assert_tag tag: 'meta', attributes: { property: 'og:type', content: 'article' } + assert_tag tag: 'meta', attributes: { property: 'og:url', content: /\/#{profile.identifier}\/#{a.name.to_slug}/ } + assert_tag tag: 'meta', attributes: { property: 'og:title', content: /#{a.name} - #{a.profile.name}/ } + assert_tag tag: 'meta', attributes: { property: 'og:site_name', content: a.profile.name } + assert_tag tag: 'meta', attributes: { property: 'og:description', content: a.body } + assert_no_tag tag: 'meta', attributes: { property: 'og:image' } + end + + should 'add meta tags with article images' do + a = TinyMceArticle.create(name: 'Article to be shared with images', body: 'This article should be shared with all social networks ', profile: profile) + + get :view_page, profile: profile.identifier, page: [ a.name.to_slug ] + assert_tag tag: 'meta', attributes: { name: 'twitter:image', content: /\/images\/x.png/ } + assert_tag tag: 'meta', attributes: { property: 'og:image', content: /\/images\/x.png/ } + end + +end diff --git a/test/functional/content_viewer_controller_test.rb b/test/functional/content_viewer_controller_test.rb index 41a845a..af40524 100644 --- a/test/functional/content_viewer_controller_test.rb +++ b/test/functional/content_viewer_controller_test.rb @@ -1405,30 +1405,6 @@ class ContentViewerControllerTest < ActionController::TestCase end end - should 'add meta tags with article info' do - a = TinyMceArticle.create(:name => 'Article to be shared', :body => 'This article should be shared with all social networks', :profile => profile) - - get :view_page, :profile => profile.identifier, :page => [ a.name.to_slug ] - - assert_tag :tag => 'meta', :attributes => { :name => 'twitter:title', :content => /#{a.name} - #{a.profile.name}/ } - assert_tag :tag => 'meta', :attributes => { :name => 'twitter:description', :content => a.body } - assert_no_tag :tag => 'meta', :attributes => { :name => 'twitter:image' } - assert_tag :tag => 'meta', :attributes => { :property => 'og:type', :content => 'article' } - assert_tag :tag => 'meta', :attributes => { :property => 'og:url', :content => /\/#{profile.identifier}\/#{a.name.to_slug}/ } - assert_tag :tag => 'meta', :attributes => { :property => 'og:title', :content => /#{a.name} - #{a.profile.name}/ } - assert_tag :tag => 'meta', :attributes => { :property => 'og:site_name', :content => a.profile.name } - assert_tag :tag => 'meta', :attributes => { :property => 'og:description', :content => a.body } - assert_no_tag :tag => 'meta', :attributes => { :property => 'og:image' } - end - - should 'add meta tags with article images' do - a = TinyMceArticle.create(:name => 'Article to be shared with images', :body => 'This article should be shared with all social networks ', :profile => profile) - - get :view_page, :profile => profile.identifier, :page => [ a.name.to_slug ] - assert_tag :tag => 'meta', :attributes => { :name => 'twitter:image', :content => /\/images\/x.png/ } - assert_tag :tag => 'meta', :attributes => { :property => 'og:image', :content => /\/images\/x.png/ } - end - should 'manage private article visualization' do community = Community.create(:name => 'test-community') community.add_member(@profile) -- libgit2 0.21.2