Commit a987c1871a4abd51875a320f184b86f4b5a81085

Authored by Leandro Santos
2 parents 5157f9a7 82193169

Merge branch 'next' into serpro-context

HACKING.themes.md 0 → 100644
... ... @@ -0,0 +1,60 @@
  1 +Noosfero Instructions for Theme Developers
  2 +==========================================
  3 +
  4 +To build Noosfero themes you must to know HTML and CSS. You may also get some advantages with Ruby and Noosfero hacking knowledge because all customizable pieces of the theme's HTML structure are [erb](http://en.wikipedia.org/wiki/ERuby) files.
  5 +
  6 +
  7 +Organization Basics
  8 +-------------------
  9 +
  10 +A theme is a directory and must inside `noosfero/public/designs/themes`, and you will find tis themes in a fresh installation:
  11 +`noosfero`, `aluminium`, `base`, `butter`, `chameleon`, `chocolate`, `orange`, `plum`, `scarletred` and `skyblue`. The `default` is only a link to `noosfero` and you can change this link to any other.
  12 +
  13 +`noosfero` is the default theme with a big header. All other are colored themes with a thin header. That colored ones can be used as additional themes for any environment, as they will search for `/images/thin-logo.png` inside the current environment.theme, to use as top left logo.
  14 +
  15 +Inside a theme we can found:
  16 +* `theme.yml` — Theme description with some nice configuration options.
  17 +* `preview.png` — A 100x100 screenshot of this theme to the theme selection UI.
  18 +* `style.css` — The main file. The magic happens here.
  19 +* `errors.css` — Change the error page look. (only if this theme is linked by `defaut`)
  20 +* `favicon.ico` — The identifier icon for your web site.
  21 +* `images` — Another name can be found by your CSS, but will not allow to reuse the logo.
  22 + * `thin-logo.png` — The logo to be reused by the colored themes.
  23 + * *many images...*
  24 +* `site_title.html.erb` — A nice place to put your logo, any code here will be placed inside `h1#site-title`.
  25 +* `header.html.erb` — That goes inside `div#theme-header`.
  26 +* `navigation.html.erb` — That goes inside `div#navigation ul`, so use `<li>`s.
  27 +* `footer.html.erb` — That goes inside `div#theme-footer`.
  28 +
  29 +You can add more files like javascript and modularized CSS, but you must to refer that by the described files above.
  30 +
  31 +To refer one of this files trough the web the path is `<domain>/designs/themes/<thistheme>/<somefile>`.
  32 +
  33 +
  34 +theme.yml
  35 +---------
  36 +
  37 +A simple definition file. See this example:
  38 +```yml
  39 +name: "My Cool Theme"
  40 +layout: "application-ng"
  41 +jquery_theme: "smoothness"
  42 +icon_theme: [default, pidgin]
  43 +gravatar: "retro"
  44 +```
  45 +
  46 +About non obvious:
  47 +* `layout` is about the theme structure to use. The `application-ng` is enough for 99.97358% use cases. If you want to use another structure, you must add a new `*.html.erb` file at `app/views/layouts/`.
  48 +* `icon_theme` point to something inside `public/designs/icons/`.
  49 +* `gravatar` set the default gravatar *(avatar picture)* for people without picture.
  50 +
  51 +
  52 +Theme Intervention from Environment Theme
  53 +-----------------------------------------
  54 +
  55 +Sometimes an environment (as instace http://cirandas.net) wants to allow profiles to set its own theme, but with some environment identification or functions, like a top bar with the social network logo and a top menu (as instace http://cirandas.net/rango-vegan).
  56 +To make the magic happens you can add some files to the environment theme.
  57 +All are optional:
  58 +* `global.css` — this must be used to style all extra html added by your intervention partials. As it is a free form css file you can style anything, but this is a conflict risk.
  59 +* `global_header.html.erb` — Will add content to `#global-header`.
  60 +* `global_footer.html.erb` — Will add content to `#global-footer`.
... ...
app/controllers/application_controller.rb
... ... @@ -179,6 +179,7 @@ class ApplicationController &lt; ActionController::Base
179 179 include SearchTermHelper
180 180  
181 181 def find_by_contents(asset, context, scope, query, paginate_options={:page => 1}, options={})
  182 + scope = scope.with_templates(options[:template_id]) unless options[:template_id].blank?
182 183 search = plugins.dispatch_first(:find_by_contents, asset, scope, query, paginate_options, options)
183 184 register_search_term(query, scope.count, search[:results].count, context, asset)
184 185 search
... ...
app/controllers/public/search_controller.rb
... ... @@ -9,6 +9,7 @@ class SearchController &lt; PublicController
9 9 before_filter :load_search_assets, :except => :suggestions
10 10 before_filter :load_query, :except => :suggestions
11 11 before_filter :load_order, :except => :suggestions
  12 + before_filter :load_templates, :except => :suggestions
12 13  
13 14 # Backwards compatibility with old URLs
14 15 def redirect_asset_param
... ... @@ -210,6 +211,11 @@ class SearchController &lt; PublicController
210 211 end
211 212 end
212 213  
  214 + def load_templates
  215 + @templates = {}
  216 + @templates[@asset] = environment.send(@asset.to_s).templates if [:people, :enterprises, :communities].include?(@asset)
  217 + end
  218 +
213 219 def limit
214 220 if map_search?(@searches)
215 221 MAP_SEARCH_LIMIT
... ... @@ -230,7 +236,7 @@ class SearchController &lt; PublicController
230 236 end
231 237  
232 238 def full_text_search
233   - @searches[@asset] = find_by_contents(@asset, environment, @scope, @query, paginate_options, {:category => @category, :filter => @order})
  239 + @searches[@asset] = find_by_contents(@asset, environment, @scope, @query, paginate_options, {:category => @category, :filter => @order, :template_id => params[:template_id]})
234 240 end
235 241  
236 242 private
... ...
app/helpers/application_helper.rb
... ... @@ -212,6 +212,7 @@ module ApplicationHelper
212 212 end
213 213  
214 214 def button(type, label, url, html_options = {})
  215 + html_options ||= {}
215 216 the_class = 'with-text'
216 217 if html_options.has_key?(:class)
217 218 the_class << ' ' << html_options[:class]
... ... @@ -398,19 +399,27 @@ module ApplicationHelper
398 399 end
399 400 end
400 401  
401   - def theme_view_file(template)
  402 + def theme_view_file(template, theme=nil)
402 403 # Since we cannot control what people are doing in external themes, we
403 404 # will keep looking for the deprecated .rhtml extension here.
404   - file = Rails.root.join('public', theme_path[1..-1], template + '.html.erb')
  405 + addr = theme ? "designs/themes/#{theme}" : theme_path[1..-1]
  406 + file = Rails.root.join('public', addr, template + '.html.erb')
405 407 return file if File.exists?(file)
406 408 nil
407 409 end
408 410  
409 411 def theme_include(template, options = {})
410   - file = theme_view_file(template)
411   - options.merge!({:file => file, :use_full_path => false})
  412 + from_theme_include(nil, template, options)
  413 + end
  414 +
  415 + def env_theme_include(template, options = {})
  416 + from_theme_include(environment.theme, template, options)
  417 + end
  418 +
  419 + def from_theme_include(theme, template, options = {})
  420 + file = theme_view_file(template, theme)
412 421 if file
413   - render options
  422 + render options.merge(file: file, use_full_path: false)
414 423 else
415 424 nil
416 425 end
... ... @@ -446,6 +455,14 @@ module ApplicationHelper
446 455 @theme_extra_navigation ||= theme_include 'navigation'
447 456 end
448 457  
  458 + def global_header
  459 + @global_header ||= env_theme_include 'global_header'
  460 + end
  461 +
  462 + def global_footer
  463 + @global_footer ||= env_theme_include 'global_footer'
  464 + end
  465 +
449 466 def is_testing_theme
450 467 !controller.session[:theme].nil?
451 468 end
... ...
app/helpers/layout_helper.rb
... ... @@ -49,24 +49,33 @@ module LayoutHelper
49 49 'selectordie',
50 50 'inputosaurus',
51 51 'chat',
  52 + 'selectordie-theme',
52 53 pngfix_stylesheet_path,
53 54 ] + tokeninput_stylesheets
54   - plugins_stylesheets = @plugins.select(&:stylesheet?).map { |plugin| plugin.class.public_path('style.css') }
55   -
56   - output = ''
57   - output += stylesheet_link_tag standard_stylesheets, :cache => 'cache/application'
58   - output += stylesheet_link_tag template_stylesheet_path
59   - output += stylesheet_link_tag icon_theme_stylesheet_path
60   - output += stylesheet_link_tag jquery_ui_theme_stylesheet_path
  55 + plugins_stylesheets = @plugins.select(&:stylesheet?).map { |plugin|
  56 + plugin.class.public_path('style.css')
  57 + }
  58 + global_css_pub = "/designs/themes/#{environment.theme}/global.css"
  59 + global_css_at_fs = Rails.root.join 'public' + global_css_pub
  60 +
  61 + output = []
  62 + output << stylesheet_link_tag(standard_stylesheets, :cache => 'cache/application')
  63 + output << stylesheet_link_tag(template_stylesheet_path)
  64 + output << stylesheet_link_tag(icon_theme_stylesheet_path)
  65 + output << stylesheet_link_tag(jquery_ui_theme_stylesheet_path)
61 66 unless plugins_stylesheets.empty?
62   - output += stylesheet_link_tag plugins_stylesheets, :cache => "cache/plugins-#{Digest::MD5.hexdigest plugins_stylesheets.to_s}"
  67 + cacheid = "cache/plugins-#{Digest::MD5.hexdigest plugins_stylesheets.to_s}"
  68 + output << stylesheet_link_tag(plugins_stylesheets, :cache => cacheid)
63 69 end
64   - output += stylesheet_link_tag theme_stylesheet_path
65   - output
  70 + if File.exists? global_css_at_fs
  71 + output << stylesheet_link_tag(global_css_pub)
  72 + end
  73 + output << stylesheet_link_tag(theme_stylesheet_path)
  74 + output.join "\n"
66 75 end
67 76  
68 77 def pngfix_stylesheet_path
69   - 'iepngfix/iepngfix.css'
  78 + 'iepngfix/iepngfix.css' #TODO: deprecate it
70 79 end
71 80  
72 81 def tokeninput_stylesheets
... ...
app/helpers/plugins_helper.rb
... ... @@ -6,4 +6,11 @@ module PluginsHelper
6 6 end
7 7 end
8 8  
  9 + def plugins_toolbar_actions_for_article(article)
  10 + toolbar_actions = Array.wrap(@plugins.dispatch(:article_extra_toolbar_buttons, article))
  11 + toolbar_actions.each do |action|
  12 + [:title, :url, :icon].each { |param| raise "No #{param} was passed as parameter for #{action}" unless action.has_key?(param) }
  13 + end
  14 + end
  15 +
9 16 end
... ...
app/helpers/search_helper.rb
... ... @@ -148,4 +148,11 @@ module SearchHelper
148 148 link_to(@enabled_searches[asset], "/search/#{asset}")
149 149 end
150 150  
  151 + def assets_submenu(asset)
  152 + return '' if @templates[asset].blank? || @templates[asset].length == 1
  153 + options = @templates[asset].map {|template| [template.name, template.id]}
  154 + options = options_for_select([[_('Choose a template'), nil]] + options, selected: (params[:template_id]))
  155 + select_tag('template_id', options, :id => 'submenu')
  156 + end
  157 +
151 158 end
... ...
app/models/comment.rb
... ... @@ -33,6 +33,8 @@ class Comment &lt; ActiveRecord::Base
33 33 end
34 34 end
35 35  
  36 + acts_as_having_settings
  37 +
36 38 xss_terminate :only => [ :body, :title, :name ], :on => 'validation'
37 39  
38 40 def comment_root
... ...
app/models/profile.rb
... ... @@ -85,7 +85,15 @@ class Profile &lt; ActiveRecord::Base
85 85 #FIXME: these will work only if the subclass is already loaded
86 86 scope :enterprises, lambda { {:conditions => (Enterprise.send(:subclasses).map(&:name) << 'Enterprise').map { |klass| "profiles.type = '#{klass}'"}.join(" OR ")} }
87 87 scope :communities, lambda { {:conditions => (Community.send(:subclasses).map(&:name) << 'Community').map { |klass| "profiles.type = '#{klass}'"}.join(" OR ")} }
88   - scope :templates, {:conditions => {:is_template => true}}
  88 + scope :templates, lambda { |template_id = nil|
  89 + conditions = {:conditions => {:is_template => true}}
  90 + conditions[:conditions].merge!({:id => template_id}) unless template_id.nil?
  91 + conditions
  92 + }
  93 +
  94 + scope :with_templates, lambda { |templates|
  95 + {:conditions => {:template_id => templates}}
  96 + }
89 97 scope :no_templates, {:conditions => {:is_template => false}}
90 98  
91 99 def members
... ...
app/views/content_viewer/_article_toolbar.html.erb
... ... @@ -46,6 +46,10 @@
46 46 <%= button(:clock, _('All versions'), {:controller => 'content_viewer', :profile => profile.identifier, :action => 'article_versions'}, :id => 'article-versions-link') %>
47 47 <% end %>
48 48  
  49 + <% plugins_toolbar_actions_for_article(@page).each do |plugin_button| %>
  50 + <%= button plugin_button[:icon], plugin_button[:title], plugin_button[:url], plugin_button[:html_options] %>
  51 + <% end %>
  52 +
49 53 <%= report_abuse(profile, :link, @page) %>
50 54  
51 55 </div>
... ...
app/views/layouts/application-ng.html.erb
... ... @@ -25,7 +25,7 @@
25 25 end.join("\n")
26 26 %>
27 27  
28   - <script type='text/javascript'>
  28 + <script type="text/javascript">
29 29 DEFAULT_LOADING_MESSAGE = <%="'#{ _('loading...') }'" %>;
30 30 </script>
31 31  
... ... @@ -38,9 +38,12 @@
38 38 if content.respond_to?(:call) then instance_exec(&content).to_s.html_safe else content.to_s.html_safe end
39 39 end.join("\n")
40 40 %>
  41 + <div id="global-header">
  42 + <%= global_header %>
  43 + </div>
41 44  
42 45 <div id="wrap-1">
43   - <div id='theme-header'>
  46 + <div id="theme-header">
44 47 <%= theme_header %>
45 48 </div>
46 49 <div id="wrap-2">
... ... @@ -60,9 +63,14 @@
60 63 </div><!-- end id="wrap-2" -->
61 64 </div><!-- end id="wrap-1" -->
62 65 <%= render_environment_features(:logged_in) if logged_in? %>
63   - <div id="theme-footer">
64   - <%= theme_footer %>
65   - </div><!-- end id="theme-footer" -->
  66 + <div id="footer">
  67 + <div id="theme-footer">
  68 + <%= theme_footer %>
  69 + </div><!-- end id="theme-footer" -->
  70 + <div id="global-footer">
  71 + <%= global_footer %>
  72 + </div><!-- end id="global-footer" -->
  73 + </div><!-- end id="footer" -->
66 74 <%= noosfero_layout_features %>
67 75 <%= addthis_javascript %>
68 76 <%=
... ...
app/views/layouts/application.html.erb
... ... @@ -52,6 +52,9 @@
52 52 registerDocumentSize();
53 53 // -->
54 54 </script>
  55 + <div id="global-header">
  56 + <%= global_header %>
  57 + </div>
55 58  
56 59 <div id="accessibility_menu">
57 60 <a href="#content" id="link_go_content"><span><%= _('Go to content') %></span></a>
... ... @@ -112,8 +115,13 @@
112 115 </div><!-- id="wrap" -->
113 116  
114 117 <div id="footer">
115   - <%= theme_footer %>
116   - </div><!-- id="footer" -->
  118 + <div id="theme-footer">
  119 + <%= theme_footer %>
  120 + </div><!-- end id="theme-footer" -->
  121 + <div id="global-footer">
  122 + <%= global_footer %>
  123 + </div><!-- end id="global-footer" -->
  124 + </div><!-- end id="footer" -->
117 125  
118 126 <%# if you need to add HTML stuff to the layout, include it in
119 127 app/views/shared/noosfero_layout_features.html.erb! %>
... ...
app/views/search/_search_content.html.erb
1 1 <div id='search-content'>
  2 + <div class='total'>
  3 + <%= _('Total of %s results ') % @searches[@asset][:results].total_entries.inspect %>
  4 + </div>
  5 +
2 6 <%= display_results(@searches, @asset) %>
3 7 <% if params[:display] != 'map' %>
4 8 <%= pagination_links @searches[@asset][:results] %>
... ...
app/views/search/_search_form.html.erb
... ... @@ -5,8 +5,12 @@
5 5 <div id='search-header'>
6 6 <%= assets_menu(@asset) %>
7 7 <%= filters(@asset) %>
  8 + <div class="clear"></div>
8 9 </div>
9 10  
  11 + <div id='search-subheader'>
  12 + <%= assets_submenu(@asset) %>
  13 + </div>
10 14 <div class="search-field">
11 15 <span class="formfield">
12 16 <%= search_input_with_suggestions('query', @asset, @query, {:id => 'search-input', :size => 50, :placeholder => hint}) %>
... ...
db/migrate/20150408231524_add_settings_to_comments.rb 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +class AddSettingsToComments < ActiveRecord::Migration
  2 + def change
  3 + add_column :comments, :settings, :text
  4 + end
  5 +end
... ...
lib/noosfero/plugin.rb
... ... @@ -426,6 +426,19 @@ class Noosfero::Plugin
426 426 []
427 427 end
428 428  
  429 + # -> Adds aditional action buttons to article
  430 + # returns = { :title => title, :icon => icon, :url => url, :html_options => {} }
  431 + # title = name that will be displayed.
  432 + # icon = css class name (for customized icons include them in a css file).
  433 + # url = url or route to which the button will redirect.
  434 + # html_options = Html options for customization
  435 + #
  436 + # Multiple values could be passed as parameter.
  437 + # returns = [{:title => title, :icon => icon}, {:title => title, :icon => icon}]
  438 + def article_extra_toolbar_buttons(article)
  439 + []
  440 + end
  441 +
429 442 # -> Adds adicional content to article
430 443 # returns = lambda block that creates html code
431 444 def article_extra_contents(article)
... ... @@ -674,6 +687,8 @@ class Noosfero::Plugin
674 687 # returns = string with reason of expiration
675 688 elsif method.to_s =~ /^content_expire_(#{content_actions.join('|')})$/
676 689 nil
  690 + elsif context.respond_to?(method)
  691 + context.send(method)
677 692 else
678 693 super
679 694 end
... ...
plugins/pg_search/test/functional/search_controller_test.rb 0 → 100644
... ... @@ -0,0 +1,32 @@
  1 +require "test_helper"
  2 +
  3 +class SearchControllerTest < ActionController::TestCase
  4 +
  5 + def setup
  6 + environment = Environment.default
  7 + environment.enable_plugin(PgSearchPlugin)
  8 + end
  9 +
  10 + should 'list all communities' do
  11 + plugin = PgSearchPlugin.new
  12 + c1 = fast_create(Community, :name => 'Testing community 1')
  13 + c2 = fast_create(Community, :name => 'Testing community 3')
  14 + c3 = fast_create(Community, :name => 'Testing community 3')
  15 +
  16 + get :communities
  17 + assert_equivalent [c1, c2, c3], assigns(:searches)[:communities][:results]
  18 + end
  19 +
  20 + should 'list communities of a specific template' do
  21 + plugin = PgSearchPlugin.new
  22 + t1 = fast_create(Community, :is_template => true)
  23 + t2 = fast_create(Community, :is_template => true)
  24 + c1 = fast_create(Community, :template_id => t1.id, :name => 'Testing community 1')
  25 + c2 = fast_create(Community, :template_id => t2.id, :name => 'Testing community 2')
  26 + c3 = fast_create(Community, :template_id => t1.id, :name => 'Testing community 3')
  27 + c4 = fast_create(Community, :name => 'Testing community 3')
  28 +
  29 + get :communities, :template_id => t1.id
  30 + assert_equivalent [c1, c3], assigns(:searches)[:communities][:results]
  31 + end
  32 +end
... ...
public/javascripts/search.js
... ... @@ -15,9 +15,17 @@
15 15 $('form.search_form').submit();
16 16 });
17 17  
  18 + // Filter submenu
  19 + $('#search-subheader select').change(function(){
  20 + $('form.search_form').submit();
  21 + });
  22 +
18 23 // Custom styled select
19 24 $('#search-filters select').selectOrDie();
20 25  
  26 + // Custom styled select
  27 + $('#search-subheader select').selectOrDie();
  28 +
21 29 // Form Ajax submission
22 30 $('form.search_form').submit(function () {
23 31 $.ajax({
... ...
public/stylesheets/application.css
... ... @@ -77,19 +77,6 @@ div#errorExplanation h2 {
77 77 #footer_content {
78 78 clear: both;
79 79 }
80   -#footer {
81   - text-align: center;
82   - clear: both;
83   - font-size: 10px;
84   - color: #777;
85   -}
86   -#footer a {
87   - color: #777;
88   - text-decoration: none;
89   -}
90   -#footer a:hover {
91   - color: #555;
92   -}
93 80 div#profile-disabled {
94 81 border: 2px solid #944;
95 82 text-align: center;
... ...
public/stylesheets/search.css
... ... @@ -953,7 +953,7 @@ ul#assets-menu {
953 953 text-align: justify;
954 954 text-justify: distribute-all-lines; /* distribute items in IE */
955 955 list-style-type: none;
956   - margin: 5px 0 13px;
  956 + margin: 5px 0px 10px 0px;
957 957 padding: 0;
958 958 width: 500px;
959 959 float: left;
... ... @@ -984,6 +984,15 @@ ul#assets-menu li.selected a {
984 984 color: #EF2929;
985 985 font-weight: bold;
986 986 }
  987 +ul#assets-links li.selected a {
  988 + border-bottom: 4px solid #dd4b39;
  989 + padding-bottom: 6px;
  990 +}
  991 +
  992 +ul#assets-links li.selected a {
  993 + color: #dd4b39;
  994 + font-weight: bold;
  995 +}
987 996  
988 997 #search-filters {
989 998 float: right;
... ... @@ -1037,3 +1046,13 @@ ul#assets-menu li.selected a {
1037 1046 border-bottom:1px solid #ccc;
1038 1047 margin-bottom: 10px;
1039 1048 }
  1049 +
  1050 +#search-header{
  1051 + border-bottom: 1px solid #ebebeb;
  1052 +}
  1053 +
  1054 +#search-content .total{
  1055 + color: #808080;
  1056 + line-height: 20px;
  1057 + font-style: oblique;
  1058 +}
... ...
public/stylesheets/selectordie-theme.css 0 → 100644
... ... @@ -0,0 +1,75 @@
  1 +/* Default custom select styles */
  2 +
  3 +#search-subheader div.sod_select {
  4 + display: inline-block;
  5 + vertical-align: middle;
  6 + position: relative;
  7 + text-align: left;
  8 + background: #fff;
  9 + z-index: 100;
  10 + -webkit-touch-callout: none;
  11 + -webkit-user-select: none;
  12 + -khtml-user-select: none;
  13 + -moz-user-select: none;
  14 + -ms-user-select: none;
  15 + user-select: none;
  16 + background: transparent;
  17 + max-width: 400px;
  18 +}
  19 +
  20 +#search-subheader div.sod_select:focus {
  21 + outline: none; /* For better accessibility add a style for this in your skin */
  22 +}
  23 +
  24 +#search-subheader .sod_select select {
  25 + display: none;
  26 +}
  27 +
  28 +#search-subheader .sod_label::after {
  29 + font-family: Arial, 'Liberation Sans', sans-serif;
  30 + font-weight: bold;
  31 + content: '+';
  32 + left: 0px;
  33 + -webkit-transform: translate3d(0,-50%,0) rotate3d(0,0,1,0deg);;
  34 + transform: translate3d(0,-50%,0) rotate3d(0,0,1,0deg);;
  35 + -webkit-transition: -webkit-transform 0.5s;
  36 + transition: transform 0.5s;
  37 + position: absolute;
  38 + top: 50%;
  39 + font-size: 2.1em;
  40 +}
  41 +
  42 +#search-subheader .sod_select.open .sod_label::after {
  43 + -webkit-transform: translate3d(0,-50%,0) rotate3d(0,0,1,225deg);
  44 + transform: translate3d(0,-50%,0) rotate3d(0,0,1,225deg);
  45 +}
  46 +
  47 +/* Changes on select or die*/
  48 +#search-subheader .sod_select{
  49 + border: none;
  50 + padding-top: 10px;
  51 + padding-left: 20px;
  52 + padding-bottom: 10px;
  53 + width: auto;
  54 + font-weight: normal;
  55 + text-transform: none;
  56 + font-size: 12px;
  57 +}
  58 +
  59 +#search-subheader .sod_select.open{
  60 +}
  61 +
  62 +#search-subheader .sod_select .sod_list{
  63 + border: 1px solid #ebebeb;
  64 + margin-left: -1px;
  65 + width: auto;
  66 +}
  67 +
  68 +#search-subheader .sod_select:before,
  69 +#search-subheader .sod_select:after {
  70 + content: "";
  71 +}
  72 +
  73 +#search-subheader .sod_select.focus {
  74 + box-shadow: none;
  75 +}
... ...
test/functional/content_viewer_controller_test.rb
... ... @@ -1436,4 +1436,99 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1436 1436  
1437 1437 assert_no_tag :tag => 'h1', :attributes => { :class => /title/ }, :content => article.name
1438 1438 end
  1439 +
  1440 + should 'add extra toolbar actions on article from plugins' do
  1441 + class Plugin1 < Noosfero::Plugin
  1442 + def article_extra_toolbar_buttons(article)
  1443 + {:title => 'some_title1', :icon => 'some_icon1', :url => {}}
  1444 + end
  1445 + end
  1446 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name])
  1447 +
  1448 + Environment.default.enable_plugin(Plugin1.name)
  1449 +
  1450 + page = profile.articles.create!(:name => 'myarticle', :body => 'the body of the text')
  1451 +
  1452 + get :view_page, :profile => profile.identifier, :page => [ 'myarticle' ]
  1453 + assert_tag :tag => 'div', :attributes => { :id => 'article-actions' }, :descendant => { :tag => 'a', :attributes => { :title => "some_title1" }}
  1454 + end
  1455 +
  1456 + should 'add more than one extra toolbar actions on article from plugins' do
  1457 + class Plugin1 < Noosfero::Plugin
  1458 + def article_extra_toolbar_buttons(article)
  1459 + {:title => 'some_title1', :icon => 'some_icon1', :url => {}}
  1460 + end
  1461 + end
  1462 + class Plugin2 < Noosfero::Plugin
  1463 + def article_extra_toolbar_buttons(article)
  1464 + {:title => 'some_title2', :icon => 'some_icon2', :url => {}}
  1465 + end
  1466 + end
  1467 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
  1468 +
  1469 + Environment.default.enable_plugin(Plugin1.name)
  1470 + Environment.default.enable_plugin(Plugin2.name)
  1471 +
  1472 + page = profile.articles.create!(:name => 'myarticle', :body => 'the body of the text')
  1473 +
  1474 + get :view_page, :profile => profile.identifier, :page => [ 'myarticle' ]
  1475 + assert_tag :tag => 'div', :attributes => { :id => 'article-actions' }, :descendant => { :tag => 'a', :attributes => { :title => "some_title1" }}
  1476 + assert_tag :tag => 'div', :attributes => { :id => 'article-actions' }, :descendant => { :tag => 'a', :attributes => { :title => "some_title2" }}
  1477 + end
  1478 +
  1479 + should 'add icon attribute in extra toolbar actions on article from plugins' do
  1480 + class Plugin1 < Noosfero::Plugin
  1481 + def article_extra_toolbar_buttons(article)
  1482 + {:title => 'some_title', :icon => 'some_icon', :url => {}}
  1483 + end
  1484 + end
  1485 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name])
  1486 +
  1487 + Environment.default.enable_plugin(Plugin1.name)
  1488 +
  1489 + page = profile.articles.create!(:name => 'myarticle', :body => 'the body of the text')
  1490 +
  1491 + get :view_page, :profile => profile.identifier, :page => [ 'myarticle' ]
  1492 + assert_tag :tag => 'div', :attributes => { :id => 'article-actions' }, :descendant => { :tag => 'a', :attributes => { :class => /some_icon/ }}
  1493 + end
  1494 +
  1495 + should 'add url attribute in extra toolbar actions on article from plugins' do
  1496 + class Plugin1 < Noosfero::Plugin
  1497 + def article_extra_toolbar_buttons(article)
  1498 + {:title => 'some_title', :icon => 'some_icon', :url => '/someurl'}
  1499 + end
  1500 + end
  1501 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name])
  1502 +
  1503 + Environment.default.enable_plugin(Plugin1.name)
  1504 +
  1505 + page = profile.articles.create!(:name => 'myarticle', :body => 'the body of the text')
  1506 +
  1507 + get :view_page, :profile => profile.identifier, :page => [ 'myarticle' ]
  1508 + assert_tag :tag => 'div', :attributes => { :id => 'article-actions' }, :descendant => { :tag => 'a', :attributes => { :href => "/someurl" }}
  1509 + end
  1510 +
  1511 + should 'use context method in extra toolbar actions on article from plugins' do
  1512 + class Plugin1 < Noosfero::Plugin
  1513 + def article_extra_toolbar_buttons(article)
  1514 + if current_person.public?
  1515 + {:title => 'some_title', :icon => 'some_icon', :url => '/someurl'}
  1516 + else
  1517 + {:title => 'another_title', :icon => 'another_icon', :url => '/anotherurl'}
  1518 + end
  1519 + end
  1520 + end
  1521 + Noosfero::Plugin.stubs(:all).returns([Plugin1.name])
  1522 +
  1523 + Environment.default.enable_plugin(Plugin1.name)
  1524 +
  1525 + page = profile.articles.create!(:name => 'myarticle', :body => 'the body of the text')
  1526 +
  1527 + profile.public_profile = false
  1528 + profile.save
  1529 + login_as(profile.identifier)
  1530 + get :view_page, :profile => profile.identifier, :page => [ 'myarticle' ]
  1531 + assert_tag :tag => 'div', :attributes => { :id => 'article-actions' }, :descendant => { :tag => 'a', :attributes => { :href => "/anotherurl" }}
  1532 + end
  1533 +
1439 1534 end
... ...
test/functional/search_controller_test.rb
... ... @@ -13,14 +13,14 @@ class SearchControllerTest &lt; ActionController::TestCase
13 13 @request.stubs(:ssl?).returns(false)
14 14 @response = ActionController::TestResponse.new
15 15  
16   - @category = Category.create!(:name => 'my-category', :environment => Environment.default)
  16 + @environment = Environment.default
  17 + @category = Category.create!(:name => 'my-category', :environment => @environment)
17 18  
18   - env = Environment.default
19   - domain = env.domains.first
  19 + domain = @environment.domains.first
20 20 if !domain
21 21 domain = Domain.create!(:name => "127.0.0.1")
22   - env.domains = [domain]
23   - env.save!
  22 + @environment.domains = [domain]
  23 + @environment.save!
24 24 end
25 25 domain.google_maps_key = 'ENVIRONMENT_KEY'
26 26 domain.save!
... ... @@ -37,6 +37,8 @@ class SearchControllerTest &lt; ActionController::TestCase
37 37 Person.any_instance.stubs(:user).returns(user)
38 38 end
39 39  
  40 + attr_reader :environment
  41 +
40 42 def create_article_with_optional_category(name, profile, category = nil)
41 43 fast_create(Article, {:name => name, :profile_id => profile.id }, :search => true, :category => category)
42 44 end
... ... @@ -651,6 +653,122 @@ class SearchControllerTest &lt; ActionController::TestCase
651 653 assert_equal [st1,st2].to_json, response.body
652 654 end
653 655  
  656 + should 'templates variable be an hash in articles asset' do
  657 + get :articles
  658 + assert assigns(:templates).kind_of?(Hash)
  659 + end
  660 +
  661 + should 'not load people templates in articles asset' do
  662 + t1 = fast_create(Person, :is_template => true, :environment_id => environment.id)
  663 + t2 = fast_create(Person, :is_template => true, :environment_id => environment.id)
  664 + get :articles
  665 + assert_nil assigns(:templates)[:people]
  666 + end
  667 +
  668 + should 'not load communities templates in articles asset' do
  669 + t1 = fast_create(Community, :is_template => true, :environment_id => environment.id)
  670 + t2 = fast_create(Community, :is_template => true, :environment_id => environment.id)
  671 + get :articles
  672 + assert_nil assigns(:templates)[:communities]
  673 + end
  674 +
  675 + should 'not load enterprises templates in articles asset' do
  676 + t1 = fast_create(Enterprise, :is_template => true, :environment_id => environment.id)
  677 + t2 = fast_create(Enterprise, :is_template => true, :environment_id => environment.id)
  678 + get :articles
  679 + assert_nil assigns(:templates)[:enterprises]
  680 + end
  681 +
  682 + should 'templates variable be equals to people templates in people assert' do
  683 + t1 = fast_create(Person, :is_template => true, :environment_id => environment.id)
  684 + t2 = fast_create(Person, :is_template => true, :environment_id => environment.id)
  685 + get :people
  686 +
  687 + assert_equivalent [t1,t2], assigns(:templates)[:people]
  688 + end
  689 +
  690 + should 'not load communities templates in people asset' do
  691 + t1 = fast_create(Community, :is_template => true, :environment_id => environment.id)
  692 + t2 = fast_create(Community, :is_template => true, :environment_id => environment.id)
  693 + get :people
  694 + assert_nil assigns(:templates)[:communities]
  695 + end
  696 +
  697 + should 'not load enterprises templates in people asset' do
  698 + t1 = fast_create(Enterprise, :is_template => true, :environment_id => environment.id)
  699 + t2 = fast_create(Enterprise, :is_template => true, :environment_id => environment.id)
  700 + get :people
  701 + assert_nil assigns(:templates)[:enterprises]
  702 + end
  703 +
  704 + should 'templates variable be equals to communities templates in communities assert' do
  705 + t1 = fast_create(Community, :is_template => true, :environment_id => environment.id)
  706 + t2 = fast_create(Community, :is_template => true, :environment_id => environment.id)
  707 + get :communities
  708 +
  709 + assert_equivalent [t1,t2], assigns(:templates)[:communities]
  710 + end
  711 +
  712 + should 'not load people templates in communities asset' do
  713 + t1 = fast_create(Person, :is_template => true, :environment_id => environment.id)
  714 + t2 = fast_create(Person, :is_template => true, :environment_id => environment.id)
  715 + get :communities
  716 + assert_nil assigns(:templates)[:people]
  717 + end
  718 +
  719 + should 'not load enterprises templates in communities asset' do
  720 + t1 = fast_create(Enterprise, :is_template => true, :environment_id => environment.id)
  721 + t2 = fast_create(Enterprise, :is_template => true, :environment_id => environment.id)
  722 + get :communities
  723 + assert_nil assigns(:templates)[:enterprises]
  724 + end
  725 +
  726 + should 'templates variable be equals to enterprises templates in enterprises assert' do
  727 + t1 = fast_create(Enterprise, :is_template => true, :environment_id => environment.id)
  728 + t2 = fast_create(Enterprise, :is_template => true, :environment_id => environment.id)
  729 + get :enterprises
  730 +
  731 + assert_equivalent [t1,t2], assigns(:templates)[:enterprises]
  732 + end
  733 +
  734 + should 'not load communities templates in enterprises asset' do
  735 + t1 = fast_create(Community, :is_template => true, :environment_id => environment.id)
  736 + t2 = fast_create(Community, :is_template => true, :environment_id => environment.id)
  737 + get :enterprises
  738 + assert_nil assigns(:templates)[:communities]
  739 + end
  740 +
  741 + should 'not load people templates in enterprises asset' do
  742 + t1 = fast_create(Person, :is_template => true, :environment_id => environment.id)
  743 + t2 = fast_create(Person, :is_template => true, :environment_id => environment.id)
  744 + get :enterprises
  745 + assert_nil assigns(:templates)[:people]
  746 + end
  747 +
  748 + should 'list all community of on specific template' do
  749 + t1 = fast_create(Community, :is_template => true, :environment_id => environment.id)
  750 + t2 = fast_create(Community, :is_template => true, :environment_id => environment.id)
  751 + c1 = fast_create(Community, :template_id => t1.id, :name => 'Testing community 1', :created_at => DateTime.now - 2)
  752 + c2 = fast_create(Community, :template_id => t2.id, :name => 'Testing community 2', :created_at => DateTime.now - 1)
  753 + c3 = fast_create(Community, :template_id => t1.id, :name => 'Testing community 3')
  754 + c4 = fast_create(Community, :name => 'Testing community 3')
  755 +
  756 + get :communities, :template_id => t1.id
  757 + assert_equivalent [c1,c3] , assigns(:searches)[:communities][:results]
  758 + end
  759 +
  760 + should 'list all communities of no template is passed' do
  761 + t1 = fast_create(Community, :is_template => true, :environment_id => environment.id)
  762 + t2 = fast_create(Community, :is_template => true, :environment_id => environment.id)
  763 + c1 = create(Community, :template_id => t1.id, :name => 'Testing community 1', :created_at => DateTime.now - 2)
  764 + c2 = create(Community, :template_id => t2.id, :name => 'Testing community 2', :created_at => DateTime.now - 1)
  765 + c3 = create(Community, :template_id => t1.id, :name => 'Testing community 3')
  766 + c4 = create(Community, :name => 'Testing community 3')
  767 +
  768 + get :communities, :template_id => nil
  769 + assert_equivalent [t1,t2,c1,c2,c3,c4] , assigns(:searches)[:communities][:results]
  770 + end
  771 +
654 772 protected
655 773  
656 774 def create_event(profile, options)
... ...
test/unit/application_helper_test.rb
... ... @@ -961,6 +961,47 @@ class ApplicationHelperTest &lt; ActionView::TestCase
961 961 assert_equal '', manage_communities
962 962 end
963 963  
  964 + should 'include file from current theme out of a profile page' do
  965 + def profile; nil; end
  966 + def environment; e={}; def e.theme; 'env-theme'; end; e; end
  967 + def render(opt); opt; end
  968 + File.stubs(:exists?).returns(false)
  969 + file = Rails.root.join 'public/designs/themes/env-theme/somefile.html.erb'
  970 + assert_nil theme_include('somefile') # exists? = false
  971 + File.expects(:exists?).with(file).returns(true).at_least_once
  972 + assert_equal file, theme_include('somefile')[:file] # exists? = true
  973 + end
  974 +
  975 + should 'include file from current theme inside a profile page' do
  976 + def profile; p={}; def p.theme; 'my-theme'; end; p; end
  977 + def render(opt); opt; end
  978 + File.stubs(:exists?).returns(false)
  979 + file = Rails.root.join 'public/designs/themes/my-theme/otherfile.html.erb'
  980 + assert_nil theme_include('otherfile') # exists? = false
  981 + File.expects(:exists?).with(file).returns(true).at_least_once
  982 + assert_equal file, theme_include('otherfile')[:file] # exists? = true
  983 + end
  984 +
  985 + should 'include file from env theme' do
  986 + def profile; p={}; def p.theme; 'my-theme'; end; p; end
  987 + def environment; e={}; def e.theme; 'env-theme'; end; e; end
  988 + def render(opt); opt; end
  989 + File.stubs(:exists?).returns(false)
  990 + file = Rails.root.join 'public/designs/themes/env-theme/afile.html.erb'
  991 + assert_nil env_theme_include('afile') # exists? = false
  992 + File.expects(:exists?).with(file).returns(true).at_least_once
  993 + assert_equal file, env_theme_include('afile')[:file] # exists? = true
  994 + end
  995 +
  996 + should 'include file from some theme' do
  997 + def render(opt); opt; end
  998 + File.stubs(:exists?).returns(false)
  999 + file = Rails.root.join 'public/designs/themes/atheme/afile.html.erb'
  1000 + assert_nil from_theme_include('atheme', 'afile') # exists? = false
  1001 + File.expects(:exists?).with(file).returns(true).at_least_once
  1002 + assert_equal file, from_theme_include('atheme', 'afile')[:file] # exists? = true
  1003 + end
  1004 +
964 1005 protected
965 1006 include NoosferoTestHelper
966 1007  
... ...
test/unit/layout_helper_test.rb
1 1 require_relative "../test_helper"
2 2  
3 3 class LayoutHelperTest < ActionView::TestCase
  4 + include ApplicationHelper
4 5  
5 6 should 'append logged-in class in body when user is logged-in' do
6 7 expects(:logged_in?).returns(true)
... ... @@ -14,4 +15,19 @@ class LayoutHelperTest &lt; ActionView::TestCase
14 15 assert_not_includes body_classes.split, 'logged-in'
15 16 end
16 17  
  18 + should 'add global.css to noosfero_stylesheets if env theme has it' do
  19 + env = fast_create Environment
  20 + env.theme = 'my-theme'
  21 + @plugins = []
  22 + expects(:profile).returns(nil).at_least_once
  23 + expects(:environment).returns(env).at_least_once
  24 + expects(:theme_option).with(:icon_theme).returns(['my-icons']).at_least_once
  25 + expects(:jquery_theme).returns('jquery-nice').at_least_once
  26 + global_css = Rails.root.join "public/designs/themes/#{env.theme}/global.css"
  27 + File.stubs(:exists?).returns(false)
  28 + File.expects(:exists?).with(global_css).returns(true).at_least_once
  29 + css = noosfero_stylesheets
  30 + assert_match /<link [^<]*href="\/designs\/themes\/my-theme\/global.css"/, css
  31 + end
  32 +
17 33 end
... ...
test/unit/plugin_test.rb
... ... @@ -560,4 +560,11 @@ class PluginTest &lt; ActiveSupport::TestCase
560 560 assert_equivalent [st4.term, st2.term], limited_suggestions
561 561 end
562 562  
  563 + should 'article_extra_toolbar_buttons return an empty array by default' do
  564 + class Plugin1 < Noosfero::Plugin
  565 + end
  566 + p = Plugin1.new
  567 + assert_equal [], p.article_extra_toolbar_buttons(nil)
  568 + end
  569 +
563 570 end
... ...
test/unit/plugins_helper_test.rb 0 → 100644
... ... @@ -0,0 +1,47 @@
  1 +require_relative "../test_helper"
  2 +
  3 +class PluginsHelperTest < ActionView::TestCase
  4 +
  5 + def setup
  6 + @environment = Environment.default
  7 + @plugins = mock
  8 + end
  9 +
  10 + attr_accessor :environment, :plugins
  11 +
  12 + should 'plugins_toolbar_actions_for_article return an array if the plugin return a single hash' do
  13 + hash = {:title => 'some title', :url => 'some_url', :icon => 'some icon'}
  14 + plugins.expects(:dispatch).with(:article_extra_toolbar_buttons, nil).returns(hash)
  15 + assert_equal [hash], plugins_toolbar_actions_for_article(nil)
  16 + end
  17 +
  18 + should 'plugins_toolbar_actions_for_article return an empty array if an array is passed as parameter' do
  19 + plugins.expects(:dispatch).with(:article_extra_toolbar_buttons, nil).returns([])
  20 + assert_equal [], plugins_toolbar_actions_for_article(nil)
  21 + end
  22 +
  23 + should 'plugins_toolbar_actions_for_article throw raise if no title is passed as parameter' do
  24 + plugins.expects(:dispatch).with(:article_extra_toolbar_buttons, nil).returns({:url => 'some_url', :icon => 'some icon'})
  25 +
  26 + assert_raise(RuntimeError) do
  27 + plugins_toolbar_actions_for_article(nil)
  28 + end
  29 + end
  30 +
  31 + should 'plugins_toolbar_actions_for_article throw raise if no icon is passed as parameter' do
  32 + plugins.expects(:dispatch).with(:article_extra_toolbar_buttons, nil).returns({:title => 'some title', :url => 'some_url'})
  33 +
  34 + assert_raise(RuntimeError) do
  35 + plugins_toolbar_actions_for_article(nil)
  36 + end
  37 + end
  38 +
  39 + should 'plugins_toolbar_actions_for_article throw raise if no url is passed as parameter' do
  40 + plugins.expects(:dispatch).with(:article_extra_toolbar_buttons, nil).returns({:title => 'some title', :icon => 'some icon'})
  41 +
  42 + assert_raise(RuntimeError) do
  43 + plugins_toolbar_actions_for_article(nil)
  44 + end
  45 + end
  46 +
  47 +end
... ...
test/unit/profile_test.rb
... ... @@ -1416,6 +1416,71 @@ class ProfileTest &lt; ActiveSupport::TestCase
1416 1416 assert_not_includes environment.profiles.templates, profile
1417 1417 end
1418 1418  
  1419 + should 'return an specific template when specified' do
  1420 + environment = Environment.default
  1421 + t1 = fast_create(Profile, :is_template => true)
  1422 + t2 = fast_create(Profile, :is_template => true)
  1423 + profile = fast_create(Profile)
  1424 +
  1425 + assert_equal [t1], environment.profiles.templates(t1)
  1426 + assert_equal [t2], environment.profiles.templates(t2)
  1427 + end
  1428 +
  1429 + should 'not return a template when and invalid template is specified' do
  1430 + environment = Environment.default
  1431 + t1 = fast_create(Profile, :is_template => true)
  1432 + t2 = fast_create(Profile, :is_template => true)
  1433 + t3 = fast_create(Profile)
  1434 +
  1435 + assert_equal [], environment.profiles.templates(t3)
  1436 + end
  1437 +
  1438 + should 'return profiles of specified template passing object' do
  1439 + environment = Environment.default
  1440 + t1 = fast_create(Profile, :is_template => true)
  1441 + t2 = fast_create(Profile, :is_template => true)
  1442 + p1 = fast_create(Profile, :template_id => t1.id)
  1443 + p2 = fast_create(Profile, :template_id => t2.id)
  1444 + p3 = fast_create(Profile, :template_id => t1.id)
  1445 +
  1446 + assert_equivalent [p1,p3], environment.profiles.with_templates(t1)
  1447 + end
  1448 +
  1449 + should 'return profiles of specified template passing id' do
  1450 + environment = Environment.default
  1451 + t1 = fast_create(Profile, :is_template => true)
  1452 + t2 = fast_create(Profile, :is_template => true)
  1453 + p1 = fast_create(Profile, :template_id => t1.id)
  1454 + p2 = fast_create(Profile, :template_id => t2.id)
  1455 + p3 = fast_create(Profile, :template_id => t1.id)
  1456 +
  1457 + assert_equivalent [p1,p3], environment.profiles.with_templates(t1.id)
  1458 + end
  1459 +
  1460 + should 'return profiles of a list of specified templates' do
  1461 + environment = Environment.default
  1462 + t1 = fast_create(Profile, :is_template => true)
  1463 + t2 = fast_create(Profile, :is_template => true)
  1464 + t3 = fast_create(Profile, :is_template => true)
  1465 + p1 = fast_create(Profile, :template_id => t1.id)
  1466 + p2 = fast_create(Profile, :template_id => t2.id)
  1467 + p3 = fast_create(Profile, :template_id => t3.id)
  1468 +
  1469 + assert_equivalent [p1,p2], environment.profiles.with_templates([t1,t2])
  1470 + end
  1471 +
  1472 + should 'return all profiles without any template if nil is passed as parameter' do
  1473 + environment = Environment.default
  1474 + Profile.delete_all
  1475 + t1 = fast_create(Profile, :is_template => true)
  1476 + t2 = fast_create(Profile, :is_template => true)
  1477 + p1 = fast_create(Profile, :template_id => t1.id)
  1478 + p2 = fast_create(Profile, :template_id => t2.id)
  1479 + p3 = fast_create(Profile)
  1480 +
  1481 + assert_equivalent [t1,t2,p3], environment.profiles.with_templates(nil)
  1482 + end
  1483 +
1419 1484 should 'return a list of profiles that are not templates' do
1420 1485 environment = Environment.default
1421 1486 p1 = fast_create(Profile, :is_template => false)
... ...
test/unit/search_helper_test.rb
... ... @@ -3,6 +3,9 @@ require_relative &quot;../test_helper&quot;
3 3 class SearchHelperTest < ActiveSupport::TestCase
4 4  
5 5 include SearchHelper
  6 + include ActionView::Helpers::FormOptionsHelper
  7 + include ActionView::Helpers::FormTagHelper
  8 +
6 9  
7 10 should 'return whether on a multiple search' do
8 11 stubs(:params).returns({:action => 'index', :display => 'map'})
... ... @@ -122,4 +125,84 @@ class SearchHelperTest &lt; ActiveSupport::TestCase
122 125 end
123 126 end
124 127  
  128 + should 'return an empty string in assets_submenu for articles assets' do
  129 + @templates = {}
  130 + assert_equal '', assets_submenu(:articles)
  131 + @templates = {:articles => nil}
  132 + assert_equal '', assets_submenu(:articles)
  133 + end
  134 +
  135 + should 'return an empty string in assets_submenu for people asset without template' do
  136 + @templates = {:people => nil}
  137 + assert_equal '', assets_submenu(:people)
  138 +
  139 + @templates = {:people => []}
  140 + assert_equal '', assets_submenu(:people)
  141 + end
  142 +
  143 + should 'return an empty string in assets_submenu for people asset with only one template' do
  144 + t = fast_create(Person, :is_template => true)
  145 + @templates = {:people => [t]}
  146 + assert_equal '', assets_submenu(:people)
  147 + end
  148 +
  149 + should 'return a select of templates for people asset with more then one template' do
  150 + t1 = fast_create(Person, :is_template => true)
  151 + t2 = fast_create(Person, :is_template => true)
  152 + @templates = {:people => [t1,t2]}
  153 + SearchHelperTest.any_instance.stubs(:params).returns({})
  154 + assert_match /select/, assets_submenu(:people)
  155 + assert_match /#{t1.name}/, assets_submenu(:people)
  156 + assert_match /#{t2.name}/, assets_submenu(:people)
  157 + end
  158 +
  159 + should 'return an empty string in assets_submenu for communities asset without template' do
  160 + @templates = {:communities => nil}
  161 + assert_equal '', assets_submenu(:communities)
  162 +
  163 + @templates = {:communities => []}
  164 + assert_equal '', assets_submenu(:communities)
  165 + end
  166 +
  167 + should 'return an empty string in assets_submenu for communities asset with only one template' do
  168 + t = fast_create(Community, :is_template => true)
  169 + @templates = {:communities => [t]}
  170 + assert_equal '', assets_submenu(:communities)
  171 + end
  172 +
  173 + should 'return a select of templates for communities asset with more then one template' do
  174 + t1 = fast_create(Community, :is_template => true)
  175 + t2 = fast_create(Community, :is_template => true)
  176 + @templates = {:communities => [t1,t2]}
  177 + SearchHelperTest.any_instance.stubs(:params).returns({})
  178 + assert_match /select/, assets_submenu(:communities)
  179 + assert_match /#{t1.name}/, assets_submenu(:communities)
  180 + assert_match /#{t2.name}/, assets_submenu(:communities)
  181 + end
  182 +
  183 + should 'return an empty string in assets_submenu for enterprises asset without template' do
  184 + @templates = {:enterprises => nil}
  185 + assert_equal '', assets_submenu(:enterprises)
  186 +
  187 + @templates = {:enterprises => []}
  188 + assert_equal '', assets_submenu(:enterprises)
  189 + end
  190 +
  191 + should 'return an empty string in assets_submenu for enterprises asset with only one template' do
  192 + t = fast_create(Enterprise, :is_template => true)
  193 + @templates = {:enterprises => [t]}
  194 + assert_equal '', assets_submenu(:enterprises)
  195 + end
  196 +
  197 + should 'return a select of templates for enterprises asset with more then one template' do
  198 + t1 = fast_create(Enterprise, :is_template => true)
  199 + t2 = fast_create(Enterprise, :is_template => true)
  200 + @templates = {:enterprises => [t1,t2]}
  201 + SearchHelperTest.any_instance.stubs(:params).returns({})
  202 + assert_match /select/, assets_submenu(:enterprises)
  203 + assert_match /#{t1.name}/, assets_submenu(:enterprises)
  204 + assert_match /#{t2.name}/, assets_submenu(:enterprises)
  205 + end
  206 +
  207 +
125 208 end
... ...