Commit a987c1871a4abd51875a320f184b86f4b5a81085
Exists in
theme-brasil-digital-from-staging
and in
9 other branches
Merge branch 'next' into serpro-context
Showing
29 changed files
with
802 additions
and
44 deletions
Show diff stats
... | ... | @@ -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 < 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 < 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 < 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 < 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
app/models/profile.rb
... | ... | @@ -85,7 +85,15 @@ class Profile < 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}) %> | ... | ... |
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 | +} | ... | ... |
... | ... | @@ -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 < 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 < 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 < 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 < 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 < 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 < 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 < 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 | ... | ... |
... | ... | @@ -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 < 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 "../test_helper" |
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 < 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 | ... | ... |