Commit 8a1be65dea5b6df9a8122f498e2a82cb8ef9ff38
1 parent
ee532d16
Exists in
staging
and in
42 other branches
metadata: Support key attr specification (fix tests)
Showing
15 changed files
with
233 additions
and
163 deletions
Show diff stats
app/helpers/layout_helper.rb
app/views/layouts/application-ng.html.erb
| ... | ... | @@ -7,11 +7,6 @@ |
| 7 | 7 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> |
| 8 | 8 | <meta name="description" content="<%= @environment.name %>" /> |
| 9 | 9 | |
| 10 | - <!-- Twitter Card --> | |
| 11 | - <meta name="twitter:card" value="summary"> | |
| 12 | - <meta name="twitter:title" content="<%= h page_title %>"> | |
| 13 | - <meta name="twitter:description" content="<%= meta_description_tag(@page) %>"> | |
| 14 | - | |
| 15 | 10 | <!-- site root --> |
| 16 | 11 | <meta property="noosfero:root" content="<%= Noosfero.root %>"/> |
| 17 | 12 | ... | ... |
plugins/metadata/lib/ext/article.rb
| ... | ... | @@ -2,31 +2,42 @@ require_dependency 'article' |
| 2 | 2 | |
| 3 | 3 | class Article |
| 4 | 4 | |
| 5 | - Metadata = { | |
| 6 | - 'og:type' => MetadataPlugin.og_types[:article], | |
| 7 | - 'og:url' => proc{ |a, c| c.og_url_for a.url }, | |
| 8 | - 'og:title' => proc{ |a, c| a.title }, | |
| 9 | - 'og:image' => proc do |a, c| | |
| 10 | - result = a.body_images_paths | |
| 11 | - result = "#{a.profile.environment.top_url}#{a.profile.image.public_filename}" if a.profile.image if result.blank? | |
| 12 | - result = MetadataPlugin.config[:open_graph][:environment_logo] if result.blank? | |
| 13 | - result | |
| 14 | - end, | |
| 15 | - 'og:see_also' => [], | |
| 16 | - 'og:site_name' => proc{ |a, c| a.profile.name }, | |
| 17 | - 'og:updated_time' => proc{ |a, c| a.updated_at.iso8601 }, | |
| 18 | - 'og:locale:locale' => proc{ |a, c| a.environment.default_language }, | |
| 19 | - 'og:locale:alternate' => proc{ |a, c| a.environment.languages - [a.environment.default_language] }, | |
| 20 | - 'twitter:image' => proc{ |a, c| a.body_images_paths }, | |
| 21 | - 'article:expiration_time' => "", # In the future we might want to populate this | |
| 22 | - 'article:modified_time' => proc{ |a, c| a.updated_at.iso8601 }, | |
| 23 | - 'article:published_time' => proc{ |a, c| a.published_at.iso8601 }, | |
| 24 | - 'article:section' => "", # In the future we might want to populate this | |
| 25 | - 'article:tag' => proc{ |a, c| a.tags.map &:name }, | |
| 26 | - 'og:description' => proc{ |a, c| ActionView::Base.full_sanitizer.sanitize a.body }, | |
| 27 | - 'og:rich_attachment' => "", | |
| 5 | + metadata_spec namespace: :og, key_attr: :property, tags: { | |
| 6 | + type: MetadataPlugin.og_types[:article] || :article, | |
| 7 | + url: proc{ |a, plugin| plugin.og_url_for a.url }, | |
| 8 | + title: proc{ |a, plugin| "#{a.title} - #{a.profile.name}" }, | |
| 9 | + image: proc do |a, plugin| | |
| 10 | + result = a.body_images_paths | |
| 11 | + result = "#{a.profile.environment.top_url}#{a.profile.image.public_filename}" if a.profile.image if result.blank? | |
| 12 | + result ||= MetadataPlugin.config[:open_graph][:environment_logo] rescue nil if result.blank? | |
| 13 | + result | |
| 14 | + end, | |
| 15 | + see_also: [], | |
| 16 | + site_name: proc{ |a, c| a.profile.name }, | |
| 17 | + updated_time: proc{ |a, c| a.updated_at.iso8601 }, | |
| 18 | + 'locale:locale' => proc{ |a, c| a.environment.default_language }, | |
| 19 | + 'locale:alternate' => proc{ |a, c| a.environment.languages - [a.environment.default_language] }, | |
| 20 | + | |
| 21 | + description: proc{ |a, plugin| ActionView::Base.full_sanitizer.sanitize a.body }, | |
| 22 | + rich_attachment: "", | |
| 28 | 23 | } |
| 29 | 24 | |
| 25 | + metadata_spec namespace: :twitter, key_attr: :name, tags: { | |
| 26 | + card: 'summary', | |
| 27 | + description: proc do |a, plugin| | |
| 28 | + description = a.body.to_s || a.environment.name | |
| 29 | + CGI.escapeHTML(plugin.helpers.truncate(plugin.helpers.strip_tags(description), length: 200)) | |
| 30 | + end, | |
| 31 | + title: proc{ |a, plugin| "#{a.title} - #{a.profile.name}" }, | |
| 32 | + image: proc{ |a, plugin| a.body_images_paths }, | |
| 33 | + } | |
| 30 | 34 | |
| 35 | + metadata_spec namespace: :article, key_attr: :property, tags: { | |
| 36 | + expiration_time: "", # In the future we might want to populate this | |
| 37 | + modified_time: proc{ |a, plugin| a.updated_at.iso8601 }, | |
| 38 | + published_time: proc{ |a, plugin| a.published_at.iso8601 }, | |
| 39 | + section: "", # In the future we might want to populate this | |
| 40 | + tag: proc{ |a, plugin| a.tags.map &:name }, | |
| 41 | + } | |
| 31 | 42 | |
| 32 | 43 | end | ... | ... |
plugins/metadata/lib/ext/community.rb
| ... | ... | @@ -3,8 +3,8 @@ require_dependency "#{File.dirname __FILE__}/profile" |
| 3 | 3 | |
| 4 | 4 | class Community |
| 5 | 5 | |
| 6 | - Metadata = Metadata.merge({ | |
| 7 | - 'og:type' => MetadataPlugin.og_types[:community], | |
| 8 | - }) | |
| 6 | + metadata_spec namespace: :og, tags: { | |
| 7 | + type: MetadataPlugin.og_types[:community] || :community, | |
| 8 | + } | |
| 9 | 9 | |
| 10 | 10 | end | ... | ... |
plugins/metadata/lib/ext/enterprise.rb
| ... | ... | @@ -3,16 +3,18 @@ require_dependency "#{File.dirname __FILE__}/profile" |
| 3 | 3 | |
| 4 | 4 | class Enterprise |
| 5 | 5 | |
| 6 | - Metadata = Metadata.merge({ | |
| 7 | - 'og:type' => MetadataPlugin.og_types[:enterprise], | |
| 8 | - 'business:contact_data:email' => proc{ |e, c| e.contact_email }, | |
| 9 | - 'business:contact_data:phone_number' => proc{ |e, c| e.contact_phone }, | |
| 10 | - 'business:contact_data:street_address' => proc{ |e, c| e.address }, | |
| 11 | - 'business:contact_data:locality' => proc{ |e, c| e.city }, | |
| 12 | - 'business:contact_data:region' => proc{ |e, c| e.state }, | |
| 13 | - 'business:contact_data:postal_code' => proc{ |e, c| e.zip_code }, | |
| 14 | - 'business:contact_data:country_name' => proc{ |e| e.country }, | |
| 15 | - 'place:location:latitude' => proc{ |e, c| p.lat }, | |
| 16 | - 'place:location:longitude' => proc{ |e, c| p.lng }, | |
| 17 | - }) | |
| 6 | + metadata_spec namespace: :og, tags: { | |
| 7 | + type: MetadataPlugin.og_types[:enterprise] || :enterprise, | |
| 8 | + } | |
| 9 | + | |
| 10 | + metadata_spec namespace: 'business:contact_data', tags: { | |
| 11 | + email: proc{ |e, plugin| e.contact_email }, | |
| 12 | + phone_number: proc{ |e, plugin| e.contact_phone }, | |
| 13 | + street_address: proc{ |e, plugin| e.address }, | |
| 14 | + locality: proc{ |e, plugin| e.city }, | |
| 15 | + region: proc{ |e, plugin| e.state }, | |
| 16 | + postal_code: proc{ |e, plugin| e.zip_code }, | |
| 17 | + country_name: proc{ |e, plugin| e.country }, | |
| 18 | + } | |
| 19 | + | |
| 18 | 20 | end | ... | ... |
plugins/metadata/lib/ext/environment.rb
| ... | ... | @@ -2,12 +2,12 @@ require_dependency 'environment' |
| 2 | 2 | |
| 3 | 3 | class Environment |
| 4 | 4 | |
| 5 | - Metadata = { | |
| 6 | - 'og:site_name' => proc{ |e, c| e.name }, | |
| 7 | - 'og:description' => proc{ |e, c| e.name }, | |
| 8 | - 'og:url' => proc{ |e, c| e.top_url }, | |
| 9 | - 'og:locale:locale' => proc{ |e, c| e.default_language }, | |
| 10 | - 'og:locale:alternate' => proc{ |e, c| e.languages - [e.default_language] } | |
| 5 | + metadata_spec namespace: :og, tags: { | |
| 6 | + site_name: proc{ |e, plugin| e.name }, | |
| 7 | + description: proc{ |e, plugin| e.name }, | |
| 8 | + url: proc{ |e, plugin| e.top_url }, | |
| 9 | + 'locale:locale' => proc{ |e, plugin| e.default_language }, | |
| 10 | + 'locale:alternate' => proc{ |e, plugin| e.languages - [e.default_language] }, | |
| 11 | 11 | } |
| 12 | 12 | |
| 13 | 13 | end | ... | ... |
plugins/metadata/lib/ext/person.rb
| ... | ... | @@ -3,8 +3,8 @@ require_dependency "#{File.dirname __FILE__}/profile" |
| 3 | 3 | |
| 4 | 4 | class Person |
| 5 | 5 | |
| 6 | - Metadata = Metadata.merge({ | |
| 7 | - 'og:type' => MetadataPlugin.og_types[:person], | |
| 8 | - }) | |
| 6 | + metadata_spec namespace: :og, tags: { | |
| 7 | + type: MetadataPlugin.og_types[:person] || :person, | |
| 8 | + } | |
| 9 | 9 | |
| 10 | 10 | end | ... | ... |
plugins/metadata/lib/ext/product.rb
| ... | ... | @@ -2,24 +2,25 @@ require_dependency 'product' |
| 2 | 2 | |
| 3 | 3 | class Product |
| 4 | 4 | |
| 5 | - Metadata = { | |
| 6 | - 'og:type' => MetadataPlugin.og_types[:product], | |
| 7 | - 'og:url' => proc{ |p, c| c.og_url_for p.url }, | |
| 8 | - 'og:gr_hascurrencyvalue' => proc{ |p, c| p.price.to_f }, | |
| 9 | - 'og:gr_hascurrency' => proc{ |p, c| p.environment.currency_unit }, | |
| 10 | - 'og:title' => proc{ |p, c| p.name }, | |
| 11 | - 'og:description' => proc{ |p, c| ActionView::Base.full_sanitizer.sanitize p.description }, | |
| 12 | - 'og:image' => proc{ |p, c| "#{p.environment.top_url}#{p.image.public_filename}" if p.image }, | |
| 13 | - 'og:image:type' => proc{ |p, c| p.image.content_type if p.image }, | |
| 14 | - 'og:image:height' => proc{ |p, c| p.image.height if p.image }, | |
| 15 | - 'og:image:width' => proc{ |p, c| p.image.width if p.image }, | |
| 16 | - 'og:see_also' => [], | |
| 17 | - 'og:site_name' => proc{ |p, c| c.og_url_for p.profile.url }, | |
| 18 | - 'og:updated_time' => proc{ |p, c| p.updated_at.iso8601 }, | |
| 19 | - 'og:locale:locale' => proc{ |p, c| p.environment.default_language }, | |
| 20 | - 'og:locale:alternate' => proc{ |p, c| p.environment.languages - [p.environment.default_language] }, | |
| 21 | - } | |
| 5 | + metadata_spec namespace: :og, tags: { | |
| 6 | + type: MetadataPlugin.og_types[:product] || :product, | |
| 7 | + url: proc{ |p, plugin| plugin.og_url_for p.url }, | |
| 8 | + gr_hascurrencyvalue: proc{ |p, plugin| p.price.to_f }, | |
| 9 | + gr_hascurrency: proc{ |p, plugin| p.environment.currency_unit }, | |
| 10 | + title: proc{ |a, plugin| "#{p.name} - #{p.profile.name}" }, | |
| 11 | + description: proc{ |p, plugin| ActionView::Base.full_sanitizer.sanitize p.description }, | |
| 12 | + | |
| 13 | + image: proc{ |p, plugin| "#{p.environment.top_url}#{p.image.public_filename}" if p.image }, | |
| 14 | + 'image:type' => proc{ |p, plugin| p.image.content_type if p.image }, | |
| 15 | + 'image:height' => proc{ |p, plugin| p.image.height if p.image }, | |
| 16 | + 'image:width' => proc{ |p, plugin| p.image.width if p.image }, | |
| 22 | 17 | |
| 23 | - protected | |
| 18 | + see_also: [], | |
| 19 | + site_name: proc{ |p, plugin| plugin.og_url_for p.profile.url }, | |
| 20 | + updated_time: proc{ |p, plugin| p.updated_at.iso8601 }, | |
| 21 | + | |
| 22 | + 'locale:locale' => proc{ |p, plugin| p.environment.default_language }, | |
| 23 | + 'locale:alternate' => proc{ |p, plugin| p.environment.languages - [p.environment.default_language] if p.environment.languages }, | |
| 24 | + } | |
| 24 | 25 | |
| 25 | 26 | end | ... | ... |
plugins/metadata/lib/ext/profile.rb
| ... | ... | @@ -2,23 +2,26 @@ require_dependency 'profile' |
| 2 | 2 | |
| 3 | 3 | class Profile |
| 4 | 4 | |
| 5 | - Metadata = { | |
| 6 | - 'og:type' => MetadataPlugin.og_types[:profile], | |
| 7 | - 'og:image' => proc{ |p, c| "#{p.environment.top_url}#{p.image.public_filename}" if p.image }, | |
| 8 | - 'og:title' => proc{ |p, c| p.short_name nil }, | |
| 9 | - 'og:url' => proc do |p, c| | |
| 5 | + metadata_spec namespace: :og, tags: { | |
| 6 | + type: MetadataPlugin.og_types[:profile] || :profile, | |
| 7 | + image: proc{ |p, plugin| "#{p.environment.top_url}#{p.image.public_filename}" if p.image }, | |
| 8 | + title: proc{ |p, plugin| p.nickname || p.name }, | |
| 9 | + url: proc do |p, plugin| | |
| 10 | 10 | #force profile identifier for custom domains and fixed host. see og_url_for |
| 11 | - c.og_url_for p.url.merge(profile: p.identifier) | |
| 11 | + plugin.og_url_for p.url.merge(profile: p.identifier) | |
| 12 | 12 | end, |
| 13 | - 'og:description' => proc{ |p, c| p.description }, | |
| 14 | - 'og:updated_time' => proc{ |p, c| p.updated_at.iso8601 }, | |
| 15 | - 'place:location:latitude' => proc{ |p, c| p.lat }, | |
| 16 | - 'place:location:longitude' => proc{ |p, c| p.lng }, | |
| 17 | - 'og:locale:locale' => proc{ |p, c| p.environment.default_language }, | |
| 18 | - 'og:locale:alternate' => proc{ |p, c| p.environment.languages - [p.environment.default_language] }, | |
| 19 | - 'og:site_name' => "", | |
| 20 | - 'og:see_also' => "", | |
| 21 | - 'og:rich_attachment' => "", | |
| 13 | + description: proc{ |p, plugin| p.description }, | |
| 14 | + updated_time: proc{ |p, plugin| p.updated_at.iso8601 }, | |
| 15 | + 'locale:locale' => proc{ |p, plugin| p.environment.default_language }, | |
| 16 | + 'locale:alternate' => proc{ |p, plugin| p.environment.languages - [p.environment.default_language] if p.environment.languages }, | |
| 17 | + site_name: "", | |
| 18 | + see_also: "", | |
| 19 | + rich_attachment: "", | |
| 20 | + } | |
| 21 | + | |
| 22 | + metadata_spec namespace: 'place:location', tags: { | |
| 23 | + latitude: proc{ |p, plugin| p.lat }, | |
| 24 | + longitude: proc{ |p, plugin| p.lng }, | |
| 22 | 25 | } |
| 23 | 26 | |
| 24 | 27 | end | ... | ... |
plugins/metadata/lib/ext/uploaded_file.rb
| ... | ... | @@ -3,15 +3,15 @@ require_dependency "#{File.dirname __FILE__}/article" |
| 3 | 3 | |
| 4 | 4 | class UploadedFile |
| 5 | 5 | |
| 6 | - Metadata = { | |
| 7 | - 'og:type' => proc do |u, c| | |
| 6 | + metadata_spec namespace: :og, tags: { | |
| 7 | + type: proc do |u, plugin| | |
| 8 | 8 | type = if u.image? then :image else :uploaded_file end |
| 9 | - MetadataPlugin.og_types[type] | |
| 9 | + MetadataPlugin.og_types[type] || type | |
| 10 | 10 | end, |
| 11 | - 'og:url' => proc{ |u, c| c.og_url_for u.url.merge(view: true) }, | |
| 12 | - 'og:title' => proc{ |u, c| u.title }, | |
| 13 | - 'og:image' => proc{ |u, c| "#{u.environment.top_url}#{u.public_filename}" if u.image? }, | |
| 14 | - 'og:description' => proc{ |u, c| u.abstract || u.title }, | |
| 11 | + url: proc{ |u, plugin| plugin.og_url_for u.url.merge(view: true) }, | |
| 12 | + title: proc{ |u, plugin| u.title }, | |
| 13 | + image: proc{ |u, plugin| "#{u.environment.top_url}#{u.public_filename}" if u.image? }, | |
| 14 | + description: proc{ |u, plugin| u.abstract || u.title }, | |
| 15 | 15 | } |
| 16 | 16 | |
| 17 | 17 | end | ... | ... |
plugins/metadata/lib/metadata_plugin.rb
| ... | ... | @@ -17,30 +17,64 @@ class MetadataPlugin < Noosfero::Plugin |
| 17 | 17 | @og_types ||= self.config[:open_graph][:types] rescue {} |
| 18 | 18 | end |
| 19 | 19 | |
| 20 | + Controllers = { | |
| 21 | + manage_products: { | |
| 22 | + variable: :@product, | |
| 23 | + }, | |
| 24 | + content_viewer: { | |
| 25 | + variable: proc do | |
| 26 | + if profile and profile.home_page_id == @page.id | |
| 27 | + @profile | |
| 28 | + elsif @page.respond_to? :encapsulated_file | |
| 29 | + @page.encapsulated_file | |
| 30 | + else | |
| 31 | + @page | |
| 32 | + end | |
| 33 | + end, | |
| 34 | + }, | |
| 35 | + profile: { | |
| 36 | + variable: :@profile, | |
| 37 | + }, | |
| 38 | + # fallback | |
| 39 | + environment: { | |
| 40 | + variable: :@environment, | |
| 41 | + }, | |
| 42 | + } | |
| 43 | + | |
| 20 | 44 | def head_ending |
| 21 | 45 | plugin = self |
| 22 | 46 | lambda do |
| 23 | - options = MetadataPlugin::Spec::Controllers[controller.controller_path.to_sym] | |
| 24 | - options ||= MetadataPlugin::Spec::Controllers[:profile] if controller.is_a? ProfileController | |
| 25 | - options ||= MetadataPlugin::Spec::Controllers[:environment] | |
| 47 | + options = MetadataPlugin::Controllers[controller.controller_path.to_sym] | |
| 48 | + options ||= MetadataPlugin::Controllers[:profile] if controller.is_a? ProfileController | |
| 49 | + options ||= MetadataPlugin::Controllers[:environment] | |
| 26 | 50 | return unless options |
| 27 | 51 | |
| 28 | 52 | return unless object = case variable = options[:variable] |
| 29 | 53 | when Proc then instance_exec(&variable) rescue nil |
| 30 | 54 | else instance_variable_get variable |
| 31 | 55 | end |
| 32 | - return unless metadata = (object.class.const_get(:Metadata) rescue nil) | |
| 33 | - | |
| 34 | - metadata.map do |property, contents| | |
| 35 | - contents = contents.call(object, plugin) rescue nil if contents.is_a? Proc | |
| 36 | - next if contents.blank? | |
| 37 | - | |
| 38 | - Array(contents).map do |content| | |
| 39 | - content = content.call(object, plugin) rescue nil if content.is_a? Proc | |
| 40 | - next if content.blank? | |
| 41 | - tag 'meta', property: property, content: content | |
| 42 | - end.join | |
| 43 | - end.join | |
| 56 | + return unless specs = (object.class.metadata_specs rescue nil) | |
| 57 | + | |
| 58 | + r = [] | |
| 59 | + specs.each do |namespace, spec| | |
| 60 | + namespace = "#{namespace}:" if namespace.present? | |
| 61 | + key_attr = spec[:key_attr] || :property | |
| 62 | + value_attr = spec[:value_attr] || :content | |
| 63 | + tags = spec[:tags] | |
| 64 | + | |
| 65 | + tags.each do |key, values| | |
| 66 | + key = "#{namespace}#{key}" | |
| 67 | + values = values.call(object, plugin) rescue nil if values.is_a? Proc | |
| 68 | + next if values.blank? | |
| 69 | + | |
| 70 | + Array(values).each do |value| | |
| 71 | + value = value.call(object, plugin) rescue nil if value.is_a? Proc | |
| 72 | + next if value.blank? | |
| 73 | + r << tag(:meta, key_attr => key, value_attr => value) | |
| 74 | + end | |
| 75 | + end | |
| 76 | + end | |
| 77 | + r.join | |
| 44 | 78 | end |
| 45 | 79 | end |
| 46 | 80 | |
| ... | ... | @@ -51,9 +85,16 @@ class MetadataPlugin < Noosfero::Plugin |
| 51 | 85 | Noosfero::Application.routes.url_helpers.url_for options |
| 52 | 86 | end |
| 53 | 87 | |
| 88 | + def helpers | |
| 89 | + self.context.class.helpers | |
| 90 | + end | |
| 91 | + | |
| 54 | 92 | protected |
| 55 | 93 | |
| 56 | 94 | end |
| 57 | 95 | |
| 58 | 96 | ActiveSupport.run_load_hooks :metadata_plugin, MetadataPlugin |
| 97 | +ActiveSupport.on_load :active_record do | |
| 98 | + ActiveRecord::Base.extend MetadataPlugin::Specs::ClassMethods | |
| 99 | +end | |
| 59 | 100 | ... | ... |
plugins/metadata/lib/metadata_plugin/spec.rb
| ... | ... | @@ -1,29 +0,0 @@ |
| 1 | - | |
| 2 | -class MetadataPlugin::Spec | |
| 3 | - | |
| 4 | - Controllers = { | |
| 5 | - manage_products: { | |
| 6 | - variable: :@product, | |
| 7 | - }, | |
| 8 | - content_viewer: { | |
| 9 | - variable: proc do | |
| 10 | - if profile and profile.home_page_id == @page.id | |
| 11 | - @profile | |
| 12 | - elsif @page.respond_to? :encapsulated_file | |
| 13 | - @page.encapsulated_file | |
| 14 | - else | |
| 15 | - @page | |
| 16 | - end | |
| 17 | - end, | |
| 18 | - }, | |
| 19 | - # fallback | |
| 20 | - profile: { | |
| 21 | - variable: :@profile, | |
| 22 | - }, | |
| 23 | - # last fallback | |
| 24 | - environment: { | |
| 25 | - variable: :@environment, | |
| 26 | - }, | |
| 27 | - } | |
| 28 | - | |
| 29 | -end |
| ... | ... | @@ -0,0 +1,22 @@ |
| 1 | +module MetadataPlugin::Specs | |
| 2 | + | |
| 3 | + module ClassMethods | |
| 4 | + | |
| 5 | + def self.extended base | |
| 6 | + base.class_attribute :metadata_specs | |
| 7 | + base.metadata_specs ||= {} | |
| 8 | + end | |
| 9 | + | |
| 10 | + def metadata_spec spec = {} | |
| 11 | + namespace = spec[:namespace] | |
| 12 | + # setters are used to avoid propagation to super classes, see http://apidock.com/rails/Class/class_attribute | |
| 13 | + if _spec = self.metadata_specs[namespace] | |
| 14 | + self.metadata_specs = self.metadata_specs.deep_merge(namespace => _spec.deep_merge(spec)) | |
| 15 | + else | |
| 16 | + self.metadata_specs = self.metadata_specs.deep_merge(namespace => spec) | |
| 17 | + end | |
| 18 | + end | |
| 19 | + | |
| 20 | + end | |
| 21 | + | |
| 22 | +end | ... | ... |
plugins/metadata/test/functional/content_viewer_controller_test.rb
0 → 100644
| ... | ... | @@ -0,0 +1,51 @@ |
| 1 | +require 'test_helper' | |
| 2 | +require 'content_viewer_controller' | |
| 3 | + | |
| 4 | +# Re-raise errors caught by the controller. | |
| 5 | +class ContentViewerController; def rescue_action(e) raise e end; end | |
| 6 | + | |
| 7 | +class ContentViewerControllerTest < ActionController::TestCase | |
| 8 | + | |
| 9 | + def setup | |
| 10 | + @controller = ContentViewerController.new | |
| 11 | + @request = ActionController::TestRequest.new | |
| 12 | + @response = ActionController::TestResponse.new | |
| 13 | + | |
| 14 | + @profile = create_user('testinguser').person | |
| 15 | + @environment = @profile.environment | |
| 16 | + @environment.enabled_plugins += ['MetadataPlugin'] | |
| 17 | + @environment.save! | |
| 18 | + end | |
| 19 | + | |
| 20 | + attr_reader :profile, :environment | |
| 21 | + | |
| 22 | + should 'produce meta tags for profile if on homepage' do | |
| 23 | + get :view_page, profile: profile.identifier, page: [] | |
| 24 | + assert_tag tag: 'meta', attributes: {property: 'og:title', content: profile.name} | |
| 25 | + end | |
| 26 | + | |
| 27 | + should 'add meta tags with article info' do | |
| 28 | + a = TinyMceArticle.create(name: 'Article to be shared', body: 'This article should be shared with all social networks', profile: profile) | |
| 29 | + | |
| 30 | + get :view_page, profile: profile.identifier, page: [ a.name.to_slug ] | |
| 31 | + | |
| 32 | + assert_tag tag: 'meta', attributes: { name: 'twitter:title', content: /#{a.name} - #{a.profile.name}/ } | |
| 33 | + assert_tag tag: 'meta', attributes: { name: 'twitter:description', content: a.body } | |
| 34 | + assert_no_tag tag: 'meta', attributes: { name: 'twitter:image' } | |
| 35 | + assert_tag tag: 'meta', attributes: { property: 'og:type', content: 'article' } | |
| 36 | + assert_tag tag: 'meta', attributes: { property: 'og:url', content: /\/#{profile.identifier}\/#{a.name.to_slug}/ } | |
| 37 | + assert_tag tag: 'meta', attributes: { property: 'og:title', content: /#{a.name} - #{a.profile.name}/ } | |
| 38 | + assert_tag tag: 'meta', attributes: { property: 'og:site_name', content: a.profile.name } | |
| 39 | + assert_tag tag: 'meta', attributes: { property: 'og:description', content: a.body } | |
| 40 | + assert_no_tag tag: 'meta', attributes: { property: 'og:image' } | |
| 41 | + end | |
| 42 | + | |
| 43 | + should 'add meta tags with article images' do | |
| 44 | + a = TinyMceArticle.create(name: 'Article to be shared with images', body: 'This article should be shared with all social networks <img src="/images/x.png" />', profile: profile) | |
| 45 | + | |
| 46 | + get :view_page, profile: profile.identifier, page: [ a.name.to_slug ] | |
| 47 | + assert_tag tag: 'meta', attributes: { name: 'twitter:image', content: /\/images\/x.png/ } | |
| 48 | + assert_tag tag: 'meta', attributes: { property: 'og:image', content: /\/images\/x.png/ } | |
| 49 | + end | |
| 50 | + | |
| 51 | +end | ... | ... |
test/functional/content_viewer_controller_test.rb
| ... | ... | @@ -1405,30 +1405,6 @@ class ContentViewerControllerTest < ActionController::TestCase |
| 1405 | 1405 | end |
| 1406 | 1406 | end |
| 1407 | 1407 | |
| 1408 | - should 'add meta tags with article info' do | |
| 1409 | - a = TinyMceArticle.create(:name => 'Article to be shared', :body => 'This article should be shared with all social networks', :profile => profile) | |
| 1410 | - | |
| 1411 | - get :view_page, :profile => profile.identifier, :page => [ a.name.to_slug ] | |
| 1412 | - | |
| 1413 | - assert_tag :tag => 'meta', :attributes => { :name => 'twitter:title', :content => /#{a.name} - #{a.profile.name}/ } | |
| 1414 | - assert_tag :tag => 'meta', :attributes => { :name => 'twitter:description', :content => a.body } | |
| 1415 | - assert_no_tag :tag => 'meta', :attributes => { :name => 'twitter:image' } | |
| 1416 | - assert_tag :tag => 'meta', :attributes => { :property => 'og:type', :content => 'article' } | |
| 1417 | - assert_tag :tag => 'meta', :attributes => { :property => 'og:url', :content => /\/#{profile.identifier}\/#{a.name.to_slug}/ } | |
| 1418 | - assert_tag :tag => 'meta', :attributes => { :property => 'og:title', :content => /#{a.name} - #{a.profile.name}/ } | |
| 1419 | - assert_tag :tag => 'meta', :attributes => { :property => 'og:site_name', :content => a.profile.name } | |
| 1420 | - assert_tag :tag => 'meta', :attributes => { :property => 'og:description', :content => a.body } | |
| 1421 | - assert_no_tag :tag => 'meta', :attributes => { :property => 'og:image' } | |
| 1422 | - end | |
| 1423 | - | |
| 1424 | - should 'add meta tags with article images' do | |
| 1425 | - a = TinyMceArticle.create(:name => 'Article to be shared with images', :body => 'This article should be shared with all social networks <img src="/images/x.png" />', :profile => profile) | |
| 1426 | - | |
| 1427 | - get :view_page, :profile => profile.identifier, :page => [ a.name.to_slug ] | |
| 1428 | - assert_tag :tag => 'meta', :attributes => { :name => 'twitter:image', :content => /\/images\/x.png/ } | |
| 1429 | - assert_tag :tag => 'meta', :attributes => { :property => 'og:image', :content => /\/images\/x.png/ } | |
| 1430 | - end | |
| 1431 | - | |
| 1432 | 1408 | should 'manage private article visualization' do |
| 1433 | 1409 | community = Community.create(:name => 'test-community') |
| 1434 | 1410 | community.add_member(@profile) | ... | ... |