Commit cc81e07501b41177911bd389ce1bba503e1bd206
Exists in
staging
and in
4 other branches
merging with master
Showing
136 changed files
with
2164 additions
and
423 deletions
Show diff stats
AUTHORS.md
@@ -92,6 +92,7 @@ Daniel Alves + Rafael Manzo <rr.manzo@gmail.com> | @@ -92,6 +92,7 @@ Daniel Alves + Rafael Manzo <rr.manzo@gmail.com> | ||
92 | Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> | 92 | Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> |
93 | Daniel Bucher <daniel.bucher88@gmail.com> | 93 | Daniel Bucher <daniel.bucher88@gmail.com> |
94 | Daniel Cunha <daniel@colivre.coop.br> | 94 | Daniel Cunha <daniel@colivre.coop.br> |
95 | +daniel <dtygel@eita.org.br> | ||
95 | David Carlos <ddavidcarlos1392@gmail.com> | 96 | David Carlos <ddavidcarlos1392@gmail.com> |
96 | diegoamc <diegoamc90@gmail.com> | 97 | diegoamc <diegoamc90@gmail.com> |
97 | Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com> | 98 | Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com> |
@@ -120,6 +121,7 @@ Diego Araujo + Rodrigo Souto + Rafael Manzo <rr.manzo@gmail.com> | @@ -120,6 +121,7 @@ Diego Araujo + Rodrigo Souto + Rafael Manzo <rr.manzo@gmail.com> | ||
120 | Diego + Jefferson <diegoamc90@gmail.com> | 121 | Diego + Jefferson <diegoamc90@gmail.com> |
121 | Diego Martinez <diegoamc90@gmail.com> | 122 | Diego Martinez <diegoamc90@gmail.com> |
122 | Diego + Renan <renanteruoc@gmail.com> | 123 | Diego + Renan <renanteruoc@gmail.com> |
124 | +dtygel <dtygel@gmail.com> | ||
123 | DylanGuedes <djmgguedes@gmail.com> | 125 | DylanGuedes <djmgguedes@gmail.com> |
124 | Eduardo Passos <eduardo@risa.localdomain.localhost> | 126 | Eduardo Passos <eduardo@risa.localdomain.localhost> |
125 | Eduardo Passos <eduardosteps@gmail.com> | 127 | Eduardo Passos <eduardosteps@gmail.com> |
@@ -144,6 +146,7 @@ Italo Valcy <italo@dcc.ufba.br> | @@ -144,6 +146,7 @@ Italo Valcy <italo@dcc.ufba.br> | ||
144 | Jefferson Fernandes + Diego Araujo + Rafael Manzo <jeffs.fernandes@gmail.com> | 146 | Jefferson Fernandes + Diego Araujo + Rafael Manzo <jeffs.fernandes@gmail.com> |
145 | Jefferson Fernandes + Joao M. M. da Silva <jeffs.fernandes@gmail.com> | 147 | Jefferson Fernandes + Joao M. M. da Silva <jeffs.fernandes@gmail.com> |
146 | Jefferson Fernandes + Joao M. M. Silva <jeffs.fernandes@gmail.com> | 148 | Jefferson Fernandes + Joao M. M. Silva <jeffs.fernandes@gmail.com> |
149 | +Jérôme Jutteau <j.jutteau@gmail.com> | ||
147 | João da Silva + Eduardo Morais + Rafael Manzo <rr.manzo@gmail.com> | 150 | João da Silva + Eduardo Morais + Rafael Manzo <rr.manzo@gmail.com> |
148 | João da Silva <jaodsilv@linux.ime.usp.br> | 151 | João da Silva <jaodsilv@linux.ime.usp.br> |
149 | João Marco Maciel da Silva + Rafael Manzo + Renan Teruo <jaodsilv@linux.ime.usp.br> | 152 | João Marco Maciel da Silva + Rafael Manzo + Renan Teruo <jaodsilv@linux.ime.usp.br> |
@@ -247,8 +250,10 @@ Tallys Martins <tallysmartins@gmail.com> | @@ -247,8 +250,10 @@ Tallys Martins <tallysmartins@gmail.com> | ||
247 | Tallys Martins <tallysmartins@yahoo.com.br> | 250 | Tallys Martins <tallysmartins@yahoo.com.br> |
248 | tallys <tallys@tallys> | 251 | tallys <tallys@tallys> |
249 | tallys <tallys@tallys.(none)> | 252 | tallys <tallys@tallys.(none)> |
253 | +Thiago Casotti <thiago.casotti@uol.com.br> | ||
250 | Thiago Zoroastro <thiago.zoroastro@bol.com.br> | 254 | Thiago Zoroastro <thiago.zoroastro@bol.com.br> |
251 | Tuux <tuxa@galaxie.eu.org> | 255 | Tuux <tuxa@galaxie.eu.org> |
256 | +TWS <tablettws@gmail.com> | ||
252 | Valessio Brito <contato@valessiobrito.com.br> | 257 | Valessio Brito <contato@valessiobrito.com.br> |
253 | Valessio Brito <contato@valessiobrito.info> | 258 | Valessio Brito <contato@valessiobrito.info> |
254 | Valessio Brito <valessio@gmail.com> | 259 | Valessio Brito <valessio@gmail.com> |
Gemfile
@@ -20,18 +20,17 @@ gem 'locale', '~> 2.0.5' | @@ -20,18 +20,17 @@ gem 'locale', '~> 2.0.5' | ||
20 | gem 'whenever', :require => false | 20 | gem 'whenever', :require => false |
21 | gem 'eita-jrails', '>= 0.9.5', :require => 'jrails' | 21 | gem 'eita-jrails', '>= 0.9.5', :require => 'jrails' |
22 | 22 | ||
23 | -group :assets do | ||
24 | - gem 'uglifier', '>= 1.0.3' | ||
25 | - gem 'sass-rails' | ||
26 | -end | 23 | +# asset pipeline |
24 | +gem 'uglifier', '>= 1.0.3' | ||
25 | +gem 'sass-rails' | ||
27 | 26 | ||
28 | group :production do | 27 | group :production do |
29 | gem 'dalli', '~> 2.7.0' | 28 | gem 'dalli', '~> 2.7.0' |
30 | end | 29 | end |
31 | 30 | ||
32 | group :test do | 31 | group :test do |
33 | - gem 'rspec', '~> 2.10.0' | ||
34 | - gem 'rspec-rails', '~> 2.10.1' | 32 | + gem 'rspec', '~> 2.14.0' |
33 | + gem 'rspec-rails', '~> 2.14.1' | ||
35 | gem 'mocha', '~> 1.1.0', :require => false | 34 | gem 'mocha', '~> 1.1.0', :require => false |
36 | end | 35 | end |
37 | 36 |
app/controllers/admin/role_controller.rb
@@ -2,7 +2,7 @@ class RoleController < AdminController | @@ -2,7 +2,7 @@ class RoleController < AdminController | ||
2 | protect 'manage_environment_roles', :environment | 2 | protect 'manage_environment_roles', :environment |
3 | 3 | ||
4 | def index | 4 | def index |
5 | - @roles = environment.roles.find(:all) | 5 | + @roles = environment.roles.find(:all, :conditions => {:profile_id => nil}) |
6 | end | 6 | end |
7 | 7 | ||
8 | def new | 8 | def new |
app/controllers/application_controller.rb
@@ -9,6 +9,7 @@ class ApplicationController < ActionController::Base | @@ -9,6 +9,7 @@ class ApplicationController < ActionController::Base | ||
9 | before_filter :allow_cross_domain_access | 9 | before_filter :allow_cross_domain_access |
10 | before_filter :login_required, :if => :private_environment? | 10 | before_filter :login_required, :if => :private_environment? |
11 | before_filter :verify_members_whitelist, :if => [:private_environment?, :user] | 11 | before_filter :verify_members_whitelist, :if => [:private_environment?, :user] |
12 | + before_filter :redirect_to_current_user | ||
12 | 13 | ||
13 | def verify_members_whitelist | 14 | def verify_members_whitelist |
14 | render_access_denied unless user.is_admin? || environment.in_whitelist?(user) | 15 | render_access_denied unless user.is_admin? || environment.in_whitelist?(user) |
@@ -192,4 +193,15 @@ class ApplicationController < ActionController::Base | @@ -192,4 +193,15 @@ class ApplicationController < ActionController::Base | ||
192 | def private_environment? | 193 | def private_environment? |
193 | @environment.enabled?(:restrict_to_members) | 194 | @environment.enabled?(:restrict_to_members) |
194 | end | 195 | end |
196 | + | ||
197 | + def redirect_to_current_user | ||
198 | + if params[:profile] == '~' | ||
199 | + if logged_in? | ||
200 | + redirect_to params.merge(:profile => user.identifier) | ||
201 | + else | ||
202 | + render_not_found | ||
203 | + end | ||
204 | + end | ||
205 | + end | ||
206 | + | ||
195 | end | 207 | end |
app/controllers/my_profile/cms_controller.rb
@@ -357,7 +357,8 @@ class CmsController < MyProfileController | @@ -357,7 +357,8 @@ class CmsController < MyProfileController | ||
357 | @task.ip_address = request.remote_ip | 357 | @task.ip_address = request.remote_ip |
358 | @task.user_agent = request.user_agent | 358 | @task.user_agent = request.user_agent |
359 | @task.referrer = request.referrer | 359 | @task.referrer = request.referrer |
360 | - if verify_recaptcha(:model => @task, :message => _('Please type the words correctly')) && @task.save | 360 | + @task.requestor = current_person if logged_in? |
361 | + if (logged_in? || verify_recaptcha(:model => @task, :message => _('Please type the words correctly'))) && @task.save | ||
361 | session[:notice] = _('Thanks for your suggestion. The community administrators were notified.') | 362 | session[:notice] = _('Thanks for your suggestion. The community administrators were notified.') |
362 | redirect_to @back_to | 363 | redirect_to @back_to |
363 | end | 364 | end |
app/controllers/my_profile/profile_design_controller.rb
@@ -4,11 +4,19 @@ class ProfileDesignController < BoxOrganizerController | @@ -4,11 +4,19 @@ class ProfileDesignController < BoxOrganizerController | ||
4 | 4 | ||
5 | protect 'edit_profile_design', :profile | 5 | protect 'edit_profile_design', :profile |
6 | 6 | ||
7 | - before_filter :protect_fixed_block, :only => [:save, :move_block] | 7 | + before_filter :protect_uneditable_block, :only => [:save] |
8 | + before_filter :protect_fixed_block, :only => [:move_block] | ||
9 | + | ||
10 | + def protect_uneditable_block | ||
11 | + block = boxes_holder.blocks.find(params[:id].gsub(/^block-/, '')) | ||
12 | + if !current_person.is_admin? && !block.editable? | ||
13 | + render_access_denied | ||
14 | + end | ||
15 | + end | ||
8 | 16 | ||
9 | def protect_fixed_block | 17 | def protect_fixed_block |
10 | block = boxes_holder.blocks.find(params[:id].gsub(/^block-/, '')) | 18 | block = boxes_holder.blocks.find(params[:id].gsub(/^block-/, '')) |
11 | - if block.fixed && !current_person.is_admin? | 19 | + if !current_person.is_admin? && !block.movable? |
12 | render_access_denied | 20 | render_access_denied |
13 | end | 21 | end |
14 | end | 22 | end |
app/controllers/my_profile/profile_members_controller.rb
@@ -58,6 +58,7 @@ class ProfileMembersController < MyProfileController | @@ -58,6 +58,7 @@ class ProfileMembersController < MyProfileController | ||
58 | 58 | ||
59 | def change_role | 59 | def change_role |
60 | @roles = Profile::Roles.organization_member_roles(environment.id) | 60 | @roles = Profile::Roles.organization_member_roles(environment.id) |
61 | + @custom_roles = profile.custom_roles | ||
61 | begin | 62 | begin |
62 | @member = profile.members.find(params[:id]) | 63 | @member = profile.members.find(params[:id]) |
63 | rescue ActiveRecord::RecordNotFound | 64 | rescue ActiveRecord::RecordNotFound |
@@ -0,0 +1,116 @@ | @@ -0,0 +1,116 @@ | ||
1 | +class ProfileRolesController < MyProfileController | ||
2 | + | ||
3 | + protect 'manage_custom_roles', :profile | ||
4 | + | ||
5 | + def index | ||
6 | + @roles = profile.custom_roles | ||
7 | + end | ||
8 | + | ||
9 | + def new | ||
10 | + @role = Role.new | ||
11 | + end | ||
12 | + | ||
13 | + def create | ||
14 | + @role = Role.new({:name => params[:role][:name], :permissions => params[:role][:permissions], :environment => environment }, :without_protection => true) | ||
15 | + if @role.save | ||
16 | + profile.custom_roles << @role | ||
17 | + redirect_to :action => 'show', :id => @role | ||
18 | + else | ||
19 | + session[:notice] = _('Failed to create role') | ||
20 | + render :action => 'new' | ||
21 | + end | ||
22 | + end | ||
23 | + | ||
24 | + def show | ||
25 | + @role = environment.roles.find(params[:id]) | ||
26 | + end | ||
27 | + | ||
28 | + def edit | ||
29 | + @role = environment.roles.find(params[:id]) | ||
30 | + end | ||
31 | + | ||
32 | + def assign_role_by_members | ||
33 | + return redirect_to "/" if params[:q].nil? or !request.xhr? | ||
34 | + arg = params[:q].downcase | ||
35 | + result = find_by_contents(:people, environment, profile.members, params[:q])[:results] | ||
36 | + render :text => prepare_to_token_input(result).to_json | ||
37 | + end | ||
38 | + | ||
39 | + def destroy | ||
40 | + @role = environment.roles.find(params[:id]) | ||
41 | + @members = profile.members_by_role(@role) | ||
42 | + @roles_list = all_roles(environment, profile) | ||
43 | + @roles_list.delete(@role) | ||
44 | + end | ||
45 | + | ||
46 | + def remove | ||
47 | + @role = environment.roles.find(params[:id]) | ||
48 | + @members = profile.members_by_role(@role) | ||
49 | + member_roles = params[:roles] ? environment.roles.find(params[:roles].select{|r|!r.to_i.zero?}) : [] | ||
50 | + append_roles(@members, member_roles, profile) | ||
51 | + if @role.destroy | ||
52 | + session[:notice] = _('Role successfuly removed!') | ||
53 | + else | ||
54 | + session[:notice] = _('Failed to remove role!') | ||
55 | + end | ||
56 | + redirect_to :action => 'index' | ||
57 | + end | ||
58 | + | ||
59 | + def update | ||
60 | + @role = environment.roles.find(params[:id]) | ||
61 | + if @role.update_attributes(params[:role]) | ||
62 | + redirect_to :action => 'show', :id => @role | ||
63 | + else | ||
64 | + session[:notice] = _('Failed to edit role') | ||
65 | + render :action => 'edit' | ||
66 | + end | ||
67 | + end | ||
68 | + | ||
69 | + def assign | ||
70 | + @role = environment.roles.find(params[:id]) | ||
71 | + @roles_list = all_roles(environment, profile) | ||
72 | + @roles_list.delete(@role) | ||
73 | + end | ||
74 | + | ||
75 | + def define | ||
76 | + @role = environment.roles.find(params[:id]) | ||
77 | + selected_role = params[:selected_role] ? environment.roles.find(params[:selected_role].to_i) : nil | ||
78 | + if params[:assign_role_by].eql? "members" | ||
79 | + members_list = params[:person_id].split(',').collect {|id| environment.profiles.find(id.to_i)} | ||
80 | + members_list.collect{|person| person.add_role(@role, profile)} | ||
81 | + elsif params[:assign_role_by].eql? "roles" | ||
82 | + members = profile.members_by_role(selected_role) | ||
83 | + replace_role(members, selected_role, @role, profile) | ||
84 | + else | ||
85 | + session[:notice] = _("Error") | ||
86 | + end | ||
87 | + redirect_to :action => 'index' | ||
88 | + end | ||
89 | + | ||
90 | + protected | ||
91 | + | ||
92 | + def append_roles(members, roles, profile) | ||
93 | + members.each do |person| | ||
94 | + all_roles = person.find_roles(profile).map(&:role) + roles | ||
95 | + person.define_roles(all_roles, profile) | ||
96 | + end | ||
97 | + end | ||
98 | + | ||
99 | + def all_roles(environment, profile) | ||
100 | + Profile::Roles.organization_member_roles(environment.id) + profile.custom_roles | ||
101 | + end | ||
102 | + | ||
103 | + def replace_roles(members, roles, profile) | ||
104 | + members.each do |person| | ||
105 | + person.define_roles(roles, profile) | ||
106 | + end | ||
107 | + end | ||
108 | + | ||
109 | + def replace_role(members, role, new_role, profile) | ||
110 | + members.each do |person| | ||
111 | + person.remove_role(role, profile) | ||
112 | + person.add_role(new_role, profile) | ||
113 | + end | ||
114 | + end | ||
115 | + | ||
116 | +end |
app/helpers/application_helper.rb
@@ -707,6 +707,24 @@ module ApplicationHelper | @@ -707,6 +707,24 @@ module ApplicationHelper | ||
707 | javascript_include_tag script if script | 707 | javascript_include_tag script if script |
708 | end | 708 | end |
709 | 709 | ||
710 | + def template_path | ||
711 | + if profile.nil? | ||
712 | + "/designs/templates/#{environment.layout_template}" | ||
713 | + else | ||
714 | + "/designs/templates/#{profile.layout_template}" | ||
715 | + end | ||
716 | + end | ||
717 | + | ||
718 | + def template_javascript_src | ||
719 | + script = File.join template_path, '/javascripts/template.js' | ||
720 | + script if File.exists? File.join(Rails.root, 'public', script) | ||
721 | + end | ||
722 | + | ||
723 | + def templete_javascript_ng | ||
724 | + script = template_javascript_src | ||
725 | + javascript_include_tag script if script | ||
726 | + end | ||
727 | + | ||
710 | def file_field_or_thumbnail(label, image, i) | 728 | def file_field_or_thumbnail(label, image, i) |
711 | display_form_field label, ( | 729 | display_form_field label, ( |
712 | render :partial => (image && image.valid? ? 'shared/show_thumbnail' : 'shared/change_image'), | 730 | render :partial => (image && image.valid? ? 'shared/show_thumbnail' : 'shared/change_image'), |
app/helpers/blog_helper.rb
@@ -17,28 +17,28 @@ module BlogHelper | @@ -17,28 +17,28 @@ module BlogHelper | ||
17 | _('Configure blog') | 17 | _('Configure blog') |
18 | end | 18 | end |
19 | 19 | ||
20 | - def list_posts(articles, format = 'full', paginate = true) | 20 | + def list_posts(articles, conf = { format: 'full', paginate: true }) |
21 | pagination = will_paginate(articles, { | 21 | pagination = will_paginate(articles, { |
22 | :param_name => 'npage', | 22 | :param_name => 'npage', |
23 | :previous_label => _('« Newer posts'), | 23 | :previous_label => _('« Newer posts'), |
24 | :next_label => _('Older posts »'), | 24 | :next_label => _('Older posts »'), |
25 | :params => {:action=>"view_page", :page=>articles.first.parent.path.split('/'), :controller=>"content_viewer"} | 25 | :params => {:action=>"view_page", :page=>articles.first.parent.path.split('/'), :controller=>"content_viewer"} |
26 | - }) if articles.present? && paginate | 26 | + }) if articles.present? && conf[:paginate] |
27 | content = [] | 27 | content = [] |
28 | artic_len = articles.length | 28 | artic_len = articles.length |
29 | articles.each_with_index{ |art,i| | 29 | articles.each_with_index{ |art,i| |
30 | - css_add = [ 'position-'+(i+1).to_s() ] | 30 | + css_add = [ 'blog-post', 'position-'+(i+1).to_s() ] |
31 | position = (i%2 == 0) ? 'odd-post' : 'even-post' | 31 | position = (i%2 == 0) ? 'odd-post' : 'even-post' |
32 | css_add << 'first' if i == 0 | 32 | css_add << 'first' if i == 0 |
33 | css_add << 'last' if i == (artic_len-1) | 33 | css_add << 'last' if i == (artic_len-1) |
34 | css_add << 'not-published' if !art.published? | 34 | css_add << 'not-published' if !art.published? |
35 | - css_add << position + '-inner' | ||
36 | - content << content_tag('div', | ||
37 | - content_tag('div', | ||
38 | - display_post(art, format).html_safe + '<br style="clear:both"/>'.html_safe, | ||
39 | - :class => 'blog-post ' + css_add.join(' '), | ||
40 | - :id => "post-#{art.id}"), :class => position | ||
41 | - ) | 35 | + css_add << position |
36 | + content << (content_tag 'div', id: "post-#{art.id}", class: css_add do | ||
37 | + content_tag 'div', class: position + '-inner blog-post-inner' do | ||
38 | + display_post(art, conf[:format]).html_safe + | ||
39 | + '<br style="clear:both"/>'.html_safe | ||
40 | + end | ||
41 | + end) | ||
42 | } | 42 | } |
43 | content.join("\n<hr class='sep-posts'/>\n") + (pagination or '') | 43 | content.join("\n<hr class='sep-posts'/>\n") + (pagination or '') |
44 | end | 44 | end |
@@ -46,7 +46,16 @@ module BlogHelper | @@ -46,7 +46,16 @@ module BlogHelper | ||
46 | def display_post(article, format = 'full') | 46 | def display_post(article, format = 'full') |
47 | no_comments = (format == 'full') ? false : true | 47 | no_comments = (format == 'full') ? false : true |
48 | title = article_title(article, :no_comments => no_comments) | 48 | title = article_title(article, :no_comments => no_comments) |
49 | - html = send("display_#{format}_format", FilePresenter.for(article)).html_safe | 49 | + method = "display_#{format.split('+')[0]}_format" |
50 | + html = send(method, FilePresenter.for(article)).html_safe | ||
51 | + if format.split('+')[1] == 'pic' | ||
52 | + img = article.first_image | ||
53 | + if img.blank? | ||
54 | + '<div class="post-pic empty"></div>' | ||
55 | + else | ||
56 | + '<div class="post-pic" style="background-image:url('+img+')"></div>' | ||
57 | + end | ||
58 | + end.to_s + | ||
50 | title + html | 59 | title + html |
51 | end | 60 | end |
52 | 61 |
app/helpers/boxes_helper.rb
@@ -190,7 +190,7 @@ module BoxesHelper | @@ -190,7 +190,7 @@ module BoxesHelper | ||
190 | else | 190 | else |
191 | "before-block-#{block.id}" | 191 | "before-block-#{block.id}" |
192 | end | 192 | end |
193 | - if block.nil? or modifiable?(block) | 193 | + if block.nil? || movable?(block) |
194 | content_tag('div', ' ', :id => id, :class => 'block-target' ) + drop_receiving_element(id, :url => { :action => 'move_block', :target => id }, :accept => box.acceptable_blocks, :hoverclass => 'block-target-hover') | 194 | content_tag('div', ' ', :id => id, :class => 'block-target' ) + drop_receiving_element(id, :url => { :action => 'move_block', :target => id }, :accept => box.acceptable_blocks, :hoverclass => 'block-target-hover') |
195 | else | 195 | else |
196 | "" | 196 | "" |
@@ -199,14 +199,14 @@ module BoxesHelper | @@ -199,14 +199,14 @@ module BoxesHelper | ||
199 | 199 | ||
200 | # makes the given block draggable so it can be moved away. | 200 | # makes the given block draggable so it can be moved away. |
201 | def block_handle(block) | 201 | def block_handle(block) |
202 | - modifiable?(block) ? draggable_element("block-#{block.id}", :revert => true) : "" | 202 | + movable?(block) ? draggable_element("block-#{block.id}", :revert => true) : "" |
203 | end | 203 | end |
204 | 204 | ||
205 | def block_edit_buttons(block) | 205 | def block_edit_buttons(block) |
206 | buttons = [] | 206 | buttons = [] |
207 | nowhere = 'javascript: return false;' | 207 | nowhere = 'javascript: return false;' |
208 | 208 | ||
209 | - if modifiable?(block) | 209 | + if movable?(block) |
210 | if block.first? | 210 | if block.first? |
211 | buttons << icon_button('up-disabled', _("Can't move up anymore."), nowhere) | 211 | buttons << icon_button('up-disabled', _("Can't move up anymore."), nowhere) |
212 | else | 212 | else |
@@ -229,15 +229,15 @@ module BoxesHelper | @@ -229,15 +229,15 @@ module BoxesHelper | ||
229 | buttons << icon_button('left', _('Move to the opposite side'), { :action => 'move_block', :target => 'end-of-box-' + holder.boxes[1].id.to_s, :id => block.id }, :method => 'post' ) | 229 | buttons << icon_button('left', _('Move to the opposite side'), { :action => 'move_block', :target => 'end-of-box-' + holder.boxes[1].id.to_s, :id => block.id }, :method => 'post' ) |
230 | end | 230 | end |
231 | end | 231 | end |
232 | + end | ||
232 | 233 | ||
233 | - if block.editable? | ||
234 | - buttons << modal_icon_button(:edit, _('Edit'), { :action => 'edit', :id => block.id }) | ||
235 | - end | 234 | + if editable?(block) |
235 | + buttons << modal_icon_button(:edit, _('Edit'), { :action => 'edit', :id => block.id }) | ||
236 | + end | ||
236 | 237 | ||
237 | - if !block.main? | ||
238 | - buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post', :confirm => _('Are you sure you want to remove this block?')}) | ||
239 | - buttons << icon_button(:clone, _('Clone'), { :action => 'clone_block', :id => block.id }, { :method => 'post' }) | ||
240 | - end | 238 | + if movable?(block) && !block.main? |
239 | + buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post', :confirm => _('Are you sure you want to remove this block?')}) | ||
240 | + buttons << icon_button(:clone, _('Clone'), { :action => 'clone_block', :id => block.id }, { :method => 'post' }) | ||
241 | end | 241 | end |
242 | 242 | ||
243 | if block.respond_to?(:help) | 243 | if block.respond_to?(:help) |
@@ -273,7 +273,11 @@ module BoxesHelper | @@ -273,7 +273,11 @@ module BoxesHelper | ||
273 | classes | 273 | classes |
274 | end | 274 | end |
275 | 275 | ||
276 | - def modifiable?(block) | ||
277 | - return !block.fixed || environment.admins.include?(user) | 276 | + def movable?(block) |
277 | + return block.movable? || user.is_admin? | ||
278 | + end | ||
279 | + | ||
280 | + def editable?(block) | ||
281 | + return block.editable? || user.is_admin? | ||
278 | end | 282 | end |
279 | end | 283 | end |
app/helpers/layout_helper.rb
@@ -28,7 +28,7 @@ module LayoutHelper | @@ -28,7 +28,7 @@ module LayoutHelper | ||
28 | end | 28 | end |
29 | 29 | ||
30 | def noosfero_javascript | 30 | def noosfero_javascript |
31 | - plugins_javascripts = @plugins.flat_map{ |plugin| plugin.js_files.map{ |js| plugin.class.public_path(js, true) } }.flatten | 31 | + plugins_javascripts = @plugins.flat_map{ |plugin| Array.wrap(plugin.js_files).map{ |js| plugin.class.public_path(js, true) } }.flatten |
32 | 32 | ||
33 | output = '' | 33 | output = '' |
34 | output += render 'layouts/javascript' | 34 | output += render 'layouts/javascript' |
@@ -38,6 +38,8 @@ module LayoutHelper | @@ -38,6 +38,8 @@ module LayoutHelper | ||
38 | output += theme_javascript_ng.to_s | 38 | output += theme_javascript_ng.to_s |
39 | output += javascript_tag 'render_all_jquery_ui_widgets()' | 39 | output += javascript_tag 'render_all_jquery_ui_widgets()' |
40 | 40 | ||
41 | + output += templete_javascript_ng.to_s | ||
42 | + | ||
41 | output | 43 | output |
42 | end | 44 | end |
43 | 45 | ||
@@ -70,11 +72,7 @@ module LayoutHelper | @@ -70,11 +72,7 @@ module LayoutHelper | ||
70 | end | 72 | end |
71 | 73 | ||
72 | def template_stylesheet_path | 74 | def template_stylesheet_path |
73 | - if profile.nil? | ||
74 | - "/designs/templates/#{environment.layout_template}/stylesheets/style.css" | ||
75 | - else | ||
76 | - "/designs/templates/#{profile.layout_template}/stylesheets/style.css" | ||
77 | - end | 75 | + File.join template_path, "/stylesheets/style.css" |
78 | end | 76 | end |
79 | 77 | ||
80 | 78 |
app/helpers/tinymce_helper.rb
@@ -17,6 +17,7 @@ module TinymceHelper | @@ -17,6 +17,7 @@ module TinymceHelper | ||
17 | searchreplace wordcount visualblocks visualchars code fullscreen | 17 | searchreplace wordcount visualblocks visualchars code fullscreen |
18 | insertdatetime media nonbreaking save table contextmenu directionality | 18 | insertdatetime media nonbreaking save table contextmenu directionality |
19 | emoticons template paste textcolor colorpicker textpattern], | 19 | emoticons template paste textcolor colorpicker textpattern], |
20 | + :image_advtab => true, | ||
20 | :language => tinymce_language | 21 | :language => tinymce_language |
21 | 22 | ||
22 | options[:toolbar1] = "insertfile undo redo | copy paste | bold italic underline | styleselect fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image" | 23 | options[:toolbar1] = "insertfile undo redo | copy paste | bold italic underline | styleselect fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image" |
app/models/article.rb
@@ -5,7 +5,7 @@ class Article < ActiveRecord::Base | @@ -5,7 +5,7 @@ class Article < ActiveRecord::Base | ||
5 | :allow_members_to_edit, :translation_of_id, :language, | 5 | :allow_members_to_edit, :translation_of_id, :language, |
6 | :license_id, :parent_id, :display_posts_in_current_language, | 6 | :license_id, :parent_id, :display_posts_in_current_language, |
7 | :category_ids, :posts_per_page, :moderate_comments, | 7 | :category_ids, :posts_per_page, :moderate_comments, |
8 | - :accept_comments, :feed, :published, :source, | 8 | + :accept_comments, :feed, :published, :source, :source_name, |
9 | :highlighted, :notify_comments, :display_hits, :slug, | 9 | :highlighted, :notify_comments, :display_hits, :slug, |
10 | :external_feed_builder, :display_versions, :external_link, | 10 | :external_feed_builder, :display_versions, :external_link, |
11 | :image_builder, :show_to_followers | 11 | :image_builder, :show_to_followers |
@@ -769,7 +769,9 @@ class Article < ActiveRecord::Base | @@ -769,7 +769,9 @@ class Article < ActiveRecord::Base | ||
769 | end | 769 | end |
770 | 770 | ||
771 | def first_image | 771 | def first_image |
772 | - img = Nokogiri::HTML.fragment(self.lead.to_s).css('img[src]').first || Nokogiri::HTML.fragment(self.body.to_s).search('img').first | 772 | + img = ( image.present? && { 'src' => image.public_filename } ) || |
773 | + Nokogiri::HTML.fragment(self.lead.to_s).css('img[src]').first || | ||
774 | + Nokogiri::HTML.fragment(self.body.to_s).search('img').first | ||
773 | img.nil? ? '' : img['src'] | 775 | img.nil? ? '' : img['src'] |
774 | end | 776 | end |
775 | 777 |
app/models/block.rb
1 | class Block < ActiveRecord::Base | 1 | class Block < ActiveRecord::Base |
2 | 2 | ||
3 | - attr_accessible :title, :display, :limit, :box_id, :posts_per_page, :visualization_format, :language, :display_user, :box, :fixed | 3 | + attr_accessible :title, :display, :limit, :box_id, :posts_per_page, |
4 | + :visualization_format, :language, :display_user, | ||
5 | + :box, :edit_modes, :move_modes | ||
4 | 6 | ||
5 | # to be able to generate HTML | 7 | # to be able to generate HTML |
6 | include ActionView::Helpers::UrlHelper | 8 | include ActionView::Helpers::UrlHelper |
@@ -23,7 +25,7 @@ class Block < ActiveRecord::Base | @@ -23,7 +25,7 @@ class Block < ActiveRecord::Base | ||
23 | end | 25 | end |
24 | 26 | ||
25 | def get_limit | 27 | def get_limit |
26 | - [0,limit].max | 28 | + [0,limit.to_i].max |
27 | end | 29 | end |
28 | 30 | ||
29 | def embed_code | 31 | def embed_code |
@@ -110,8 +112,13 @@ class Block < ActiveRecord::Base | @@ -110,8 +112,13 @@ class Block < ActiveRecord::Base | ||
110 | # * <tt>'all'</tt>: the block is always displayed | 112 | # * <tt>'all'</tt>: the block is always displayed |
111 | settings_items :language, :type => :string, :default => 'all' | 113 | settings_items :language, :type => :string, :default => 'all' |
112 | 114 | ||
113 | - # The block can be configured to be fixed. Only can be edited by environment admins | ||
114 | - settings_items :fixed, :type => :boolean, :default => false | 115 | + # The block can be configured to define the edition modes options. Only can be edited by environment admins |
116 | + # It can assume the following values: | ||
117 | + # | ||
118 | + # * <tt>'all'</tt>: the block owner has all edit options for this block | ||
119 | + # * <tt>'none'</tt>: the block owner can't do anything with the block | ||
120 | + settings_items :edit_modes, :type => :string, :default => 'all' | ||
121 | + settings_items :move_modes, :type => :string, :default => 'all' | ||
115 | 122 | ||
116 | # returns the description of the block, used when the user sees a list of | 123 | # returns the description of the block, used when the user sees a list of |
117 | # blocks to choose one to include in the design. | 124 | # blocks to choose one to include in the design. |
@@ -148,7 +155,11 @@ class Block < ActiveRecord::Base | @@ -148,7 +155,11 @@ class Block < ActiveRecord::Base | ||
148 | 155 | ||
149 | # Is this block editable? (Default to <tt>false</tt>) | 156 | # Is this block editable? (Default to <tt>false</tt>) |
150 | def editable? | 157 | def editable? |
151 | - true | 158 | + self.edit_modes == "all" |
159 | + end | ||
160 | + | ||
161 | + def movable? | ||
162 | + self.move_modes == "all" | ||
152 | end | 163 | end |
153 | 164 | ||
154 | # must always return false, except on MainBlock clas. | 165 | # must always return false, except on MainBlock clas. |
@@ -228,6 +239,21 @@ class Block < ActiveRecord::Base | @@ -228,6 +239,21 @@ class Block < ActiveRecord::Base | ||
228 | } | 239 | } |
229 | end | 240 | end |
230 | 241 | ||
242 | + def edit_block_options | ||
243 | + @edit_options ||= { | ||
244 | + 'all' => _('Can be modified'), | ||
245 | + 'none' => _('Cannot be modified') | ||
246 | + } | ||
247 | + end | ||
248 | + | ||
249 | + def move_block_options | ||
250 | + @move_options ||= { | ||
251 | + 'all' => _('Can be moved'), | ||
252 | + 'none' => _('Cannot be moved') | ||
253 | + } | ||
254 | + end | ||
255 | + | ||
256 | + | ||
231 | def duplicate | 257 | def duplicate |
232 | duplicated_block = self.dup | 258 | duplicated_block = self.dup |
233 | duplicated_block.display = 'never' | 259 | duplicated_block.display = 'never' |
app/models/blog.rb
@@ -76,7 +76,7 @@ class Blog < Folder | @@ -76,7 +76,7 @@ class Blog < Folder | ||
76 | end | 76 | end |
77 | 77 | ||
78 | settings_items :visualization_format, :type => :string, :default => 'full' | 78 | settings_items :visualization_format, :type => :string, :default => 'full' |
79 | - validates_inclusion_of :visualization_format, :in => [ 'full', 'short' ], :if => :visualization_format | 79 | + validates_inclusion_of :visualization_format, :in => [ 'full', 'short', 'short+pic' ], :if => :visualization_format |
80 | 80 | ||
81 | settings_items :display_posts_in_current_language, :type => :boolean, :default => false | 81 | settings_items :display_posts_in_current_language, :type => :boolean, :default => false |
82 | 82 |
app/models/environment.rb
@@ -19,6 +19,8 @@ class Environment < ActiveRecord::Base | @@ -19,6 +19,8 @@ class Environment < ActiveRecord::Base | ||
19 | filename | 19 | filename |
20 | end | 20 | end |
21 | 21 | ||
22 | + NUMBER_OF_BOXES = 4 | ||
23 | + | ||
22 | PERMISSIONS['Environment'] = { | 24 | PERMISSIONS['Environment'] = { |
23 | 'view_environment_admin_panel' => N_('View environment admin panel'), | 25 | 'view_environment_admin_panel' => N_('View environment admin panel'), |
24 | 'edit_environment_features' => N_('Edit environment features'), | 26 | 'edit_environment_features' => N_('Edit environment features'), |
@@ -172,7 +174,7 @@ class Environment < ActiveRecord::Base | @@ -172,7 +174,7 @@ class Environment < ActiveRecord::Base | ||
172 | acts_as_having_boxes | 174 | acts_as_having_boxes |
173 | 175 | ||
174 | after_create do |env| | 176 | after_create do |env| |
175 | - 3.times do | 177 | + NUMBER_OF_BOXES.times do |
176 | env.boxes << Box.new | 178 | env.boxes << Box.new |
177 | end | 179 | end |
178 | 180 | ||
@@ -737,8 +739,8 @@ class Environment < ActiveRecord::Base | @@ -737,8 +739,8 @@ class Environment < ActiveRecord::Base | ||
737 | end | 739 | end |
738 | 740 | ||
739 | def is_default_template?(template) | 741 | def is_default_template?(template) |
740 | - is_default = template == community_default_template | ||
741 | - is_default = is_default || template == person_default_template | 742 | + is_default = template == community_default_template |
743 | + is_default = is_default || template == person_default_template | ||
742 | is_default = is_default || template == enterprise_default_template | 744 | is_default = is_default || template == enterprise_default_template |
743 | is_default | 745 | is_default |
744 | end | 746 | end |
app/models/highlights_block.rb
@@ -26,8 +26,16 @@ class HighlightsBlock < Block | @@ -26,8 +26,16 @@ class HighlightsBlock < Block | ||
26 | end | 26 | end |
27 | 27 | ||
28 | def featured_images | 28 | def featured_images |
29 | - block_images = images.select{|i| !i[:image_src].nil? }.sort { |x, y| x[:position] <=> y[:position] } | ||
30 | - shuffle ? block_images.shuffle : block_images | 29 | + images = get_images |
30 | + shuffle ? images.shuffle : images | ||
31 | + end | ||
32 | + | ||
33 | + def get_images | ||
34 | + images.select do |i| | ||
35 | + !i[:image_src].nil? | ||
36 | + end.sort do |x, y| | ||
37 | + x[:position] <=> y[:position] | ||
38 | + end | ||
31 | end | 39 | end |
32 | 40 | ||
33 | def content(args={}) | 41 | def content(args={}) |
app/models/organization.rb
@@ -29,6 +29,8 @@ class Organization < Profile | @@ -29,6 +29,8 @@ class Organization < Profile | ||
29 | 29 | ||
30 | has_many :mailings, :class_name => 'OrganizationMailing', :foreign_key => :source_id, :as => 'source' | 30 | has_many :mailings, :class_name => 'OrganizationMailing', :foreign_key => :source_id, :as => 'source' |
31 | 31 | ||
32 | + has_many :custom_roles, :class_name => 'Role', :foreign_key => :profile_id | ||
33 | + | ||
32 | scope :more_popular, :order => 'members_count DESC' | 34 | scope :more_popular, :order => 'members_count DESC' |
33 | 35 | ||
34 | validate :presence_of_required_fieds, :unless => :is_template | 36 | validate :presence_of_required_fieds, :unless => :is_template |
app/models/profile.rb
@@ -22,6 +22,8 @@ class Profile < ActiveRecord::Base | @@ -22,6 +22,8 @@ class Profile < ActiveRecord::Base | ||
22 | :display => %w[compact] | 22 | :display => %w[compact] |
23 | } | 23 | } |
24 | 24 | ||
25 | + NUMBER_OF_BOXES = 4 | ||
26 | + | ||
25 | def self.default_search_display | 27 | def self.default_search_display |
26 | 'compact' | 28 | 'compact' |
27 | end | 29 | end |
@@ -43,7 +45,7 @@ class Profile < ActiveRecord::Base | @@ -43,7 +45,7 @@ class Profile < ActiveRecord::Base | ||
43 | find_role('editor', env_id) | 45 | find_role('editor', env_id) |
44 | end | 46 | end |
45 | def self.organization_member_roles(env_id) | 47 | def self.organization_member_roles(env_id) |
46 | - all_roles(env_id).select{ |r| r.key.match(/^profile_/) unless r.key.blank? } | 48 | + all_roles(env_id).select{ |r| r.key.match(/^profile_/) unless r.key.blank? || !r.profile_id.nil?} |
47 | end | 49 | end |
48 | def self.all_roles(env_id) | 50 | def self.all_roles(env_id) |
49 | Role.all :conditions => { :environment_id => env_id } | 51 | Role.all :conditions => { :environment_id => env_id } |
@@ -75,6 +77,7 @@ class Profile < ActiveRecord::Base | @@ -75,6 +77,7 @@ class Profile < ActiveRecord::Base | ||
75 | 'publish_content' => N_('Publish content'), | 77 | 'publish_content' => N_('Publish content'), |
76 | 'invite_members' => N_('Invite members'), | 78 | 'invite_members' => N_('Invite members'), |
77 | 'send_mail_to_members' => N_('Send e-Mail to members'), | 79 | 'send_mail_to_members' => N_('Send e-Mail to members'), |
80 | + 'manage_custom_roles' => N_('Manage custom roles'), | ||
78 | } | 81 | } |
79 | 82 | ||
80 | acts_as_accessible | 83 | acts_as_accessible |
@@ -361,7 +364,7 @@ class Profile < ActiveRecord::Base | @@ -361,7 +364,7 @@ class Profile < ActiveRecord::Base | ||
361 | if template | 364 | if template |
362 | apply_template(template, :copy_articles => false) | 365 | apply_template(template, :copy_articles => false) |
363 | else | 366 | else |
364 | - 3.times do | 367 | + NUMBER_OF_BOXES.times do |
365 | self.boxes << Box.new | 368 | self.boxes << Box.new |
366 | end | 369 | end |
367 | 370 | ||
@@ -404,6 +407,7 @@ class Profile < ActiveRecord::Base | @@ -404,6 +407,7 @@ class Profile < ActiveRecord::Base | ||
404 | alias_method_chain :template, :default | 407 | alias_method_chain :template, :default |
405 | 408 | ||
406 | def apply_template(template, options = {:copy_articles => true}) | 409 | def apply_template(template, options = {:copy_articles => true}) |
410 | + self.template = template | ||
407 | copy_blocks_from(template) | 411 | copy_blocks_from(template) |
408 | copy_articles_from(template) if options[:copy_articles] | 412 | copy_articles_from(template) if options[:copy_articles] |
409 | self.apply_type_specific_template(template) | 413 | self.apply_type_specific_template(template) |
app/models/suggest_article.rb
1 | class SuggestArticle < Task | 1 | class SuggestArticle < Task |
2 | 2 | ||
3 | - validates_presence_of :target_id, :article_name, :email, :name, :article_body | 3 | + validates_presence_of :target_id |
4 | + validates_presence_of :email, :name, :if => Proc.new { |task| task.requestor.blank? } | ||
5 | + validates_associated :article_object | ||
4 | 6 | ||
5 | settings_items :email, :type => String | 7 | settings_items :email, :type => String |
6 | settings_items :name, :type => String | 8 | settings_items :name, :type => String |
7 | - settings_items :article_name, :type => String | ||
8 | - settings_items :article_body, :type => String | ||
9 | - settings_items :article_abstract, :type => String | ||
10 | - settings_items :article_parent_id, :type => String | ||
11 | - settings_items :source, :type => String | ||
12 | - settings_items :source_name, :type => String | ||
13 | - settings_items :highlighted, :type => :boolean, :default => false | ||
14 | settings_items :ip_address, :type => String | 9 | settings_items :ip_address, :type => String |
15 | settings_items :user_agent, :type => String | 10 | settings_items :user_agent, :type => String |
16 | settings_items :referrer, :type => String | 11 | settings_items :referrer, :type => String |
12 | + settings_items :article, :type => Hash, :default => {} | ||
17 | 13 | ||
18 | after_create :schedule_spam_checking | 14 | after_create :schedule_spam_checking |
19 | 15 | ||
@@ -24,34 +20,49 @@ class SuggestArticle < Task | @@ -24,34 +20,49 @@ class SuggestArticle < Task | ||
24 | include Noosfero::Plugin::HotSpot | 20 | include Noosfero::Plugin::HotSpot |
25 | 21 | ||
26 | def sender | 22 | def sender |
27 | - "#{name} (#{email})" | 23 | + requestor ? "#{requestor.name}" : "#{name} (#{email})" |
24 | + end | ||
25 | + | ||
26 | + def article_object | ||
27 | + if @article_object.nil? | ||
28 | + @article_object = article_type.new(article.merge({:profile => target}).except(:type)) | ||
29 | + if requestor.present? | ||
30 | + @article_object.author = requestor | ||
31 | + else | ||
32 | + @article_object.author_name = name | ||
33 | + end | ||
34 | + end | ||
35 | + @article_object | ||
36 | + end | ||
37 | + | ||
38 | + def article_type | ||
39 | + if article[:type].present? | ||
40 | + type = article[:type].constantize | ||
41 | + return type if type < Article | ||
42 | + end | ||
43 | + TinyMceArticle | ||
28 | end | 44 | end |
29 | 45 | ||
30 | def perform | 46 | def perform |
31 | - task = TinyMceArticle.new | ||
32 | - task.profile = target | ||
33 | - task.name = article_name | ||
34 | - task.author_name = name | ||
35 | - task.body = article_body | ||
36 | - task.abstract = article_abstract | ||
37 | - task.parent_id = article_parent_id | ||
38 | - task.source = source | ||
39 | - task.source_name = source_name | ||
40 | - task.highlighted = highlighted | ||
41 | - task.save! | 47 | + article_object.save! |
42 | end | 48 | end |
43 | 49 | ||
44 | def title | 50 | def title |
45 | _("Article suggestion") | 51 | _("Article suggestion") |
46 | end | 52 | end |
47 | 53 | ||
54 | + def article_name | ||
55 | + article[:name] | ||
56 | + end | ||
57 | + | ||
48 | def subject | 58 | def subject |
49 | article_name | 59 | article_name |
50 | end | 60 | end |
51 | 61 | ||
52 | def information | 62 | def information |
53 | - { :message => _('%{sender} suggested the publication of the article: %{subject}.'), | ||
54 | - :variables => {:sender => sender} } | 63 | + variables = requestor.blank? ? {:requestor => sender} : {} |
64 | + { :message => _('%{requestor} suggested the publication of the article: %{subject}.'), | ||
65 | + :variables => variables } | ||
55 | end | 66 | end |
56 | 67 | ||
57 | def accept_details | 68 | def accept_details |
@@ -63,8 +74,8 @@ class SuggestArticle < Task | @@ -63,8 +74,8 @@ class SuggestArticle < Task | ||
63 | end | 74 | end |
64 | 75 | ||
65 | def target_notification_description | 76 | def target_notification_description |
66 | - _('%{sender} suggested the publication of the article: %{article}.') % | ||
67 | - {:sender => sender, :article => article_name} | 77 | + _('%{requestor} suggested the publication of the article: %{article}.') % |
78 | + {:requestor => sender, :article => article_name} | ||
68 | end | 79 | end |
69 | 80 | ||
70 | def target_notification_message | 81 | def target_notification_message |
app/models/user.rb
@@ -45,7 +45,7 @@ class User < ActiveRecord::Base | @@ -45,7 +45,7 @@ class User < ActiveRecord::Base | ||
45 | p = Person.new | 45 | p = Person.new |
46 | 46 | ||
47 | p.attributes = user.person_data | 47 | p.attributes = user.person_data |
48 | - p.identifier = user.login | 48 | + p.identifier = user.login if p.identifier.blank? |
49 | p.user = user | 49 | p.user = user |
50 | p.environment = user.environment | 50 | p.environment = user.environment |
51 | p.name ||= user.name || user.login | 51 | p.name ||= user.name || user.login |
app/views/blocks/profile_info_actions/_join_leave_community.html.erb
1 | -<div class='join-leave-button'> | 1 | +<div class='join-leave-button require-login-popup'> |
2 | <% if logged_in? %> | 2 | <% if logged_in? %> |
3 | <% if profile.members.include?(user) %> | 3 | <% if profile.members.include?(user) %> |
4 | <%= button(:delete, content_tag('span', _('Leave community')), profile.leave_url, | 4 | <%= button(:delete, content_tag('span', _('Leave community')), profile.leave_url, |
app/views/box_organizer/edit.html.erb
@@ -5,12 +5,6 @@ | @@ -5,12 +5,6 @@ | ||
5 | 5 | ||
6 | <%= labelled_form_field(_('Custom title for this block: '), text_field(:block, :title, :maxlength => 20)) %> | 6 | <%= labelled_form_field(_('Custom title for this block: '), text_field(:block, :title, :maxlength => 20)) %> |
7 | 7 | ||
8 | - <% if environment.admins.include?(user) %> | ||
9 | - <div class="fixed_block"> | ||
10 | - <%= labelled_check_box(_("Fixed"), "block[fixed]", value = "1", checked = @block.fixed) %> | ||
11 | - </div> | ||
12 | - <% end %> | ||
13 | - | ||
14 | <%= render :partial => partial_for_class(@block.class) %> | 8 | <%= render :partial => partial_for_class(@block.class) %> |
15 | 9 | ||
16 | <div class="display"> | 10 | <div class="display"> |
@@ -25,6 +19,15 @@ | @@ -25,6 +19,15 @@ | ||
25 | 19 | ||
26 | <%= labelled_form_field(_('Show for:'), select(:block, :language, [ [ _('all languages'), 'all']] + environment.locales.map {|key, value| [value, key]} )) %> | 20 | <%= labelled_form_field(_('Show for:'), select(:block, :language, [ [ _('all languages'), 'all']] + environment.locales.map {|key, value| [value, key]} )) %> |
27 | 21 | ||
22 | + <% if user.is_admin? %> | ||
23 | + <div class="edit-modes"> | ||
24 | + <%= labelled_form_field _('Edit options:'), select_tag('block[edit_modes]', options_from_collection_for_select(@block.edit_block_options, :first, :last, @block.edit_modes)) %> | ||
25 | + </div> | ||
26 | + <div class="move-modes"> | ||
27 | + <%= labelled_form_field _('Move options:'), select_tag('block[move_modes]', options_from_collection_for_select(@block.move_block_options, :first, :last, @block.move_modes)) %> | ||
28 | + </div> | ||
29 | + <% end %> | ||
30 | + | ||
28 | <% button_bar do %> | 31 | <% button_bar do %> |
29 | <%= submit_button(:save, _('Save')) %> | 32 | <%= submit_button(:save, _('Save')) %> |
30 | <%= modal_close_button(_('Cancel')) %> | 33 | <%= modal_close_button(_('Cancel')) %> |
app/views/cms/_blog.html.erb
@@ -64,7 +64,11 @@ | @@ -64,7 +64,11 @@ | ||
64 | <%= labelled_check_box(_('Remove cover image'),'remove_image',true,false)%> | 64 | <%= labelled_check_box(_('Remove cover image'),'remove_image',true,false)%> |
65 | <% end %> | 65 | <% end %> |
66 | 66 | ||
67 | -<%= labelled_form_field(_('How to display posts:'), f.select(:visualization_format, [ [ _('Full post'), 'full'], [ _('First paragraph'), 'short'] ])) %> | 67 | +<%= labelled_form_field(_('How to display posts:'), f.select(:visualization_format, [ |
68 | + [ _('Full post'), 'full'], | ||
69 | + [ _('First paragraph'), 'short'], | ||
70 | + [ _('First paragraph, with post picture'), 'short+pic'] | ||
71 | +])) %> | ||
68 | 72 | ||
69 | <%= labelled_form_field(_('Posts per page:'), f.select(:posts_per_page, Blog.posts_per_page_options)) %> | 73 | <%= labelled_form_field(_('Posts per page:'), f.select(:posts_per_page, Blog.posts_per_page_options)) %> |
70 | 74 |
app/views/cms/suggest_an_article.html.erb
@@ -6,21 +6,22 @@ | @@ -6,21 +6,22 @@ | ||
6 | 6 | ||
7 | <%= labelled_form_for 'task' do |f| %> | 7 | <%= labelled_form_for 'task' do |f| %> |
8 | 8 | ||
9 | - <%= required labelled_form_field(_('Title'), text_field(:task, 'article_name', :size => 50)) %> | 9 | + <%= required labelled_form_field(_('Title'), text_field('task[article]', 'name', :size => 50)) %> |
10 | 10 | ||
11 | - <%= labelled_form_field(_('Source'), text_field(:task, 'source_name')) %> | 11 | + <%= labelled_form_field(_('Source'), text_field('task[article]', 'source_name')) %> |
12 | 12 | ||
13 | - <%= labelled_form_field(_('Source URL'), text_field(:task, 'source')) %> | 13 | + <%= labelled_form_field(_('Source URL'), text_field('task[article]', 'source')) %> |
14 | 14 | ||
15 | - <%= required labelled_form_field(_('Your name'), text_field(:task, 'name')) %> | ||
16 | - | ||
17 | - <%= required labelled_form_field(_('Email'), text_field(:task, 'email')) %> | 15 | + <% unless logged_in? %> |
16 | + <%= required labelled_form_field(_('Your name'), text_field(:task, 'name')) %> | ||
17 | + <%= required labelled_form_field(_('Email'), text_field(:task, 'email')) %> | ||
18 | + <% end %> | ||
18 | 19 | ||
19 | - <%= render :partial => 'shared/lead_and_body', :locals => {:tiny_mce => true, :object => :task, :abstract_method => 'article_abstract', :body_method => 'article_body'} %> | 20 | + <%= render :partial => 'shared/lead_and_body', :locals => {:tiny_mce => true, :object => 'task[article]'} %> |
20 | 21 | ||
21 | <%= hidden_field_tag('back_to', @back_to) %> | 22 | <%= hidden_field_tag('back_to', @back_to) %> |
22 | 23 | ||
23 | - <%= recaptcha_tags(:display => { :theme => 'clean' }, :ajax => true) %> | 24 | + <%= recaptcha_tags(:display => { :theme => 'clean' }, :ajax => true) unless logged_in? %> |
24 | 25 | ||
25 | <% button_bar do %> | 26 | <% button_bar do %> |
26 | <%= submit_button :save, _('Save') %> | 27 | <%= submit_button :save, _('Save') %> |
app/views/content_viewer/blog_page.html.erb
@@ -18,6 +18,9 @@ | @@ -18,6 +18,9 @@ | ||
18 | format = inside_block.visualization_format | 18 | format = inside_block.visualization_format |
19 | paginate = false | 19 | paginate = false |
20 | end | 20 | end |
21 | - (blog.empty? ? content_tag('em', _('(no posts)')) : list_posts(posts, format, paginate)) | 21 | + (blog.empty? ? |
22 | + content_tag('em', _('(no posts)')) : | ||
23 | + list_posts(posts, format: format, paginate: paginate) | ||
24 | + ) | ||
22 | %> | 25 | %> |
23 | </div> | 26 | </div> |
app/views/features/manage_fields.html.erb
1 | <h1><%= _('Manage fields displayed for profiles') %></h1> | 1 | <h1><%= _('Manage fields displayed for profiles') %></h1> |
2 | 2 | ||
3 | +<%= javascript_include_tag "manage-fields.js" %> | ||
4 | + | ||
3 | <% tabs = [] %> | 5 | <% tabs = [] %> |
4 | <% tabs << {:title => _("Person's fields"), :id => 'person-fields', | 6 | <% tabs << {:title => _("Person's fields"), :id => 'person-fields', |
5 | :content => (render :partial => 'manage_person_fields')} %> | 7 | :content => (render :partial => 'manage_person_fields')} %> |
@@ -11,5 +13,3 @@ | @@ -11,5 +13,3 @@ | ||
11 | <% end %> | 13 | <% end %> |
12 | 14 | ||
13 | <%= render_tabs(tabs) %> | 15 | <%= render_tabs(tabs) %> |
14 | - | ||
15 | -<%= javascript_include_tag "manage-fields.js" %> |
app/views/profile/report_abuse.html.erb
@@ -24,7 +24,7 @@ | @@ -24,7 +24,7 @@ | ||
24 | $('#report-abuse-submit-button').css('cursor', 'progress'); | 24 | $('#report-abuse-submit-button').css('cursor', 'progress'); |
25 | $.ajax({ | 25 | $.ajax({ |
26 | type: 'POST', | 26 | type: 'POST', |
27 | - url: <%= url_for({:controller => 'profile', :action => 'register_report', :profile => profile.identifier}) %>, | 27 | + url: <%= url_for({:controller => 'profile', :action => 'register_report', :profile => profile.identifier}).to_json %>, |
28 | data: $(form).serialize(), | 28 | data: $(form).serialize(), |
29 | dataType: 'json', | 29 | dataType: 'json', |
30 | success: function(data, status, ajax){ | 30 | success: function(data, status, ajax){ |
app/views/profile_editor/edit.html.erb
1 | <h1><%= _('Profile settings for %s') % profile.name %></h1> | 1 | <h1><%= _('Profile settings for %s') % profile.name %></h1> |
2 | 2 | ||
3 | -<%= javascript_include_tag 'deactivate_profile' %> | ||
4 | <%= error_messages_for :profile_data %> | 3 | <%= error_messages_for :profile_data %> |
5 | 4 | ||
6 | <%= labelled_form_for :profile_data, :html => { :id => 'profile-data', :multipart => true } do |f| %> | 5 | <%= labelled_form_for :profile_data, :html => { :id => 'profile-data', :multipart => true } do |f| %> |
app/views/profile_editor/index.html.erb
@@ -28,6 +28,8 @@ | @@ -28,6 +28,8 @@ | ||
28 | 28 | ||
29 | <%= control_panel_button(_('Manage Content'), 'cms', :controller => 'cms') %> | 29 | <%= control_panel_button(_('Manage Content'), 'cms', :controller => 'cms') %> |
30 | 30 | ||
31 | + <%= control_panel_button(_('Manage Roles'), 'roles', :controller => 'profile_roles') %> | ||
32 | + | ||
31 | <% unless profile.enterprise? %> | 33 | <% unless profile.enterprise? %> |
32 | <%= case profile.blogs.count | 34 | <%= case profile.blogs.count |
33 | when 0 | 35 | when 0 |
app/views/profile_members/change_role.html.erb
1 | <h3> <%= _('Changing role of %s') % @member.name %> </h3> | 1 | <h3> <%= _('Changing role of %s') % @member.name %> </h3> |
2 | 2 | ||
3 | <%= labelled_form_for :member, :url => {:action => 'update_roles'} do |f| %> | 3 | <%= labelled_form_for :member, :url => {:action => 'update_roles'} do |f| %> |
4 | - | ||
5 | - <%= _('Roles:') %> <br> | 4 | + |
5 | + <h4><%= _('Roles:') %></h4> | ||
6 | <% @roles.each do |r| %> | 6 | <% @roles.each do |r| %> |
7 | <%= labelled_check_box(r.name, 'roles[]', r.id, @associations.map(&:role).include?(r) ) %><br/> | 7 | <%= labelled_check_box(r.name, 'roles[]', r.id, @associations.map(&:role).include?(r) ) %><br/> |
8 | <ul class="role-permissions"> | 8 | <ul class="role-permissions"> |
@@ -11,6 +11,17 @@ | @@ -11,6 +11,17 @@ | ||
11 | <% end %> | 11 | <% end %> |
12 | </ul> | 12 | </ul> |
13 | <% end %> | 13 | <% end %> |
14 | + <% unless @custom_roles.empty? %> | ||
15 | + <h4><%= _('Custom Roles:') %></h4> | ||
16 | + <% @custom_roles.each do |r| %> | ||
17 | + <%= labelled_check_box(r.name, 'roles[]', r.id, @associations.map(&:role).include?(r) ) %><br/> | ||
18 | + <ul class="role-permissions"> | ||
19 | + <% r.permissions.each do |p| %> | ||
20 | + <li> <%= permission_name(p) %> </li> | ||
21 | + <% end %> | ||
22 | + </ul> | ||
23 | + <% end %> | ||
24 | + <% end %> | ||
14 | <%= hidden_field_tag 'person', @member.id %> | 25 | <%= hidden_field_tag 'person', @member.id %> |
15 | 26 | ||
16 | <% button_bar do %> | 27 | <% button_bar do %> |
@@ -0,0 +1,22 @@ | @@ -0,0 +1,22 @@ | ||
1 | +<%= error_messages_for :role %> | ||
2 | + | ||
3 | +<%= labelled_form_for :role, :url => (mode == :edit) ? {:action => 'update', :id => role} : {:action => 'create'} do |f| %> | ||
4 | + | ||
5 | + <%= required_fields_message %> | ||
6 | + | ||
7 | + <%= required f.text_field(:name) %> | ||
8 | + | ||
9 | + <% permissions.each do |key| %> | ||
10 | + <div class="permissions <%= key.downcase %>"> | ||
11 | + <h4><%= _('%s Permissions:' % key) %></h4> | ||
12 | + <% ActiveRecord::Base::PERMISSIONS[key].keys.each do |p| %> | ||
13 | + <%= check_box_tag("role[permissions][]", p, role.has_permission?(p), { :id => p }) %> | ||
14 | + <%= content_tag(:label, permission_name(p), { :for => p }) %><br/> | ||
15 | + <% end %> | ||
16 | + </div> | ||
17 | + <% end %> | ||
18 | + | ||
19 | + <% button_bar do %> | ||
20 | + <%= submit_button('save', (mode == :edit) ? _('Save changes') : _('Create role'), :cancel => {:action => 'index'} ) %> | ||
21 | + <% end %> | ||
22 | +<% end %> |
@@ -0,0 +1,35 @@ | @@ -0,0 +1,35 @@ | ||
1 | +<%= javascript_include_tag('assign_role.js') %> | ||
2 | + | ||
3 | +<h1> <%= _("Assign #{@role.name}") %> </h1> | ||
4 | + | ||
5 | + | ||
6 | +<%= labelled_form_for :role, :url => { :action => 'define', :id => @role.id } do |f| %> | ||
7 | + | ||
8 | + <h2> | ||
9 | + <%= _("Assign role by:") %> | ||
10 | + </h2> | ||
11 | + <p> | ||
12 | + <%= labelled_radio_button _("Members"), :assign_role_by, "members", true, :id => "assign_role_by_members", :class => "assign_role_by" %> | ||
13 | + | ||
14 | + <%= labelled_radio_button _("Roles"), :assign_role_by, "roles", false, :id => "assign_role_by_roles", :class => "assign_role_by" %> | ||
15 | + </p> | ||
16 | + <div class="assign_by_members"> | ||
17 | + <%=token_input_field_tag(:person_id, 'search-profile-members', {:action => 'assign_role_by_members'}, | ||
18 | + {:focus => false, :hint_text => _('Select members to assign the role')}) %> | ||
19 | + | ||
20 | + <% button_bar do %> | ||
21 | + <%= submit_button(:forward, _("Confirm")) %> | ||
22 | + <% end %> | ||
23 | + </div> | ||
24 | + <div class="assign_by_roles" style="display: none;"> | ||
25 | + <h6> | ||
26 | + <%= _("Replace role: ") %> | ||
27 | + </h6> | ||
28 | + <% @roles_list.each do |role| %> | ||
29 | + <%= labelled_radio_button role.name , :selected_role, role.id , false, :class => "selected_role" %> <br> | ||
30 | + <% end %> | ||
31 | + <% button_bar do %> | ||
32 | + <%= submit_button('save',_('Confirm'), :cancel => {:action => 'index'} ) %> | ||
33 | + <% end %> | ||
34 | + </div> | ||
35 | +<% end %> |
@@ -0,0 +1,23 @@ | @@ -0,0 +1,23 @@ | ||
1 | +<h1> <%= _("Deleting #{@role.name}") %> </h1> | ||
2 | + | ||
3 | +<% if @members.nil? || @members.empty? %> | ||
4 | + <p><%= _('This role is not being currently used.')%></p> | ||
5 | + <p><%= _('Are you sure you want to delete this role?') %></p> | ||
6 | + | ||
7 | + <% button_bar do %> | ||
8 | + <%= button(:remove, _('Yes, I am sure'), {:action => 'remove', :id => @role.id}, :method => :post) %> | ||
9 | + <%= button(:cancel, _('No, I gave up'), {:action => 'index'}) %> | ||
10 | + <% end %> | ||
11 | +<% else %> | ||
12 | + <p><%= _('There are members currently using this role.')%></p> | ||
13 | + <p><%= _('To which role do you want to change them?') %></p> | ||
14 | + <%= labelled_form_for :role, :url => { :action => 'remove', :id => @role.id } do |f| %> | ||
15 | + <% @roles_list.each do |role| %> | ||
16 | + <%= check_box_tag("roles[]", role.id, false ,{:id => role.key}) %> | ||
17 | + <%= content_tag(:label, role.name, { :for => role.key }) %><br/> | ||
18 | + <% end %> | ||
19 | + <% button_bar do %> | ||
20 | + <%= submit_button('save',_('Delete role'), :cancel => {:action => 'index'} ) %> | ||
21 | + <% end %> | ||
22 | + <% end %> | ||
23 | +<% end %> |
@@ -0,0 +1,27 @@ | @@ -0,0 +1,27 @@ | ||
1 | +<h1><%= _('Manage user roles') %></h1> | ||
2 | + | ||
3 | +<table> | ||
4 | + <tr> | ||
5 | + <th><%= _('Role') %></th> | ||
6 | + <th><%= _('Actions') %></th> | ||
7 | + </tr> | ||
8 | + <% @roles.each do |role| %> | ||
9 | + <tr> | ||
10 | + <td> | ||
11 | + <%= link_to role.name, :action => 'show', :id => role %> | ||
12 | + </td> | ||
13 | + <td> | ||
14 | + <div style="text-align: center;"> | ||
15 | + <%= button_without_text :edit, _('Edit'), :action => 'edit', :id => role %> | ||
16 | + <%= button_without_text :delete, _('Delete'), :action => 'destroy', :id => role %> | ||
17 | + <%= button_without_text 'vertical-toggle', _('Assign'), :action => 'assign', :id => role %> | ||
18 | + </div> | ||
19 | + </td> | ||
20 | + </tr> | ||
21 | + <% end %> | ||
22 | +</table> | ||
23 | + | ||
24 | +<% button_bar do %> | ||
25 | + <%= button :add, _('Create a new role'), :action => 'new' %> | ||
26 | + <%= button :back, _('Back to control panel'), :controller => 'profile_editor' %> | ||
27 | +<% end %> |
@@ -0,0 +1,13 @@ | @@ -0,0 +1,13 @@ | ||
1 | +<h1> <%= _(@role.name) %></h1> | ||
2 | + | ||
3 | +<h3> <%= _('Permissions') %> </h3> | ||
4 | +<ul> | ||
5 | + <% @role.permissions.each do |p| %> | ||
6 | + <li> <%= permission_name(p) %> </li> | ||
7 | + <% end %> | ||
8 | +</ul> | ||
9 | + | ||
10 | +<% button_bar do %> | ||
11 | + <%= button :edit, _('Edit'), :action => 'edit', :id => @role %> | ||
12 | + <%= button :back, _('Back to roles management'), :action => 'index' %> | ||
13 | +<% end %> |
app/views/shared/_profile_search_form.html.erb
1 | +<% search_label = _("Find in %s's content") % profile.short_name %> | ||
1 | <%= form_tag( { :controller => 'profile_search', :profile => profile.identifier}, :method => 'get', :class => 'search_form' ) do %> | 2 | <%= form_tag( { :controller => 'profile_search', :profile => profile.identifier}, :method => 'get', :class => 'search_form' ) do %> |
2 | <div class="search-field"> | 3 | <div class="search-field"> |
3 | <span class="formfield"> | 4 | <span class="formfield"> |
4 | - <%= search_input_with_suggestions 'q', :articles, @q, :title => _("Find in %s's content") % profile.short_name %> | 5 | + <%= search_input_with_suggestions 'q', :articles, @q, :title => search_label, :placeholder => search_label %> |
5 | </span> | 6 | </span> |
6 | <%= submit_button(:search, _('Search')) %> | 7 | <%= submit_button(:search, _('Search')) %> |
7 | <div> | 8 | <div> |
app/views/spam/_suggest_article.html.erb
@@ -7,13 +7,13 @@ | @@ -7,13 +7,13 @@ | ||
7 | <ul class="suggest-article-details" style="display: none"> | 7 | <ul class="suggest-article-details" style="display: none"> |
8 | <li><strong><%=_('Sent by')%></strong>: <%=task.name%> </li> | 8 | <li><strong><%=_('Sent by')%></strong>: <%=task.name%> </li> |
9 | <li><strong><%=_('Email')%></strong>: <%=task.email%> </li> | 9 | <li><strong><%=_('Email')%></strong>: <%=task.email%> </li> |
10 | - <li><strong><%=_('Source')%></strong>: <%=task.source_name%> </li> | ||
11 | - <li><strong><%=_('Source URL')%></strong>: <%=task.source%> </li> | ||
12 | - <li><strong><%=_('Folder')%></strong>: <%=(a = Article.find_by_id(task.article_parent_id))?a.name : '<em>' + s_('Folder|none') + '</em>'%> </li> | ||
13 | - <li><strong><%=_('Lead')%></strong>: <%=task.article_abstract.blank? ? '<em>' + s_('Abstract|empty') + '</em>' : task.article_abstract%> </li> | 10 | + <li><strong><%=_('Source')%></strong>: <%=task.article_object.source_name%> </li> |
11 | + <li><strong><%=_('Source URL')%></strong>: <%=task.article_object.source%> </li> | ||
12 | + <li><strong><%=_('Folder')%></strong>: <%=(a = Article.find_by_id(task.article_object.parent_id))?a.name : '<em>' + s_('Folder|none') + '</em>'%> </li> | ||
13 | + <li><strong><%=_('Lead')%></strong>: <%=task.article_object.abstract.blank? ? '<em>' + s_('Abstract|empty') + '</em>' : task.article_object.abstract%> </li> | ||
14 | <li><strong><%=_('Body')%></strong>: | 14 | <li><strong><%=_('Body')%></strong>: |
15 | <div class='suggest-article-body'> | 15 | <div class='suggest-article-body'> |
16 | - <%= task.article_body %> | 16 | + <%= task.article_object.body %> |
17 | </div> | 17 | </div> |
18 | </li> | 18 | </li> |
19 | </ul> | 19 | </ul> |
app/views/tasks/_add_member_accept_details.html.erb
1 | <%= content = _("Roles:")+"<br />" | 1 | <%= content = _("Roles:")+"<br />" |
2 | -roles = Profile::Roles.organization_member_roles(task.target.environment.id) | 2 | +roles = Profile::Roles.organization_member_roles(task.target.environment.id) + profile.custom_roles |
3 | roles.each do |role| | 3 | roles.each do |role| |
4 | content += labelled_check_box(role.name, "tasks[#{task.id}][task][roles][]", role.id, false)+"<br />" | 4 | content += labelled_check_box(role.name, "tasks[#{task.id}][task][roles][]", role.id, false)+"<br />" |
5 | end | 5 | end |
6 | content_tag('p', content, :class => 'member-classify-suggestion') | 6 | content_tag('p', content, :class => 'member-classify-suggestion') |
7 | %> | 7 | %> |
8 | - |
app/views/tasks/_suggest_article_accept_details.html.erb
1 | <%= render :file => 'shared/tiny_mce' %> | 1 | <%= render :file => 'shared/tiny_mce' %> |
2 | 2 | ||
3 | -<%= labelled_form_field(_("Sent by: "), f.text_field(:name)) %> | ||
4 | -<p><%= label_tag(_("Email: %s") % task.email) %> </p> | ||
5 | -<%= required labelled_form_field(_('Title'), f.text_field(:article_name, :size => 50)) %> | ||
6 | -<%= labelled_form_field(_('Source'), f.text_field(:source_name)) %> | ||
7 | -<%= labelled_form_field(_("Source URL"), f.text_field(:source)) %> | 3 | +<% unless task.requestor %> |
4 | + <%= labelled_form_field(_("Sent by: "), f.text_field(:name)) %> | ||
5 | + <p><%= label_tag(_("Email: %s") % task.email) %> </p> | ||
6 | +<% end %> | ||
8 | 7 | ||
9 | -<%= select_profile_folder(_('Select the folder where the article must be published'), "tasks[#{task.id}][task][article_parent_id]", task.target) %> | ||
10 | -<%= labelled_form_field(_('Highlight this article'), f.check_box(:highlighted)) %> | 8 | +<%= f.fields_for 'article', OpenStruct.new(task.article) do |a| %> |
9 | + <%= required labelled_form_field(_('Title'), a.text_field(:name, :size => 50)) %> | ||
10 | + <%= labelled_form_field(_('Source'), a.text_field(:source_name)) %> | ||
11 | + <%= labelled_form_field(_("Source URL"), a.text_field(:source)) %> | ||
11 | 12 | ||
12 | -<%= render :partial => 'shared/lead_and_body', :locals => {:tiny_mce => true, :f => f, :abstract_method => 'article_abstract', :body_method => 'article_body', :lead_id => task.id} %> | 13 | + <%= select_profile_folder(_('Select the folder where the article must be published'), "tasks[#{task.id}][task][article][parent_id]", task.target, task.article[:parent_id]) %> |
14 | + <%= labelled_form_field(_('Highlight this article'), a.check_box(:highlighted)) %> | ||
15 | + | ||
16 | + <%= a.hidden_field(:type) %> | ||
17 | + | ||
18 | + <%= render :partial => 'shared/lead_and_body', :locals => {:tiny_mce => true, :f => a, :lead_id => task.id} %> | ||
19 | +<% end %> |
app/views/user_mailer/profiles_suggestions_email.html.erb
@@ -10,8 +10,8 @@ | @@ -10,8 +10,8 @@ | ||
10 | <% @people_suggestions.each do |person| %> | 10 | <% @people_suggestions.each do |person| %> |
11 | <li><a href="<%= url_for(person.public_profile_url) %>"><%= person.name %></a></li> | 11 | <li><a href="<%= url_for(person.public_profile_url) %>"><%= person.name %></a></li> |
12 | <% end %> | 12 | <% end %> |
13 | - <ul> | ||
14 | - <%= _("To see the full list of friends suggestions, follow the link: %s") % @people_suggestions_url %> | 13 | + </ul> |
14 | + <%= _("To see the full list of friends suggestions, follow the link: %s") % url_for(@people_suggestions_url) %> | ||
15 | <% end %> | 15 | <% end %> |
16 | 16 | ||
17 | <% unless @communities_suggestions.empty? %> | 17 | <% unless @communities_suggestions.empty? %> |
@@ -21,13 +21,15 @@ | @@ -21,13 +21,15 @@ | ||
21 | <% @communities_suggestions.each do |community| %> | 21 | <% @communities_suggestions.each do |community| %> |
22 | <li><a href="<%= url_for(community.public_profile_url) %>"><%= community.name %></a></li> | 22 | <li><a href="<%= url_for(community.public_profile_url) %>"><%= community.name %></a></li> |
23 | <% end %> | 23 | <% end %> |
24 | - <ul> | ||
25 | - <%= _("To see the full list of communities suggestions, follow the link: %s") % @communities_suggestions_url %> | 24 | + </ul> |
25 | + <%= _("To see the full list of communities suggestions, follow the link: %s") % url_for(@communities_suggestions_url) %> | ||
26 | <% end %> | 26 | <% end %> |
27 | 27 | ||
28 | 28 | ||
29 | <%= _("Greetings,") %> | 29 | <%= _("Greetings,") %> |
30 | 30 | ||
31 | --- | ||
32 | -<%= _('%s team.') % @environment %> | 31 | +<p><%= _("Greetings,") %></p> |
32 | + | ||
33 | +--<br/> | ||
34 | +<%= _('%s team.') % @environment %><br/> | ||
33 | <%= @url %> | 35 | <%= @url %> |
config/environments/development.rb
@@ -35,4 +35,8 @@ Noosfero::Application.configure do | @@ -35,4 +35,8 @@ Noosfero::Application.configure do | ||
35 | config.assets.debug = true | 35 | config.assets.debug = true |
36 | 36 | ||
37 | config.consider_all_requests_local = true | 37 | config.consider_all_requests_local = true |
38 | + | ||
39 | + # send emails to /tmp/mails | ||
40 | + config.action_mailer.delivery_method = :file | ||
41 | + | ||
38 | end | 42 | end |
config/routes.rb
@@ -56,37 +56,37 @@ Noosfero::Application.routes.draw do | @@ -56,37 +56,37 @@ Noosfero::Application.routes.draw do | ||
56 | match 'search(/:action(/*category_path))', :controller => 'search' | 56 | match 'search(/:action(/*category_path))', :controller => 'search' |
57 | 57 | ||
58 | # events | 58 | # events |
59 | - match 'profile/:profile/events_by_day', :controller => 'events', :action => 'events_by_day', :profile => /#{Noosfero.identifier_format}/ | ||
60 | - match 'profile/:profile/events_by_month', :controller => 'events', :action => 'events_by_month', :profile => /#{Noosfero.identifier_format}/ | ||
61 | - match 'profile/:profile/events/:year/:month/:day', :controller => 'events', :action => 'events', :year => /\d*/, :month => /\d*/, :day => /\d*/, :profile => /#{Noosfero.identifier_format}/ | ||
62 | - match 'profile/:profile/events/:year/:month', :controller => 'events', :action => 'events', :year => /\d*/, :month => /\d*/, :profile => /#{Noosfero.identifier_format}/ | ||
63 | - match 'profile/:profile/events', :controller => 'events', :action => 'events', :profile => /#{Noosfero.identifier_format}/ | 59 | + match 'profile/:profile/events_by_day', :controller => 'events', :action => 'events_by_day', :profile => /#{Noosfero.identifier_format_in_url}/ |
60 | + match 'profile/:profile/events_by_month', :controller => 'events', :action => 'events_by_month', :profile => /#{Noosfero.identifier_format_in_url}/ | ||
61 | + match 'profile/:profile/events/:year/:month/:day', :controller => 'events', :action => 'events', :year => /\d*/, :month => /\d*/, :day => /\d*/, :profile => /#{Noosfero.identifier_format_in_url}/ | ||
62 | + match 'profile/:profile/events/:year/:month', :controller => 'events', :action => 'events', :year => /\d*/, :month => /\d*/, :profile => /#{Noosfero.identifier_format_in_url}/ | ||
63 | + match 'profile/:profile/events', :controller => 'events', :action => 'events', :profile => /#{Noosfero.identifier_format_in_url}/ | ||
64 | 64 | ||
65 | # catalog | 65 | # catalog |
66 | - match 'catalog/:profile', :controller => 'catalog', :action => 'index', :profile => /#{Noosfero.identifier_format}/, :as => :catalog | 66 | + match 'catalog/:profile', :controller => 'catalog', :action => 'index', :profile => /#{Noosfero.identifier_format_in_url}/, :as => :catalog |
67 | 67 | ||
68 | # invite | 68 | # invite |
69 | - match 'profile/:profile/invite/friends', :controller => 'invite', :action => 'invite_friends', :profile => /#{Noosfero.identifier_format}/ | ||
70 | - match 'profile/:profile/invite/:action', :controller => 'invite', :profile => /#{Noosfero.identifier_format}/ | 69 | + match 'profile/:profile/invite/friends', :controller => 'invite', :action => 'invite_friends', :profile => /#{Noosfero.identifier_format_in_url}/ |
70 | + match 'profile/:profile/invite/:action', :controller => 'invite', :profile => /#{Noosfero.identifier_format_in_url}/ | ||
71 | 71 | ||
72 | # feeds per tag | 72 | # feeds per tag |
73 | - match 'profile/:profile/tags/:id/feed', :controller => 'profile', :action =>'tag_feed', :id => /.+/, :profile => /#{Noosfero.identifier_format}/, :as => :tag_feed | 73 | + match 'profile/:profile/tags/:id/feed', :controller => 'profile', :action =>'tag_feed', :id => /.+/, :profile => /#{Noosfero.identifier_format_in_url}/, :as => :tag_feed |
74 | 74 | ||
75 | # profile tags | 75 | # profile tags |
76 | - match 'profile/:profile/tags/:id', :controller => 'profile', :action => 'content_tagged', :id => /.+/, :profile => /#{Noosfero.identifier_format}/ | ||
77 | - match 'profile/:profile/tags(/:id)', :controller => 'profile', :action => 'tags', :profile => /#{Noosfero.identifier_format}/ | 76 | + match 'profile/:profile/tags/:id', :controller => 'profile', :action => 'content_tagged', :id => /.+/, :profile => /#{Noosfero.identifier_format_in_url}/ |
77 | + match 'profile/:profile/tags(/:id)', :controller => 'profile', :action => 'tags', :profile => /#{Noosfero.identifier_format_in_url}/ | ||
78 | 78 | ||
79 | # profile search | 79 | # profile search |
80 | - match 'profile/:profile/search', :controller => 'profile_search', :action => 'index', :profile => /#{Noosfero.identifier_format}/ | 80 | + match 'profile/:profile/search', :controller => 'profile_search', :action => 'index', :profile => /#{Noosfero.identifier_format_in_url}/ |
81 | 81 | ||
82 | # comments | 82 | # comments |
83 | - match 'profile/:profile/comment/:action/:id', :controller => 'comment', :profile => /#{Noosfero.identifier_format}/ | 83 | + match 'profile/:profile/comment/:action/:id', :controller => 'comment', :profile => /#{Noosfero.identifier_format_in_url}/ |
84 | 84 | ||
85 | # public profile information | 85 | # public profile information |
86 | - match 'profile/:profile(/:action(/:id))', :controller => 'profile', :action => 'index', :id => /[^\/]*/, :profile => /#{Noosfero.identifier_format}/, :as => :profile | 86 | + match 'profile/:profile(/:action(/:id))', :controller => 'profile', :action => 'index', :id => /[^\/]*/, :profile => /#{Noosfero.identifier_format_in_url}/, :as => :profile |
87 | 87 | ||
88 | # contact | 88 | # contact |
89 | - match 'contact/:profile/:action(/:id)', :controller => 'contact', :action => 'index', :id => /.*/, :profile => /#{Noosfero.identifier_format}/ | 89 | + match 'contact/:profile/:action(/:id)', :controller => 'contact', :action => 'index', :id => /.*/, :profile => /#{Noosfero.identifier_format_in_url}/ |
90 | 90 | ||
91 | # map balloon | 91 | # map balloon |
92 | match 'map_balloon/:action/:id', :controller => 'map_balloon', :id => /.*/ | 92 | match 'map_balloon/:action/:id', :controller => 'map_balloon', :id => /.*/ |
@@ -98,8 +98,8 @@ Noosfero::Application.routes.draw do | @@ -98,8 +98,8 @@ Noosfero::Application.routes.draw do | ||
98 | ## Controllers that are profile-specific (for profile admins ) | 98 | ## Controllers that are profile-specific (for profile admins ) |
99 | ###################################################### | 99 | ###################################################### |
100 | # profile customization - "My profile" | 100 | # profile customization - "My profile" |
101 | - match 'myprofile/:profile', :controller => 'profile_editor', :action => 'index', :profile => /#{Noosfero.identifier_format}/ | ||
102 | - match 'myprofile/:profile/:controller(/:action(/:id))', :controller => Noosfero.pattern_for_controllers_in_directory('my_profile'), :profile => /#{Noosfero.identifier_format}/, :as => :myprofile | 101 | + match 'myprofile/:profile', :controller => 'profile_editor', :action => 'index', :profile => /#{Noosfero.identifier_format_in_url}/ |
102 | + match 'myprofile/:profile/:controller(/:action(/:id))', :controller => Noosfero.pattern_for_controllers_in_directory('my_profile'), :profile => /#{Noosfero.identifier_format_in_url}/, :as => :myprofile | ||
103 | 103 | ||
104 | 104 | ||
105 | ###################################################### | 105 | ###################################################### |
@@ -127,14 +127,14 @@ Noosfero::Application.routes.draw do | @@ -127,14 +127,14 @@ Noosfero::Application.routes.draw do | ||
127 | # cache stuff - hack | 127 | # cache stuff - hack |
128 | match 'public/:action/:id', :controller => 'public' | 128 | match 'public/:action/:id', :controller => 'public' |
129 | 129 | ||
130 | - match ':profile/*page/versions', :controller => 'content_viewer', :action => 'article_versions', :profile => /#{Noosfero.identifier_format}/, :constraints => EnvironmentDomainConstraint.new | 130 | + match ':profile/*page/versions', :controller => 'content_viewer', :action => 'article_versions', :profile => /#{Noosfero.identifier_format_in_url}/, :constraints => EnvironmentDomainConstraint.new |
131 | match '*page/versions', :controller => 'content_viewer', :action => 'article_versions' | 131 | match '*page/versions', :controller => 'content_viewer', :action => 'article_versions' |
132 | 132 | ||
133 | - match ':profile/*page/versions_diff', :controller => 'content_viewer', :action => 'versions_diff', :profile => /#{Noosfero.identifier_format}/, :constraints => EnvironmentDomainConstraint.new | 133 | + match ':profile/*page/versions_diff', :controller => 'content_viewer', :action => 'versions_diff', :profile => /#{Noosfero.identifier_format_in_url}/, :constraints => EnvironmentDomainConstraint.new |
134 | match '*page/versions_diff', :controller => 'content_viewer', :action => 'versions_diff' | 134 | match '*page/versions_diff', :controller => 'content_viewer', :action => 'versions_diff' |
135 | 135 | ||
136 | # match requests for profiles that don't have a custom domain | 136 | # match requests for profiles that don't have a custom domain |
137 | - match ':profile(/*page)', :controller => 'content_viewer', :action => 'view_page', :profile => /#{Noosfero.identifier_format}/, :constraints => EnvironmentDomainConstraint.new | 137 | + match ':profile(/*page)', :controller => 'content_viewer', :action => 'view_page', :profile => /#{Noosfero.identifier_format_in_url}/, :constraints => EnvironmentDomainConstraint.new |
138 | 138 | ||
139 | # match requests for content in domains hosted for profiles | 139 | # match requests for content in domains hosted for profiles |
140 | match '/(*page)', :controller => 'content_viewer', :action => 'view_page' | 140 | match '/(*page)', :controller => 'content_viewer', :action => 'view_page' |
db/migrate/20150210143723_add_custom_roles_permission_to_admin_roles.rb
0 → 100644
@@ -0,0 +1,18 @@ | @@ -0,0 +1,18 @@ | ||
1 | +class AddCustomRolesPermissionToAdminRoles < ActiveRecord::Migration | ||
2 | + def self.up | ||
3 | + environment_admin = Role.find_by_key("environment_administrator") | ||
4 | + profile_admin = Role.find_by_key("profile_admin") | ||
5 | + environment_admin.permissions.append("manage_custom_roles") | ||
6 | + profile_admin.permissions.append("manage_custom_roles") | ||
7 | + environment_admin.save! | ||
8 | + profile_admin.save! | ||
9 | + end | ||
10 | + def self.down | ||
11 | + environment_admin = Role.find_by_key("environment_administrator") | ||
12 | + profile_admin = Role.find_by_key("profile_admin") | ||
13 | + environment_admin.permissions.delete("manage_custom_roles") | ||
14 | + profile_admin.permissions.delete("manage_custom_roles") | ||
15 | + environment_admin.save! | ||
16 | + profile_admin.save! | ||
17 | + end | ||
18 | +end |
db/migrate/20150423144533_add_new_box_to_every_environment_and_profile.rb
0 → 100644
@@ -0,0 +1,15 @@ | @@ -0,0 +1,15 @@ | ||
1 | +class AddNewBoxToEveryEnvironmentAndProfile < ActiveRecord::Migration | ||
2 | + def up | ||
3 | + Environment.find_each do |env| | ||
4 | + env.boxes << Box.new if env.boxes.count < 4 | ||
5 | + end | ||
6 | + | ||
7 | + Profile.find_each do |profile| | ||
8 | + profile.boxes << Box.new if profile.boxes.count < 4 | ||
9 | + end | ||
10 | + end | ||
11 | + | ||
12 | + def down | ||
13 | + say "this migration can't be reverted" | ||
14 | + end | ||
15 | +end |
db/schema.rb
@@ -593,6 +593,7 @@ ActiveRecord::Schema.define(:version => 20150408231524) do | @@ -593,6 +593,7 @@ ActiveRecord::Schema.define(:version => 20150408231524) do | ||
593 | t.boolean "system", :default => false | 593 | t.boolean "system", :default => false |
594 | t.text "permissions" | 594 | t.text "permissions" |
595 | t.integer "environment_id" | 595 | t.integer "environment_id" |
596 | + t.integer "profile_id" | ||
596 | end | 597 | end |
597 | 598 | ||
598 | create_table "scraps", :force => true do |t| | 599 | create_table "scraps", :force => true do |t| |
debian/changelog
1 | +noosfero (1.2~0) UNRELEASED; urgency=medium | ||
2 | + | ||
3 | + * Temporary version in heavy development | ||
4 | + | ||
5 | + -- Antonio Terceiro <terceiro@debian.org> Fri, 08 May 2015 16:08:18 -0300 | ||
6 | + | ||
7 | +noosfero (1.1) wheezy; urgency=low | ||
8 | + | ||
9 | + * Noosfero 1.1 final release | ||
10 | + | ||
11 | + -- Antonio Terceiro <terceiro@colivre.coop.br> Mon, 04 May 2015 18:47:35 -0300 | ||
12 | + | ||
1 | noosfero (1.1~rc4) wheezy; urgency=medium | 13 | noosfero (1.1~rc4) wheezy; urgency=medium |
2 | 14 | ||
3 | * Fourth release candidate for Noosfero 1.1 | 15 | * Fourth release candidate for Noosfero 1.1 |
debian/control
@@ -14,8 +14,8 @@ Build-Depends: cucumber, | @@ -14,8 +14,8 @@ Build-Depends: cucumber, | ||
14 | ruby-database-cleaner, | 14 | ruby-database-cleaner, |
15 | ruby-gettext, | 15 | ruby-gettext, |
16 | ruby-mocha, | 16 | ruby-mocha, |
17 | - ruby-rspec, | ||
18 | - ruby-rspec-rails, | 17 | + ruby-rspec (>= 2.14), |
18 | + ruby-rspec-rails (>= 2.14), | ||
19 | ruby-selenium-webdriver, | 19 | ruby-selenium-webdriver, |
20 | ruby-sqlite3, | 20 | ruby-sqlite3, |
21 | ruby-tidy, | 21 | ruby-tidy, |
@@ -59,7 +59,9 @@ Depends: adduser, | @@ -59,7 +59,9 @@ Depends: adduser, | ||
59 | ruby-redcloth, | 59 | ruby-redcloth, |
60 | ruby-rest-client, | 60 | ruby-rest-client, |
61 | ruby-rmagick, | 61 | ruby-rmagick, |
62 | + ruby-sass-rails, | ||
62 | ruby-tzinfo (>= 1.1.0-2~), | 63 | ruby-tzinfo (>= 1.1.0-2~), |
64 | + ruby-uglifier, | ||
63 | ruby-whenever, | 65 | ruby-whenever, |
64 | ruby-will-paginate (>= 2.3.12-1~), | 66 | ruby-will-paginate (>= 2.3.12-1~), |
65 | tango-icon-theme, | 67 | tango-icon-theme, |
debian/noosfero.install
@@ -25,6 +25,7 @@ etc/init.d/noosfero etc/init.d | @@ -25,6 +25,7 @@ etc/init.d/noosfero etc/init.d | ||
25 | etc/logrotate.d/noosfero etc/logrotate.d | 25 | etc/logrotate.d/noosfero etc/logrotate.d |
26 | etc/noosfero/varnish-accept-language.vcl etc/noosfero | 26 | etc/noosfero/varnish-accept-language.vcl etc/noosfero |
27 | etc/noosfero/varnish-noosfero.vcl etc/noosfero | 27 | etc/noosfero/varnish-noosfero.vcl etc/noosfero |
28 | +etc/awstats-noosfero.conf etc/noosfero | ||
28 | lib usr/share/noosfero | 29 | lib usr/share/noosfero |
29 | locale usr/share/noosfero | 30 | locale usr/share/noosfero |
30 | plugins usr/share/noosfero | 31 | plugins usr/share/noosfero |
@@ -0,0 +1,20 @@ | @@ -0,0 +1,20 @@ | ||
1 | +Feature: Change appearance | ||
2 | + As a user | ||
3 | + I want to change the appearance of my profile page | ||
4 | + | ||
5 | + Background: | ||
6 | + Given the following users | ||
7 | + | login | name | | ||
8 | + | joaosilva | Joao Silva | | ||
9 | + | ||
10 | + Scenario: Change appearance from default(3 boxes) to Left Top and Right(4 boxes) | ||
11 | + Given I am logged in as "joaosilva" | ||
12 | + And I go to joaosilva's control panel | ||
13 | + And I follow "Edit sideboxes" | ||
14 | + And I should not see an element ".box-4" | ||
15 | + And I go to joaosilva's control panel | ||
16 | + And I follow "Edit Appearance" | ||
17 | + And I follow "Left Top and Right" | ||
18 | + And I go to joaosilva's control panel | ||
19 | + And I follow "Edit sideboxes" | ||
20 | + And I should see an element ".box-4" |
features/signup.feature
@@ -267,32 +267,6 @@ Feature: signup | @@ -267,32 +267,6 @@ Feature: signup | ||
267 | Then I should be on the homepage | 267 | Then I should be on the homepage |
268 | 268 | ||
269 | @selenium | 269 | @selenium |
270 | - Scenario: join community on signup | ||
271 | - Given the following users | ||
272 | - | login | name | | ||
273 | - | mariasilva | Maria Silva | | ||
274 | - And the following communities | ||
275 | - | name | identifier | owner | | ||
276 | - | Free Software | freesoftware | mariasilva | | ||
277 | - And feature "skip_new_user_email_confirmation" is disabled on environment | ||
278 | - And I am on /freesoftware | ||
279 | - When I follow "Join" | ||
280 | - And I follow "New user" | ||
281 | - And I fill in the following within ".no-boxes": | ||
282 | - | e-Mail | josesilva@example.com | | ||
283 | - | Username | josesilva | | ||
284 | - | Password | secret | | ||
285 | - | Password confirmation | secret | | ||
286 | - | Full name | José da Silva | | ||
287 | - And wait for the captcha signup time | ||
288 | - And I press "Create my account" | ||
289 | - And I go to josesilva's confirmation URL | ||
290 | - And I fill in "Username" with "josesilva" | ||
291 | - And I fill in "Password" with "secret" | ||
292 | - And I press "Log in" | ||
293 | - Then "José da Silva" should be a member of "Free Software" | ||
294 | - | ||
295 | - @selenium | ||
296 | Scenario: user registration is moderated by admin | 270 | Scenario: user registration is moderated by admin |
297 | Given feature "admin_must_approve_new_users" is enabled on environment | 271 | Given feature "admin_must_approve_new_users" is enabled on environment |
298 | And feature "skip_new_user_email_confirmation" is disabled on environment | 272 | And feature "skip_new_user_email_confirmation" is disabled on environment |
features/step_definitions/noosfero_steps.rb
@@ -94,8 +94,8 @@ Given /^the following blocks$/ do |table| | @@ -94,8 +94,8 @@ Given /^the following blocks$/ do |table| | ||
94 | owner.boxes<< Box.new | 94 | owner.boxes<< Box.new |
95 | owner.boxes.first.blocks << MainBlock.new | 95 | owner.boxes.first.blocks << MainBlock.new |
96 | end | 96 | end |
97 | - box_id = owner.boxes.last.id | ||
98 | - klass.constantize.create!(item.merge(:box_id => box_id)) | 97 | + box = owner.boxes.where(:position => 3).first |
98 | + klass.constantize.create!(item.merge(:box => box)) | ||
99 | end | 99 | end |
100 | end | 100 | end |
101 | 101 |
lib/authenticated_system.rb
@@ -60,7 +60,11 @@ module AuthenticatedSystem | @@ -60,7 +60,11 @@ module AuthenticatedSystem | ||
60 | if logged_in? && authorized? | 60 | if logged_in? && authorized? |
61 | true | 61 | true |
62 | else | 62 | else |
63 | - access_denied | 63 | + if params[:require_login_popup] |
64 | + render :json => { :require_login_popup => true } | ||
65 | + else | ||
66 | + access_denied | ||
67 | + end | ||
64 | end | 68 | end |
65 | end | 69 | end |
66 | 70 |
lib/noosfero.rb
@@ -57,6 +57,12 @@ module Noosfero | @@ -57,6 +57,12 @@ module Noosfero | ||
57 | '[a-z0-9][a-z0-9~.]*([_\-][a-z0-9~.]+)*' | 57 | '[a-z0-9][a-z0-9~.]*([_\-][a-z0-9~.]+)*' |
58 | end | 58 | end |
59 | 59 | ||
60 | + # All valid identifiers, plus ~ meaning "the current user". See | ||
61 | + # ApplicationController#redirect_to_current_user | ||
62 | + def self.identifier_format_in_url | ||
63 | + "(#{identifier_format}|~)" | ||
64 | + end | ||
65 | + | ||
60 | def self.default_hostname | 66 | def self.default_hostname |
61 | Environment.table_exists? && Environment.default ? Environment.default.default_hostname : 'localhost' | 67 | Environment.table_exists? && Environment.default ? Environment.default.default_hostname : 'localhost' |
62 | end | 68 | end |
lib/noosfero/plugin.rb
@@ -8,6 +8,10 @@ class Noosfero::Plugin | @@ -8,6 +8,10 @@ class Noosfero::Plugin | ||
8 | self.context = context | 8 | self.context = context |
9 | end | 9 | end |
10 | 10 | ||
11 | + def environment | ||
12 | + context.environment if self.context | ||
13 | + end | ||
14 | + | ||
11 | class << self | 15 | class << self |
12 | 16 | ||
13 | attr_writer :should_load | 17 | attr_writer :should_load |
@@ -35,6 +39,7 @@ class Noosfero::Plugin | @@ -35,6 +39,7 @@ class Noosfero::Plugin | ||
35 | # filters must be loaded after all extensions | 39 | # filters must be loaded after all extensions |
36 | klasses.each do |plugin| | 40 | klasses.each do |plugin| |
37 | load_plugin_filters plugin | 41 | load_plugin_filters plugin |
42 | + load_plugin_hotspots plugin | ||
38 | end | 43 | end |
39 | end | 44 | end |
40 | 45 | ||
@@ -108,6 +113,23 @@ class Noosfero::Plugin | @@ -108,6 +113,23 @@ class Noosfero::Plugin | ||
108 | end | 113 | end |
109 | end | 114 | end |
110 | 115 | ||
116 | + # This is a generic method to extend the hotspots list with plugins | ||
117 | + # hotspots. This allows plugins to extend other plugins. | ||
118 | + # To use this, the plugin must define its hotspots inside a module Hotspots. | ||
119 | + # Its also needed to include Noosfero::Plugin::HotSpot module | ||
120 | + # in order to dispatch plugins methods. | ||
121 | + # | ||
122 | + # Checkout FooPlugin for usage example. | ||
123 | + def load_plugin_hotspots(plugin) | ||
124 | + ActionDispatch::Reloader.to_prepare do | ||
125 | + begin | ||
126 | + module_name = "#{plugin.name}::Hotspots" | ||
127 | + Noosfero::Plugin.send(:include, module_name.constantize) | ||
128 | + rescue NameError | ||
129 | + end | ||
130 | + end | ||
131 | + end | ||
132 | + | ||
111 | def add_controller_filters(controller_class, plugin, filters) | 133 | def add_controller_filters(controller_class, plugin, filters) |
112 | unless filters.is_a?(Array) | 134 | unless filters.is_a?(Array) |
113 | filters = [filters] | 135 | filters = [filters] |
lib/noosfero/version.rb
lib/tasks/backup.rake
1 | -desc "Creates a backup of the user files stored in public/" | ||
2 | -task :backup do | ||
3 | - dirs = Dir.glob('public/images/[0-9][0-9][0-9][0-9]') + ['public/articles', 'public/thumbnails', 'public/user_themes'].select { |d| File.exists?(d) } | ||
4 | - tarball = 'backups/files-' + Time.now.strftime('%Y-%m-%d-%R') + '.tar' | 1 | +task :load_backup_config do |
2 | + $config = YAML.load_file('config/database.yml') | ||
3 | +end | ||
4 | + | ||
5 | +task :check_backup_support => :load_backup_config do | ||
6 | + if $config['production']['adapter'] != 'postgresql' | ||
7 | + fail("Only PostgreSQL is supported for backups at the moment") | ||
8 | + end | ||
9 | +end | ||
10 | + | ||
11 | +backup_dirs = [ | ||
12 | + 'public/image_uploads', | ||
13 | + 'public/articles', | ||
14 | + 'public/thumbnails', | ||
15 | + 'public/user_themes', | ||
16 | +] | ||
17 | + | ||
18 | +desc "Creates a backup of the database and uploaded files" | ||
19 | +task :backup => :check_backup_support do | ||
20 | + dirs = backup_dirs.select { |d| File.exists?(d) } | ||
21 | + | ||
22 | + backup_name = Time.now.strftime('%Y-%m-%d-%R') | ||
23 | + backup_file = File.join('tmp/backup', backup_name) + '.tar.gz' | ||
24 | + mkdir_p 'tmp/backup' | ||
25 | + dump = File.join('tmp/backup', backup_name) + '.sql' | ||
26 | + | ||
27 | + database = $config['production']['database'] | ||
28 | + host = $config['production']['host'] | ||
29 | + sh "pg_dump -h #{host} #{database} > #{dump}" | ||
30 | + | ||
31 | + sh 'tar', 'chaf', backup_file, dump, *dirs | ||
32 | + rm_f dump | ||
33 | + | ||
34 | + puts "****************************************************" | ||
35 | + puts "Backup in #{backup_file} !" | ||
36 | + puts | ||
37 | + puts "To restore, use:" | ||
38 | + puts "$ rake restore BACKUP=#{backup_file}" | ||
39 | + puts "****************************************************" | ||
40 | +end | ||
41 | + | ||
42 | +def invalid_backup!(message, items=[]) | ||
43 | + puts "E: #{message}" | ||
44 | + items.each do |i| | ||
45 | + puts "E: - #{i}" | ||
46 | + end | ||
47 | + puts "E: Is this a backup archive created by Noosfero with \`rake backup\`?" | ||
48 | + exit 1 | ||
49 | +end | ||
50 | + | ||
51 | +desc "Restores a backup created previousy with \`rake backup\`" | ||
52 | +task :restore => :check_backup_support do | ||
53 | + backup = ENV["BACKUP"] | ||
54 | + unless backup | ||
55 | + puts "usage: rake restore BACKUP=/path/to/backup" | ||
56 | + exit 1 | ||
57 | + end | ||
58 | + | ||
59 | + files = `tar taf #{backup}`.split | ||
60 | + | ||
61 | + # validate files in the backup | ||
62 | + invalid_files = [] | ||
63 | + files.each do |f| | ||
64 | + if f !~ /tmp\/backup\// && (backup_dirs.none? { |d| f =~ /^#{d}\// }) | ||
65 | + invalid_files << f | ||
66 | + end | ||
67 | + end | ||
68 | + if invalid_files.size > 0 | ||
69 | + invalid_backup!("Invalid files found in the backup archive", invalid_files) | ||
70 | + end | ||
71 | + | ||
72 | + # find database dump in the archive | ||
73 | + dumps = files.select do |f| | ||
74 | + File.dirname(f) == 'tmp/backup' && f =~ /\.sql$/ | ||
75 | + end | ||
76 | + if dumps.size == 0 | ||
77 | + invalid_backup!("Could not find a database dump in the archive.") | ||
78 | + elsif dumps.size > 1 | ||
79 | + invalid_backup!("Multiple database dumps found in the archive:", dumps) | ||
80 | + end | ||
81 | + dump = dumps.first | ||
82 | + | ||
83 | + database = $config['production']['database'] | ||
84 | + username = $config['production']['username'] | ||
85 | + host = $config['production']['host'] | ||
86 | + | ||
87 | + puts "WARNING: backups should be restored to an empty database, otherwise" | ||
88 | + puts "data from the backup may not be loaded properly." | ||
89 | + puts | ||
90 | + puts 'You can remove the existing database and create a new one with:' | ||
91 | + puts | ||
92 | + puts "$ sudo -u postgres dropdb -h #{host} #{database}" | ||
93 | + puts "$ sudo -u postgres createdb -h #{host} #{database} --owner #{username}" | ||
94 | + puts | ||
95 | + print "Are you sure you want to continue (y/N)? " | ||
96 | + response = $stdin.gets.strip | ||
97 | + unless ['y', 'yes'].include?(response.downcase) | ||
98 | + puts "*** ABORTED." | ||
99 | + exit 1 | ||
100 | + end | ||
101 | + | ||
102 | + sh 'tar', 'xaf', backup | ||
103 | + sh "rails dbconsole production < #{dump}" | ||
104 | + rm_f dump | ||
5 | 105 | ||
6 | - mkdir_p(File.dirname(tarball)) | ||
7 | - sh('tar', 'cf', tarball, *dirs) | 106 | + puts "****************************************************" |
107 | + puts "Backup restored!" | ||
108 | + puts "****************************************************" | ||
8 | end | 109 | end |
lib/tasks/doc.rake
@@ -12,9 +12,8 @@ namespace :noosfero do | @@ -12,9 +12,8 @@ namespace :noosfero do | ||
12 | end | 12 | end |
13 | end | 13 | end |
14 | task :unlink_plugins_textiles do | 14 | task :unlink_plugins_textiles do |
15 | - root = Pathname.new(File.dirname(__FILE__) + '/../..').expand_path | ||
16 | - rm_f Dir.glob(root.join('doc/noosfero/plugins/*.textile')) - | ||
17 | - [root.join('doc/noosfero/plugins/index.textile')] | 15 | + rm_f Dir.glob('doc/noosfero/plugins/*.textile') - |
16 | + ['doc/noosfero/plugins/index.textile'] | ||
18 | end | 17 | end |
19 | input = Dir.glob('doc/noosfero/**/*.textile') + plugins_textiles.map{|i| "doc/noosfero/plugins/#{File.basename(i)}"} | 18 | input = Dir.glob('doc/noosfero/**/*.textile') + plugins_textiles.map{|i| "doc/noosfero/plugins/#{File.basename(i)}"} |
20 | topics_xhtml = input.map { |item| item.sub('.textile', '.en.xhtml') }.uniq | 19 | topics_xhtml = input.map { |item| item.sub('.textile', '.en.xhtml') }.uniq |
lib/tasks/error_messages.rake
@@ -4,7 +4,7 @@ targets = [] | @@ -4,7 +4,7 @@ targets = [] | ||
4 | templates.each do |template| | 4 | templates.each do |template| |
5 | target = template.gsub(/.erb$/, '') | 5 | target = template.gsub(/.erb$/, '') |
6 | targets << target | 6 | targets << target |
7 | - file target => [:makemo, template] do | 7 | + file target => [:makemo, template, :environment] do |
8 | require 'erb' | 8 | require 'erb' |
9 | erb = ERB.new(File.read(template)) | 9 | erb = ERB.new(File.read(template)) |
10 | File.open(target, 'w') do |file| | 10 | File.open(target, 'w') do |file| |
plugins/event/po/pt/event.po
@@ -5,8 +5,8 @@ | @@ -5,8 +5,8 @@ | ||
5 | # | 5 | # |
6 | msgid "" | 6 | msgid "" |
7 | msgstr "" | 7 | msgstr "" |
8 | -"Project-Id-Version: 1.0-690-gcb6e853\n" | ||
9 | -"POT-Creation-Date: 2015-03-05 12:09-0300\n" | 8 | +"Project-Id-Version: 1.1~rc4\n" |
9 | +"POT-Creation-Date: 2015-04-20 19:44-0300\n" | ||
10 | "PO-Revision-Date: 2015-01-30 00:18-0000\n" | 10 | "PO-Revision-Date: 2015-01-30 00:18-0000\n" |
11 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | 11 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
12 | "Language-Team: LANGUAGE <LL@li.org>\n" | 12 | "Language-Team: LANGUAGE <LL@li.org>\n" |
@@ -16,61 +16,53 @@ msgstr "" | @@ -16,61 +16,53 @@ msgstr "" | ||
16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
17 | "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" | 17 | "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" |
18 | 18 | ||
19 | +#: plugins/event/lib/event_plugin.rb:4 | ||
20 | +msgid "Event Extras" | ||
21 | +msgstr "Extras para Eventos" | ||
22 | + | ||
23 | +#: plugins/event/lib/event_plugin.rb:8 | ||
24 | +msgid "" | ||
25 | +"Include a new block to show the environment's or profiles' events information" | ||
26 | +msgstr "" | ||
27 | +"Adiciona um novo bloco para apresentar as informações de eventos do ambiente " | ||
28 | +"ou dos perfis" | ||
29 | + | ||
19 | #: plugins/event/lib/event_plugin/event_block.rb:12 | 30 | #: plugins/event/lib/event_plugin/event_block.rb:12 |
20 | msgid "Events" | 31 | msgid "Events" |
21 | msgstr "Eventos" | 32 | msgstr "Eventos" |
22 | 33 | ||
23 | #: plugins/event/lib/event_plugin/event_block.rb:16 | 34 | #: plugins/event/lib/event_plugin/event_block.rb:16 |
24 | msgid "Show the profile events or all environment events." | 35 | msgid "Show the profile events or all environment events." |
25 | -msgstr "Mostrar todos os eventos." | 36 | +msgstr "Mostra todos os eventos de um perfil ou do ambiente." |
26 | 37 | ||
27 | #: plugins/event/lib/event_plugin/event_block.rb:65 | 38 | #: plugins/event/lib/event_plugin/event_block.rb:65 |
28 | -#, fuzzy | ||
29 | msgid "One month ago" | 39 | msgid "One month ago" |
30 | msgid_plural "%d months ago" | 40 | msgid_plural "%d months ago" |
31 | -msgstr[0] "Iniciou a um mês atrás." | ||
32 | -msgstr[1] "Iniciou a %d meses atrás." | 41 | +msgstr[0] "Um mês atrás" |
42 | +msgstr[1] "%d meses atrás." | ||
33 | 43 | ||
34 | #: plugins/event/lib/event_plugin/event_block.rb:67 | 44 | #: plugins/event/lib/event_plugin/event_block.rb:67 |
35 | msgid "Yesterday" | 45 | msgid "Yesterday" |
36 | msgid_plural "%d days ago" | 46 | msgid_plural "%d days ago" |
37 | -msgstr[0] "" | ||
38 | -msgstr[1] "" | 47 | +msgstr[0] "Ontem" |
48 | +msgstr[1] "%d dias atrás" | ||
39 | 49 | ||
40 | #: plugins/event/lib/event_plugin/event_block.rb:69 | 50 | #: plugins/event/lib/event_plugin/event_block.rb:69 |
41 | msgid "Today" | 51 | msgid "Today" |
42 | -msgstr "" | 52 | +msgstr "Hoje" |
43 | 53 | ||
44 | #: plugins/event/lib/event_plugin/event_block.rb:71 | 54 | #: plugins/event/lib/event_plugin/event_block.rb:71 |
45 | msgid "Tomorrow" | 55 | msgid "Tomorrow" |
46 | msgid_plural "%d days left to start" | 56 | msgid_plural "%d days left to start" |
47 | -msgstr[0] "" | ||
48 | -msgstr[1] "" | 57 | +msgstr[0] "Amanhã" |
58 | +msgstr[1] "%d dias para começar" | ||
49 | 59 | ||
50 | #: plugins/event/lib/event_plugin/event_block.rb:73 | 60 | #: plugins/event/lib/event_plugin/event_block.rb:73 |
51 | -#, fuzzy | ||
52 | msgid "One month left to start" | 61 | msgid "One month left to start" |
53 | msgid_plural "%d months left to start" | 62 | msgid_plural "%d months left to start" |
54 | msgstr[0] "Um mês para iniciar" | 63 | msgstr[0] "Um mês para iniciar" |
55 | msgstr[1] "% meses para iniciar" | 64 | msgstr[1] "% meses para iniciar" |
56 | 65 | ||
57 | -#: plugins/event/lib/event_plugin.rb:4 | ||
58 | -msgid "Event Extras" | ||
59 | -msgstr "Eventos" | ||
60 | - | ||
61 | -#: plugins/event/lib/event_plugin.rb:8 | ||
62 | -msgid "" | ||
63 | -"Include a new block to show the environment's or profiles' events information" | ||
64 | -msgstr "" | ||
65 | -"Adiciona um novo bloco para apresentar as informações de eventos do ambiente " | ||
66 | -"ou de perfis" | ||
67 | - | ||
68 | -#: plugins/event/views/event_plugin/event_block_item.html.erb:6 | ||
69 | -msgid "Duration: 1 day" | ||
70 | -msgid_plural "Duration: %s days" | ||
71 | -msgstr[0] "" | ||
72 | -msgstr[1] "" | ||
73 | - | ||
74 | #: plugins/event/views/profile_design/event_plugin/_event_block.html.erb:1 | 66 | #: plugins/event/views/profile_design/event_plugin/_event_block.html.erb:1 |
75 | msgid "Limit of items" | 67 | msgid "Limit of items" |
76 | msgstr "Limite de itens" | 68 | msgstr "Limite de itens" |
@@ -94,12 +86,17 @@ msgstr "Mostrar apenas eventos futuros" | @@ -94,12 +86,17 @@ msgstr "Mostrar apenas eventos futuros" | ||
94 | 86 | ||
95 | #: plugins/event/views/profile_design/event_plugin/_event_block.html.erb:22 | 87 | #: plugins/event/views/profile_design/event_plugin/_event_block.html.erb:22 |
96 | msgid "Limit of days to display" | 88 | msgid "Limit of days to display" |
97 | -msgstr "Limite de dias de distância para mostrar eventos" | 89 | +msgstr "Limite de dias para mostrar" |
98 | 90 | ||
99 | #: plugins/event/views/profile_design/event_plugin/_event_block.html.erb:24 | 91 | #: plugins/event/views/profile_design/event_plugin/_event_block.html.erb:24 |
100 | -#, fuzzy | ||
101 | msgid "Only show events in this interval of days." | 92 | msgid "Only show events in this interval of days." |
102 | -msgstr "Mostar somente eventos que acontecem dentro do limite de dias" | 93 | +msgstr "Mostar somente os eventos nesse intervalo de dias" |
94 | + | ||
95 | +#: plugins/event/views/event_plugin/event_block_item.html.erb:6 | ||
96 | +msgid "Duration: 1 day" | ||
97 | +msgid_plural "Duration: %s days" | ||
98 | +msgstr[0] "Duração: 1 dia" | ||
99 | +msgstr[1] "Duração: %s dias" | ||
103 | 100 | ||
104 | #~ msgid "Started one day ago." | 101 | #~ msgid "Started one day ago." |
105 | #~ msgid_plural "Started %d days ago." | 102 | #~ msgid_plural "Started %d days ago." |
plugins/foo/lib/foo_plugin.rb
1 | class FooPlugin < Noosfero::Plugin | 1 | class FooPlugin < Noosfero::Plugin |
2 | + include Noosfero::Plugin::HotSpot | ||
2 | 3 | ||
3 | def self.plugin_name | 4 | def self.plugin_name |
4 | "Foo" | 5 | "Foo" |
@@ -8,12 +9,29 @@ class FooPlugin < Noosfero::Plugin | @@ -8,12 +9,29 @@ class FooPlugin < Noosfero::Plugin | ||
8 | _("A sample plugin to test autoload craziness.") | 9 | _("A sample plugin to test autoload craziness.") |
9 | end | 10 | end |
10 | 11 | ||
12 | + module Hotspots | ||
13 | + # -> Custom foo plugin hotspot | ||
14 | + # do something to extend the FooPlugin behaviour | ||
15 | + # receive params a, b and c | ||
16 | + # returns = boolean or something else | ||
17 | + def foo_plugin_my_hotspot(a, b, c) | ||
18 | + end | ||
19 | + | ||
20 | + # -> Custom title for foo profiles tab | ||
21 | + # returns = a string with a custom title | ||
22 | + def foo_plugin_tab_title | ||
23 | + end | ||
24 | + end | ||
25 | + | ||
11 | def control_panel_buttons | 26 | def control_panel_buttons |
12 | {:title => 'Foo plugin button', :icon => '', :url => ''} | 27 | {:title => 'Foo plugin button', :icon => '', :url => ''} |
13 | end | 28 | end |
14 | 29 | ||
15 | def profile_tabs | 30 | def profile_tabs |
16 | - {:title => 'Foo plugin tab', :id => 'foo_plugin', :content => lambda {'Foo plugin random content'} } | 31 | + title = plugins.dispatch_first(:foo_plugin_tab_title) |
32 | + title = 'Foo plugin tab' unless title | ||
33 | + | ||
34 | + {:title => title, :id => 'foo_plugin', :content => lambda {'Foo plugin random content'} } | ||
17 | end | 35 | end |
18 | 36 | ||
19 | end | 37 | end |
plugins/foo/test/unit/foo_plugin_test.rb
@@ -4,7 +4,25 @@ class FooPluginTest < ActiveSupport::TestCase | @@ -4,7 +4,25 @@ class FooPluginTest < ActiveSupport::TestCase | ||
4 | def test_foo | 4 | def test_foo |
5 | FooPlugin::Bar.create! | 5 | FooPlugin::Bar.create! |
6 | end | 6 | end |
7 | + | ||
7 | def test_monkey_patch | 8 | def test_monkey_patch |
8 | Profile.new.bar | 9 | Profile.new.bar |
9 | end | 10 | end |
11 | + | ||
12 | + should "respond to new hotspots" do | ||
13 | + plugin = FooPlugin.new | ||
14 | + | ||
15 | + assert plugin.respond_to?(:foo_plugin_my_hotspot) | ||
16 | + assert plugin.respond_to?(:foo_plugin_tab_title) | ||
17 | + end | ||
18 | + | ||
19 | + should "other plugin respond to new hotspots" do | ||
20 | + class TestPlugin < Noosfero::Plugin | ||
21 | + end | ||
22 | + | ||
23 | + plugin = TestPlugin.new | ||
24 | + | ||
25 | + assert plugin.respond_to?(:foo_plugin_my_hotspot) | ||
26 | + assert plugin.respond_to?(:foo_plugin_tab_title) | ||
27 | + end | ||
10 | end | 28 | end |
plugins/google_analytics/lib/ext/profile.rb
@@ -2,4 +2,9 @@ require_dependency 'profile' | @@ -2,4 +2,9 @@ require_dependency 'profile' | ||
2 | 2 | ||
3 | class Profile | 3 | class Profile |
4 | settings_items :google_analytics_profile_id | 4 | settings_items :google_analytics_profile_id |
5 | + attr_accessible :google_analytics_profile_id | ||
6 | + | ||
7 | + descendants.each do |descendant| | ||
8 | + descendant.attr_accessible :google_analytics_profile_id | ||
9 | + end | ||
5 | end | 10 | end |
plugins/google_analytics/lib/google_analytics_plugin.rb
@@ -19,12 +19,15 @@ class GoogleAnalyticsPlugin < Noosfero::Plugin | @@ -19,12 +19,15 @@ class GoogleAnalyticsPlugin < Noosfero::Plugin | ||
19 | 19 | ||
20 | def head_ending | 20 | def head_ending |
21 | unless profile_id.blank? | 21 | unless profile_id.blank? |
22 | - expanded_template('tracking-code.rhtml',{:profile_id => profile_id}) | 22 | + expanded_template('tracking-code.html.erb',{:profile_id => profile_id}) |
23 | end | 23 | end |
24 | end | 24 | end |
25 | 25 | ||
26 | def profile_editor_extras | 26 | def profile_editor_extras |
27 | - expanded_template('profile-editor-extras.rhtml',{:profile_id => profile_id}) | 27 | + analytics_id = profile_id |
28 | + lambda { | ||
29 | + render :file => 'profile-editor-extras', :locals => { :profile_id => analytics_id } | ||
30 | + } | ||
28 | end | 31 | end |
29 | 32 | ||
30 | end | 33 | end |
plugins/google_analytics/test/functional/profile_editor_controller_test.rb
0 → 100644
@@ -0,0 +1,31 @@ | @@ -0,0 +1,31 @@ | ||
1 | +require 'test_helper' | ||
2 | +require 'profile_editor_controller' | ||
3 | + | ||
4 | +# Re-raise errors caught by the controller. | ||
5 | +class ProfileEditorController; def rescue_action(e) raise e end; end | ||
6 | + | ||
7 | +class ProfileEditorControllerTest < ActionController::TestCase | ||
8 | + | ||
9 | + def setup | ||
10 | + @controller = ProfileEditorController.new | ||
11 | + @request = ActionController::TestRequest.new | ||
12 | + @response = ActionController::TestResponse.new | ||
13 | + @profile = create_user('default_user').person | ||
14 | + login_as(@profile.identifier) | ||
15 | + Environment.default.enable_plugin(GoogleAnalyticsPlugin.name) | ||
16 | + end | ||
17 | + | ||
18 | + attr_accessor :profile | ||
19 | + | ||
20 | + should 'add extra fields to profile editor info and settings' do | ||
21 | + get :edit, :profile => profile.identifier | ||
22 | + assert_tag_in_string @response.body, :tag => 'label', :content => /Google Analytics/, :attributes => { :for => 'profile_data_google_analytics_profile_id' } | ||
23 | + assert_tag_in_string @response.body, :tag => 'input', :attributes => { :id => 'profile_data_google_analytics_profile_id' } | ||
24 | + end | ||
25 | + | ||
26 | + should 'save code filled in on field' do | ||
27 | + post :edit, :profile => profile.identifier, :profile_data => {:google_analytics_profile_id => 12345678} | ||
28 | + assert_equal '12345678', Person.find(profile.id).google_analytics_profile_id | ||
29 | + end | ||
30 | + | ||
31 | +end |
plugins/google_analytics/test/unit/google_analytics_plugin_test.rb
@@ -27,11 +27,6 @@ class GoogleAnalyticsPluginTest < ActiveSupport::TestCase | @@ -27,11 +27,6 @@ class GoogleAnalyticsPluginTest < ActiveSupport::TestCase | ||
27 | assert_equal 'content', @plugin.head_ending | 27 | assert_equal 'content', @plugin.head_ending |
28 | end | 28 | end |
29 | 29 | ||
30 | - should 'add extra fields to profile editor info and settings' do | ||
31 | - assert_tag_in_string @plugin.profile_editor_extras, | ||
32 | - :tag => 'input', :attributes => {:id => 'profile_data_google_analytics_profile_id', :value => 10} | ||
33 | - end | ||
34 | - | ||
35 | should 'extends Profile with attr google_analytics_profile_id' do | 30 | should 'extends Profile with attr google_analytics_profile_id' do |
36 | assert_respond_to Profile.new, :google_analytics_profile_id | 31 | assert_respond_to Profile.new, :google_analytics_profile_id |
37 | end | 32 | end |
plugins/google_analytics/views/profile-editor-extras.html.erb
0 → 100644
@@ -0,0 +1,3 @@ | @@ -0,0 +1,3 @@ | ||
1 | +<h2><%= c_('Statistics') %></h2> | ||
2 | +<%= labelled_form_field(_('Google Analytics Profile ID'), text_field(:profile_data, :google_analytics_profile_id, :value => profile_id)) %> | ||
3 | +<%= link_to(_('See how to configure statistics for your profile'), '/doc/plugins/google_analytics', :target => '_blank') %> |
plugins/google_analytics/views/profile-editor-extras.rhtml
@@ -1,5 +0,0 @@ | @@ -1,5 +0,0 @@ | ||
1 | -<% extend ApplicationHelper %> | ||
2 | - | ||
3 | -<h2><%= c_('Statistics') %></h2> | ||
4 | -<%= labelled_form_field(_('Google Analytics Profile ID'), text_field(:profile_data, :google_analytics_profile_id, :value => profile_id)) %> | ||
5 | -<%= link_to(_('See how to configure statistics for your profile'), '/doc/plugins/google_analytics', :target => '_blank') %> |
@@ -0,0 +1,9 @@ | @@ -0,0 +1,9 @@ | ||
1 | +<script> | ||
2 | + (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ | ||
3 | + (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), | ||
4 | + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) | ||
5 | + })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); | ||
6 | + | ||
7 | + ga('create', '<%= escape_javascript locals[:profile_id] %>', 'auto'); | ||
8 | + ga('send', 'pageview'); | ||
9 | +</script> |
plugins/google_analytics/views/tracking-code.rhtml
@@ -1,10 +0,0 @@ | @@ -1,10 +0,0 @@ | ||
1 | -<script type="text/javascript"> | ||
2 | - var _gaq = _gaq || []; | ||
3 | - _gaq.push(['_setAccount', '<%= escape_javascript locals[:profile_id] %>']); | ||
4 | - _gaq.push(['_trackPageview']); | ||
5 | - (function() { | ||
6 | - var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; | ||
7 | - ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; | ||
8 | - var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); | ||
9 | - })(); | ||
10 | -</script> |
plugins/ldap/lib/ldap_authentication.rb
@@ -77,18 +77,20 @@ class LdapAuthentication | @@ -77,18 +77,20 @@ class LdapAuthentication | ||
77 | end | 77 | end |
78 | 78 | ||
79 | def get_user_attributes_from_ldap_entry(entry) | 79 | def get_user_attributes_from_ldap_entry(entry) |
80 | - { | ||
81 | - :dn => entry.dn, | ||
82 | - :fullname => LdapAuthentication.get_attr(entry, self.attr_fullname), | ||
83 | - :mail => LdapAuthentication.get_attr(entry, self.attr_mail), | ||
84 | - } | 80 | + attributes = entry.instance_values["myhash"] |
81 | + | ||
82 | + attributes[:dn] = entry.dn | ||
83 | + attributes[:fullname] = LdapAuthentication.get_attr(entry, self.attr_fullname) | ||
84 | + attributes[:mail] = LdapAuthentication.get_attr(entry, self.attr_mail) | ||
85 | + | ||
86 | + attributes | ||
85 | end | 87 | end |
86 | 88 | ||
87 | # Return the attributes needed for the LDAP search. It will only | 89 | # Return the attributes needed for the LDAP search. It will only |
88 | # include the user attributes if on-the-fly registration is enabled | 90 | # include the user attributes if on-the-fly registration is enabled |
89 | def search_attributes | 91 | def search_attributes |
90 | if onthefly_register? | 92 | if onthefly_register? |
91 | - ['dn', self.attr_fullname, self.attr_mail] | 93 | + nil |
92 | else | 94 | else |
93 | ['dn'] | 95 | ['dn'] |
94 | end | 96 | end |
@@ -111,6 +113,7 @@ class LdapAuthentication | @@ -111,6 +113,7 @@ class LdapAuthentication | ||
111 | end | 113 | end |
112 | login_filter = Net::LDAP::Filter.eq( self.attr_login, login ) | 114 | login_filter = Net::LDAP::Filter.eq( self.attr_login, login ) |
113 | object_filter = Net::LDAP::Filter.eq( "objectClass", "*" ) | 115 | object_filter = Net::LDAP::Filter.eq( "objectClass", "*" ) |
116 | + | ||
114 | attrs = {} | 117 | attrs = {} |
115 | 118 | ||
116 | search_filter = object_filter & login_filter | 119 | search_filter = object_filter & login_filter |
plugins/ldap/lib/ldap_plugin.rb
1 | require File.dirname(__FILE__) + '/ldap_authentication.rb' | 1 | require File.dirname(__FILE__) + '/ldap_authentication.rb' |
2 | 2 | ||
3 | class LdapPlugin < Noosfero::Plugin | 3 | class LdapPlugin < Noosfero::Plugin |
4 | + include Noosfero::Plugin::HotSpot | ||
4 | 5 | ||
5 | def self.plugin_name | 6 | def self.plugin_name |
6 | "LdapPlugin" | 7 | "LdapPlugin" |
@@ -10,6 +11,26 @@ class LdapPlugin < Noosfero::Plugin | @@ -10,6 +11,26 @@ class LdapPlugin < Noosfero::Plugin | ||
10 | _("A plugin that add ldap support.") | 11 | _("A plugin that add ldap support.") |
11 | end | 12 | end |
12 | 13 | ||
14 | + module Hotspots | ||
15 | + # -> Custom ldap plugin hotspot to set profile data before user creation | ||
16 | + # receive the followings params: | ||
17 | + # - attrs with ldap received data | ||
18 | + # - login received by ldap | ||
19 | + # - params from current context | ||
20 | + # returns = updated person_data hash | ||
21 | + def ldap_plugin_set_profile_data(attrs, params) | ||
22 | + [attrs, params] | ||
23 | + end | ||
24 | + | ||
25 | + # -> Custom ldap plugin hotspot to update user object | ||
26 | + # receive the followings params: | ||
27 | + # - user: user object | ||
28 | + # - attrs with ldap received data | ||
29 | + # returns = none | ||
30 | + def ldap_plugin_update_user(user, attrs) | ||
31 | + end | ||
32 | + end | ||
33 | + | ||
13 | def allow_user_registration | 34 | def allow_user_registration |
14 | false | 35 | false |
15 | end | 36 | end |
@@ -35,17 +56,22 @@ class LdapPlugin < Noosfero::Plugin | @@ -35,17 +56,22 @@ class LdapPlugin < Noosfero::Plugin | ||
35 | 56 | ||
36 | if attrs | 57 | if attrs |
37 | user.login = login | 58 | user.login = login |
38 | - user.email = attrs[:mail] | 59 | + user.email = get_email(attrs, login) |
39 | user.name = attrs[:fullname] | 60 | user.name = attrs[:fullname] |
40 | user.password = password | 61 | user.password = password |
41 | user.password_confirmation = password | 62 | user.password_confirmation = password |
42 | - user.person_data = context.params[:profile_data] | 63 | + user.person_data = plugins.pipeline(:ldap_plugin_set_profile_data, attrs, context.params).last[:profile_data] |
43 | user.activated_at = Time.now.utc | 64 | user.activated_at = Time.now.utc |
44 | user.activation_code = nil | 65 | user.activation_code = nil |
45 | 66 | ||
46 | ldap = LdapAuthentication.new(context.environment.ldap_plugin_attributes) | 67 | ldap = LdapAuthentication.new(context.environment.ldap_plugin_attributes) |
47 | begin | 68 | begin |
48 | - user = nil unless user.save | 69 | + if user.save |
70 | + user.activate | ||
71 | + plugins.dispatch(:ldap_plugin_update_user, user, attrs) | ||
72 | + else | ||
73 | + user = nil | ||
74 | + end | ||
49 | rescue | 75 | rescue |
50 | #User not saved | 76 | #User not saved |
51 | end | 77 | end |
@@ -54,7 +80,6 @@ class LdapPlugin < Noosfero::Plugin | @@ -54,7 +80,6 @@ class LdapPlugin < Noosfero::Plugin | ||
54 | end | 80 | end |
55 | 81 | ||
56 | else | 82 | else |
57 | - | ||
58 | return nil if !user.activated? | 83 | return nil if !user.activated? |
59 | 84 | ||
60 | begin | 85 | begin |
@@ -69,6 +94,16 @@ class LdapPlugin < Noosfero::Plugin | @@ -69,6 +94,16 @@ class LdapPlugin < Noosfero::Plugin | ||
69 | user | 94 | user |
70 | end | 95 | end |
71 | 96 | ||
97 | + def get_email(attrs, login) | ||
98 | + return attrs[:mail] unless attrs[:mail].blank? | ||
99 | + | ||
100 | + if attrs[:fullname] | ||
101 | + return attrs[:fullname].to_slug + "@ldap.user" | ||
102 | + else | ||
103 | + return login.to_slug + "@ldap.user" | ||
104 | + end | ||
105 | + end | ||
106 | + | ||
72 | def login_extra_contents | 107 | def login_extra_contents |
73 | proc do | 108 | proc do |
74 | @person = Person.new(:environment => @environment) | 109 | @person = Person.new(:environment => @environment) |
plugins/require_auth_to_comment/controllers/require_auth_to_comment_plugin_admin_controller.rb
0 → 100644
@@ -0,0 +1,14 @@ | @@ -0,0 +1,14 @@ | ||
1 | +class RequireAuthToCommentPluginAdminController < AdminController | ||
2 | + | ||
3 | + def index | ||
4 | + settings = params[:settings] | ||
5 | + settings ||= {} | ||
6 | + @settings = Noosfero::Plugin::Settings.new(environment, RequireAuthToCommentPlugin, settings) | ||
7 | + if request.post? | ||
8 | + @settings.save! | ||
9 | + session[:notice] = 'Settings succefully saved.' | ||
10 | + redirect_to :action => 'index' | ||
11 | + end | ||
12 | + end | ||
13 | + | ||
14 | +end |
plugins/require_auth_to_comment/lib/require_auth_to_comment_plugin.rb
@@ -21,11 +21,20 @@ class RequireAuthToCommentPlugin < Noosfero::Plugin | @@ -21,11 +21,20 @@ class RequireAuthToCommentPlugin < Noosfero::Plugin | ||
21 | end | 21 | end |
22 | 22 | ||
23 | def stylesheet? | 23 | def stylesheet? |
24 | - true | 24 | + !display_login_popup? |
25 | + end | ||
26 | + | ||
27 | + def display_login_popup? | ||
28 | + settings = Noosfero::Plugin::Settings.new(context.environment, self.class) | ||
29 | + settings.require_type == 'display_login_popup' | ||
30 | + end | ||
31 | + | ||
32 | + def self.require_type_default_setting | ||
33 | + 'hide_button' | ||
25 | end | 34 | end |
26 | 35 | ||
27 | def js_files | 36 | def js_files |
28 | - ['hide_comment_form.js', 'jquery.livequery.min.js'] | 37 | + ['hide_comment_form.js', 'jquery.livequery.min.js'] + (display_login_popup? ? ['comment_require_login.js'] : []) |
29 | end | 38 | end |
30 | 39 | ||
31 | def body_beginning | 40 | def body_beginning |
plugins/require_auth_to_comment/public/comment_require_login.js
0 → 100644
@@ -0,0 +1,8 @@ | @@ -0,0 +1,8 @@ | ||
1 | +(function($) { | ||
2 | + $(window).bind('userDataLoaded', function(event, data) { | ||
3 | + if (!data.login && $('meta[name="profile.allow_unauthenticated_comments"]').length <= 0) { | ||
4 | + $('.display-comment-form').unbind(); | ||
5 | + $('.display-comment-form').addClass('require-login-popup'); | ||
6 | + } | ||
7 | + }); | ||
8 | +})(jQuery); |
plugins/require_auth_to_comment/test/unit/require_auth_to_comment_plugin_test.rb
@@ -5,9 +5,10 @@ class RequireAuthToCommentPluginTest < ActiveSupport::TestCase | @@ -5,9 +5,10 @@ class RequireAuthToCommentPluginTest < ActiveSupport::TestCase | ||
5 | def setup | 5 | def setup |
6 | @plugin = RequireAuthToCommentPlugin.new | 6 | @plugin = RequireAuthToCommentPlugin.new |
7 | @comment = Comment.new | 7 | @comment = Comment.new |
8 | + @environment = fast_create(Environment) | ||
8 | end | 9 | end |
9 | 10 | ||
10 | - attr_reader :plugin, :comment | 11 | + attr_reader :plugin, :comment, :environment |
11 | 12 | ||
12 | should 'reject comments for unauthenticated users' do | 13 | should 'reject comments for unauthenticated users' do |
13 | plugin.context = logged_in(false) | 14 | plugin.context = logged_in(false) |
@@ -29,6 +30,35 @@ class RequireAuthToCommentPluginTest < ActiveSupport::TestCase | @@ -29,6 +30,35 @@ class RequireAuthToCommentPluginTest < ActiveSupport::TestCase | ||
29 | assert !comment.rejected? | 30 | assert !comment.rejected? |
30 | end | 31 | end |
31 | 32 | ||
33 | + should 'the default require type setting be hide_button' do | ||
34 | + assert_equal 'hide_button', plugin.class.require_type_default_setting | ||
35 | + end | ||
36 | + | ||
37 | + should 'display_login_popup? be false by default' do | ||
38 | + context = mock(); | ||
39 | + context.expects(:environment).returns(environment) | ||
40 | + plugin.expects(:context).returns(context) | ||
41 | + assert !plugin.display_login_popup? | ||
42 | + end | ||
43 | + | ||
44 | + should 'display_login_popup? be true if require_type is defined as display_login_popup' do | ||
45 | + context = mock(); | ||
46 | + context.expects(:environment).returns(environment) | ||
47 | + environment[:settings] = {:require_auth_to_comment_plugin => {:require_type => "display_login_popup"}} | ||
48 | + plugin.expects(:context).returns(context) | ||
49 | + assert plugin.display_login_popup? | ||
50 | + end | ||
51 | + | ||
52 | + should 'not display stylesheet if login popup is active' do | ||
53 | + plugin.expects(:display_login_popup?).returns(true) | ||
54 | + assert !plugin.stylesheet? | ||
55 | + end | ||
56 | + | ||
57 | + should 'display stylesheet if login popup is inactive' do | ||
58 | + plugin.expects(:display_login_popup?).returns(false) | ||
59 | + assert plugin.stylesheet? | ||
60 | + end | ||
61 | + | ||
32 | protected | 62 | protected |
33 | 63 | ||
34 | def logged_in(boolean) | 64 | def logged_in(boolean) |
plugins/require_auth_to_comment/views/require_auth_to_comment_plugin_admin/index.html.erb
0 → 100644
@@ -0,0 +1,20 @@ | @@ -0,0 +1,20 @@ | ||
1 | +<h1><%= _('Require auth to comment Settings')%></h1> | ||
2 | + | ||
3 | +<%= form_for(:settings) do |f| %> | ||
4 | + | ||
5 | + <div class="require-type"> | ||
6 | + <strong> | ||
7 | + <div class="hide-button"> | ||
8 | + <%= radio_button(:settings, :require_type, 'hide_button') %> <%= _('Hide button') %> | ||
9 | + </div> | ||
10 | + <div class="display-login-popup"> | ||
11 | + <%= radio_button(:settings, :require_type, 'display_login_popup') %> <%= _('Display login popup') %> | ||
12 | + </div> | ||
13 | + </strong> | ||
14 | + </div> | ||
15 | + | ||
16 | + <% button_bar do %> | ||
17 | + <%= submit_button(:save, _('Save'), :cancel => {:controller => 'plugins', :action => 'index'}) %> | ||
18 | + <% end %> | ||
19 | + | ||
20 | +<% end %> |
plugins/send_email/controllers/send_email_plugin_base_controller.rb
@@ -11,7 +11,8 @@ module SendEmailPluginBaseController | @@ -11,7 +11,8 @@ module SendEmailPluginBaseController | ||
11 | ) | 11 | ) |
12 | @mail.subject = params[:subject] unless params[:subject].blank? | 12 | @mail.subject = params[:subject] unless params[:subject].blank? |
13 | if @mail.valid? | 13 | if @mail.valid? |
14 | - SendEmailPlugin::Sender.send_message(request.referer, @context_url, @mail).deliver | 14 | + @referer = request.referer |
15 | + SendEmailPlugin::Sender.send_message(@referer, @context_url, @mail).deliver | ||
15 | if request.xhr? | 16 | if request.xhr? |
16 | render :text => _('Message sent') | 17 | render :text => _('Message sent') |
17 | else | 18 | else |
plugins/send_email/lib/send_email_plugin.rb
@@ -16,9 +16,9 @@ class SendEmailPlugin < Noosfero::Plugin | @@ -16,9 +16,9 @@ class SendEmailPlugin < Noosfero::Plugin | ||
16 | 16 | ||
17 | def parse_content(html, source) | 17 | def parse_content(html, source) |
18 | if context.profile | 18 | if context.profile |
19 | - html.gsub!(/\{sendemail\}/, "/profile/#{context.profile.identifier}/plugin/send_email/deliver") | 19 | + html.gsub!(/({|%7[Bb])sendemail(}|%7[Dd])/, "/profile/#{context.profile.identifier}/plugin/send_email/deliver") |
20 | else | 20 | else |
21 | - html.gsub!(/\{sendemail\}/, '/plugin/send_email/deliver') | 21 | + html.gsub!(/({|%7[Bb])sendemail(}|%7[Dd])/, '/plugin/send_email/deliver') |
22 | end | 22 | end |
23 | [html, source] | 23 | [html, source] |
24 | end | 24 | end |
plugins/send_email/lib/send_email_plugin/mail.rb
@@ -10,12 +10,11 @@ class SendEmailPlugin::Mail | @@ -10,12 +10,11 @@ class SendEmailPlugin::Mail | ||
10 | validate :recipients_format | 10 | validate :recipients_format |
11 | 11 | ||
12 | def initialize(attributes = {:subject => 'New mail'}) | 12 | def initialize(attributes = {:subject => 'New mail'}) |
13 | - @environment = attributes[:environment] | ||
14 | - @from = attributes[:from] | ||
15 | - @to = attributes[:to] | ||
16 | - @subject = attributes[:subject] | ||
17 | - @message = attributes[:message] | ||
18 | - @params = attributes[:params] | 13 | + if attributes |
14 | + attributes.each do |attr,value| | ||
15 | + self.send("#{attr}=", value) | ||
16 | + end | ||
17 | + end | ||
19 | end | 18 | end |
20 | 19 | ||
21 | def recipients_format | 20 | def recipients_format |
@@ -36,7 +35,7 @@ class SendEmailPlugin::Mail | @@ -36,7 +35,7 @@ class SendEmailPlugin::Mail | ||
36 | end | 35 | end |
37 | 36 | ||
38 | def params=(value = {}) | 37 | def params=(value = {}) |
39 | - [:action, :controller, :to, :message, :subject, :from].each{|k| value.delete(k)} | 38 | + [:profile, :action, :controller, :to, :message, :subject, :from, :commit].each{|k| value.delete(k)} |
40 | @params = value | 39 | @params = value |
41 | end | 40 | end |
42 | 41 |
plugins/send_email/lib/send_email_plugin/sender.rb
@@ -7,9 +7,9 @@ class SendEmailPlugin::Sender < Noosfero::Plugin::MailerBase | @@ -7,9 +7,9 @@ class SendEmailPlugin::Sender < Noosfero::Plugin::MailerBase | ||
7 | @params = mail.params | 7 | @params = mail.params |
8 | 8 | ||
9 | mail( | 9 | mail( |
10 | + content_type: 'text/plain', | ||
10 | to: mail.to, | 11 | to: mail.to, |
11 | from: mail.from, | 12 | from: mail.from, |
12 | - body: mail.params, | ||
13 | subject: "[#{mail.environment.name}] #{mail.subject}" | 13 | subject: "[#{mail.environment.name}] #{mail.subject}" |
14 | ) | 14 | ) |
15 | end | 15 | end |
plugins/send_email/test/functional/send_email_plugin_base_controller_test.rb
@@ -54,6 +54,13 @@ def run_common_tests | @@ -54,6 +54,13 @@ def run_common_tests | ||
54 | post :deliver, @extra_args.merge(:to => 'john@example.com', :message => 'Hi john', :subject => 'Hello john') | 54 | post :deliver, @extra_args.merge(:to => 'john@example.com', :message => 'Hi john', :subject => 'Hello john') |
55 | assert_equal '[Colivre.net] Hello john', ActionMailer::Base.deliveries.first.subject | 55 | assert_equal '[Colivre.net] Hello john', ActionMailer::Base.deliveries.first.subject |
56 | end | 56 | end |
57 | + | ||
58 | + should 'deliver mail with message from view' do | ||
59 | + Environment.any_instance.stubs(:send_email_plugin_allow_to).returns('john@example.com') | ||
60 | + post :deliver, @extra_args.merge(:to => 'john@example.com', :message => 'Hi john', :subject => 'Hello john') | ||
61 | + assert_match /Contact from/, ActionMailer::Base.deliveries.first.body.to_s | ||
62 | + end | ||
63 | + | ||
57 | end | 64 | end |
58 | 65 | ||
59 | class SendEmailPluginProfileControllerTest < ActionController::TestCase | 66 | class SendEmailPluginProfileControllerTest < ActionController::TestCase |
plugins/send_email/test/unit/send_email_plugin_sender_test.rb
@@ -15,12 +15,14 @@ class SendEmailPluginSenderTest < ActiveSupport::TestCase | @@ -15,12 +15,14 @@ class SendEmailPluginSenderTest < ActiveSupport::TestCase | ||
15 | end | 15 | end |
16 | 16 | ||
17 | should 'be able to deliver mail' do | 17 | should 'be able to deliver mail' do |
18 | + @mail.expects(:params).returns({}) | ||
18 | response = SendEmailPlugin::Sender.send_message("http://localhost/contact", 'http//profile', @mail) | 19 | response = SendEmailPlugin::Sender.send_message("http://localhost/contact", 'http//profile', @mail) |
19 | assert_equal 'noreply@localhost', response.from.join | 20 | assert_equal 'noreply@localhost', response.from.join |
20 | assert_equal "[Noosfero] #{@mail.subject}", response.subject | 21 | assert_equal "[Noosfero] #{@mail.subject}", response.subject |
21 | end | 22 | end |
22 | 23 | ||
23 | should 'deliver mail to john@example.com' do | 24 | should 'deliver mail to john@example.com' do |
25 | + @mail.expects(:params).returns({}) | ||
24 | response = SendEmailPlugin::Sender.send_message("http://localhost/contact", 'http//profile', @mail) | 26 | response = SendEmailPlugin::Sender.send_message("http://localhost/contact", 'http//profile', @mail) |
25 | assert_equal ['john@example.com'], response.to | 27 | assert_equal ['john@example.com'], response.to |
26 | end | 28 | end |
plugins/send_email/test/unit/send_email_plugin_test.rb
@@ -26,4 +26,12 @@ class SendEmailPluginTest < ActiveSupport::TestCase | @@ -26,4 +26,12 @@ class SendEmailPluginTest < ActiveSupport::TestCase | ||
26 | assert_match /profile\/#{@plugin.context.profile.identifier}\/plugin\/send_email\/deliver/, @plugin.parse_content("expand this macro {sendemail}", nil).first | 26 | assert_match /profile\/#{@plugin.context.profile.identifier}\/plugin\/send_email\/deliver/, @plugin.parse_content("expand this macro {sendemail}", nil).first |
27 | end | 27 | end |
28 | 28 | ||
29 | + should 'expand macro used on form on profile context' do | ||
30 | + profile = fast_create(Community) | ||
31 | + @plugin.context.stubs(:profile).returns(profile) | ||
32 | + article = RawHTMLArticle.create!(:name => 'Raw HTML', :body => "<form action='{sendemail}'></form>", :profile => profile) | ||
33 | + | ||
34 | + assert_match /profile\/#{profile.identifier}\/plugin\/send_email\/deliver/, @plugin.parse_content(article.to_html, nil).first | ||
35 | + end | ||
36 | + | ||
29 | end | 37 | end |
plugins/send_email/views/send_email_plugin/sender/message.html.erb
plugins/send_email/views/send_email_plugin/sender/send_message.html.erb
0 → 100644
plugins/send_email/views/send_email_plugin/success.html.erb
@@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
2 | 2 | ||
3 | <table class='sendemail-plugin-message-sent'> | 3 | <table class='sendemail-plugin-message-sent'> |
4 | <tr><td class='label'><strong><%= c_('Subject') %>:</strong></td><td class='value'><em><%=h @mail.subject %></em></td></tr> | 4 | <tr><td class='label'><strong><%= c_('Subject') %>:</strong></td><td class='value'><em><%=h @mail.subject %></em></td></tr> |
5 | - <tr><td class='label'><strong><%= c_('Message') %>:</strong></td><td class='value'><pre><%=h render :file => 'send_email_plugin/sender/message' %></pre></td></tr> | 5 | + <tr><td class='label'><strong><%= c_('Message') %>:</strong></td><td class='value'><pre><%=h render :file => 'send_email_plugin/sender/send_message' %></pre></td></tr> |
6 | </table> | 6 | </table> |
7 | 7 | ||
8 | <p><%= button :back, c_('Back'), :back %></p> | 8 | <p><%= button :back, c_('Back'), :back %></p> |
plugins/sub_organizations/db/migrate/20150508153119_add_timestamp_to_relation.rb
0 → 100644
plugins/sub_organizations/lib/sub_organizations_plugin/relation.rb
1 | class SubOrganizationsPlugin::Relation < Noosfero::Plugin::ActiveRecord | 1 | class SubOrganizationsPlugin::Relation < Noosfero::Plugin::ActiveRecord |
2 | - record_timestamps = false | ||
3 | - | ||
4 | belongs_to :parent, :polymorphic => true | 2 | belongs_to :parent, :polymorphic => true |
5 | belongs_to :child, :polymorphic => true | 3 | belongs_to :child, :polymorphic => true |
6 | 4 |
plugins/vote/public/style.css
plugins/vote/views/vote/_vote.html.erb
@@ -5,7 +5,7 @@ reload_url = url_for(:controller => 'vote_plugin_profile', :profile => profile.i | @@ -5,7 +5,7 @@ reload_url = url_for(:controller => 'vote_plugin_profile', :profile => profile.i | ||
5 | 5 | ||
6 | <span id="vote_<%= model %>_<%= target.id %>_<%= vote %>" data-reload_url=<%= reload_url %> class="vote-action action <%= action %>-action"> | 6 | <span id="vote_<%= model %>_<%= target.id %>_<%= vote %>" data-reload_url=<%= reload_url %> class="vote-action action <%= action %>-action"> |
7 | 7 | ||
8 | - <%= link_to_remote content_tag(:span, count, :class=>'like-action-counter') + content_tag(:span, '', :class=>"action-icon #{action}"), :url => url, :html => {:class => "#{active ? 'like-action-active':''} #{user ? '':'disabled'}"} %> | 8 | + <%= link_to content_tag(:span, count, :class=>'like-action-counter') + content_tag(:span, '', :class=>"action-icon #{action}"), url, :class => "#{active ? 'like-action-active':''} #{user ? '':'disabled'} require-login-popup" %> |
9 | 9 | ||
10 | <% if !voters.blank? %> | 10 | <% if !voters.blank? %> |
11 | <span class="vote-detail"> | 11 | <span class="vote-detail"> |
public/designs/templates/lefttopright/javascripts/template.js
0 → 100644
public/designs/templates/lefttopright/stylesheets/style.css
0 → 100644
@@ -0,0 +1,42 @@ | @@ -0,0 +1,42 @@ | ||
1 | +#boxes { | ||
2 | + display: table; | ||
3 | + width: 100%; | ||
4 | +} | ||
5 | + | ||
6 | +.box-1 { | ||
7 | + width: 58%; | ||
8 | + float: left; | ||
9 | + margin: 1% 1% 0% 1%; | ||
10 | +} | ||
11 | + | ||
12 | + | ||
13 | +.box-2 { | ||
14 | + position: relative; | ||
15 | + float: left; | ||
16 | + width: 20%; | ||
17 | +} | ||
18 | + | ||
19 | +.box-3 { | ||
20 | + position: relative; | ||
21 | + float: right; | ||
22 | + width: 20%; | ||
23 | + margin-top: 1%; | ||
24 | +} | ||
25 | + | ||
26 | +.box-4 { | ||
27 | + float: left; | ||
28 | + width: 79%; | ||
29 | + margin-left: 21%; | ||
30 | +} | ||
31 | + | ||
32 | +#profile-activity ul, | ||
33 | +#profile-network ul, | ||
34 | +#profile-wall ul { | ||
35 | + width: 460px; | ||
36 | +} | ||
37 | +#profile-activity ul.comment-replies, | ||
38 | +#profile-network ul.comment-replies, | ||
39 | +#profile-wall ul.comment-replies { | ||
40 | + width: auto; | ||
41 | +} | ||
42 | + |
3.02 KB
@@ -0,0 +1,434 @@ | @@ -0,0 +1,434 @@ | ||
1 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||
2 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> | ||
3 | + | ||
4 | +<svg | ||
5 | + xmlns:dc="http://purl.org/dc/elements/1.1/" | ||
6 | + xmlns:cc="http://creativecommons.org/ns#" | ||
7 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||
8 | + xmlns:svg="http://www.w3.org/2000/svg" | ||
9 | + xmlns="http://www.w3.org/2000/svg" | ||
10 | + xmlns:xlink="http://www.w3.org/1999/xlink" | ||
11 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||
12 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||
13 | + width="64px" | ||
14 | + height="64px" | ||
15 | + id="svg2383" | ||
16 | + sodipodi:version="0.32" | ||
17 | + inkscape:version="0.48.3.1 r9886" | ||
18 | + sodipodi:docname="thumbnail.svg" | ||
19 | + inkscape:output_extension="org.inkscape.output.svg.inkscape" | ||
20 | + inkscape:export-filename="thumbnail.png" | ||
21 | + inkscape:export-xdpi="90" | ||
22 | + inkscape:export-ydpi="90" | ||
23 | + version="1.1"> | ||
24 | + <defs | ||
25 | + id="defs2385"> | ||
26 | + <linearGradient | ||
27 | + id="linearGradient3263"> | ||
28 | + <stop | ||
29 | + id="stop3265" | ||
30 | + offset="0" | ||
31 | + style="stop-color:#204a87;stop-opacity:1" /> | ||
32 | + <stop | ||
33 | + id="stop3267" | ||
34 | + offset="1" | ||
35 | + style="stop-color:#729fcf;stop-opacity:1" /> | ||
36 | + </linearGradient> | ||
37 | + <linearGradient | ||
38 | + id="linearGradient3257" | ||
39 | + inkscape:collect="always"> | ||
40 | + <stop | ||
41 | + id="stop3259" | ||
42 | + offset="0" | ||
43 | + style="stop-color:#204a87;stop-opacity:1" /> | ||
44 | + <stop | ||
45 | + id="stop3261" | ||
46 | + offset="1" | ||
47 | + style="stop-color:#729fcf;stop-opacity:1" /> | ||
48 | + </linearGradient> | ||
49 | + <linearGradient | ||
50 | + inkscape:collect="always" | ||
51 | + id="linearGradient3245"> | ||
52 | + <stop | ||
53 | + style="stop-color:#204a87;stop-opacity:1" | ||
54 | + offset="0" | ||
55 | + id="stop3247" /> | ||
56 | + <stop | ||
57 | + style="stop-color:#729fcf;stop-opacity:1" | ||
58 | + offset="1" | ||
59 | + id="stop3249" /> | ||
60 | + </linearGradient> | ||
61 | + <inkscape:perspective | ||
62 | + sodipodi:type="inkscape:persp3d" | ||
63 | + inkscape:vp_x="0 : 32 : 1" | ||
64 | + inkscape:vp_y="0 : 1000 : 0" | ||
65 | + inkscape:vp_z="64 : 32 : 1" | ||
66 | + inkscape:persp3d-origin="32 : 21.333333 : 1" | ||
67 | + id="perspective2391" /> | ||
68 | + <filter | ||
69 | + inkscape:collect="always" | ||
70 | + id="filter3241"> | ||
71 | + <feGaussianBlur | ||
72 | + inkscape:collect="always" | ||
73 | + stdDeviation="0.9075" | ||
74 | + id="feGaussianBlur3243" /> | ||
75 | + </filter> | ||
76 | + <linearGradient | ||
77 | + inkscape:collect="always" | ||
78 | + xlink:href="#linearGradient3245" | ||
79 | + id="linearGradient3251" | ||
80 | + x1="11.5" | ||
81 | + y1="60.5" | ||
82 | + x2="3.5" | ||
83 | + y2="3.5" | ||
84 | + gradientUnits="userSpaceOnUse" | ||
85 | + gradientTransform="translate(2,0)" /> | ||
86 | + <linearGradient | ||
87 | + inkscape:collect="always" | ||
88 | + xlink:href="#linearGradient3263" | ||
89 | + id="linearGradient3253" | ||
90 | + x1="49.5" | ||
91 | + y1="60.5" | ||
92 | + x2="23.5" | ||
93 | + y2="3.5" | ||
94 | + gradientUnits="userSpaceOnUse" | ||
95 | + gradientTransform="translate(2,0)" /> | ||
96 | + <linearGradient | ||
97 | + inkscape:collect="always" | ||
98 | + xlink:href="#linearGradient3257" | ||
99 | + id="linearGradient3255" | ||
100 | + x1="60.5" | ||
101 | + y1="60.5" | ||
102 | + x2="51.5" | ||
103 | + y2="3.5" | ||
104 | + gradientUnits="userSpaceOnUse" /> | ||
105 | + <filter | ||
106 | + color-interpolation-filters="sRGB" | ||
107 | + inkscape:collect="always" | ||
108 | + id="filter3241-2"> | ||
109 | + <feGaussianBlur | ||
110 | + inkscape:collect="always" | ||
111 | + stdDeviation="0.9075" | ||
112 | + id="feGaussianBlur3243-4" /> | ||
113 | + </filter> | ||
114 | + <linearGradient | ||
115 | + inkscape:collect="always" | ||
116 | + xlink:href="#linearGradient3245-1" | ||
117 | + id="linearGradient3251-0" | ||
118 | + x1="11.5" | ||
119 | + y1="60.5" | ||
120 | + x2="3.5" | ||
121 | + y2="3.5" | ||
122 | + gradientUnits="userSpaceOnUse" | ||
123 | + gradientTransform="translate(249.71429,298.93361)" /> | ||
124 | + <linearGradient | ||
125 | + inkscape:collect="always" | ||
126 | + id="linearGradient3245-1"> | ||
127 | + <stop | ||
128 | + style="stop-color:#204a87;stop-opacity:1" | ||
129 | + offset="0" | ||
130 | + id="stop3247-6" /> | ||
131 | + <stop | ||
132 | + style="stop-color:#729fcf;stop-opacity:1" | ||
133 | + offset="1" | ||
134 | + id="stop3249-5" /> | ||
135 | + </linearGradient> | ||
136 | + <filter | ||
137 | + color-interpolation-filters="sRGB" | ||
138 | + inkscape:collect="always" | ||
139 | + id="filter3241-4-8"> | ||
140 | + <feGaussianBlur | ||
141 | + inkscape:collect="always" | ||
142 | + stdDeviation="0.9075" | ||
143 | + id="feGaussianBlur3243-0-7" /> | ||
144 | + </filter> | ||
145 | + <linearGradient | ||
146 | + inkscape:collect="always" | ||
147 | + xlink:href="#linearGradient3263-5-8" | ||
148 | + id="linearGradient5185" | ||
149 | + gradientUnits="userSpaceOnUse" | ||
150 | + gradientTransform="matrix(1.4160224,0,0,0.76166072,243.22589,313.33388)" | ||
151 | + x1="42.5" | ||
152 | + y1="60.5" | ||
153 | + x2="19.5" | ||
154 | + y2="3.5" /> | ||
155 | + <linearGradient | ||
156 | + id="linearGradient3263-5-8"> | ||
157 | + <stop | ||
158 | + id="stop3265-4-3" | ||
159 | + offset="0" | ||
160 | + style="stop-color:#204a87;stop-opacity:1" /> | ||
161 | + <stop | ||
162 | + id="stop3267-2-4" | ||
163 | + offset="1" | ||
164 | + style="stop-color:#729fcf;stop-opacity:1" /> | ||
165 | + </linearGradient> | ||
166 | + <filter | ||
167 | + color-interpolation-filters="sRGB" | ||
168 | + inkscape:collect="always" | ||
169 | + id="filter3241-0"> | ||
170 | + <feGaussianBlur | ||
171 | + inkscape:collect="always" | ||
172 | + stdDeviation="0.9075" | ||
173 | + id="feGaussianBlur3243-3" /> | ||
174 | + </filter> | ||
175 | + <linearGradient | ||
176 | + inkscape:collect="always" | ||
177 | + xlink:href="#linearGradient3245-7" | ||
178 | + id="linearGradient5168" | ||
179 | + gradientUnits="userSpaceOnUse" | ||
180 | + gradientTransform="matrix(1.0025263,0,0,0.76423683,344.68831,300.13218)" | ||
181 | + x1="11.5" | ||
182 | + y1="60.5" | ||
183 | + x2="3.5" | ||
184 | + y2="3.5" /> | ||
185 | + <linearGradient | ||
186 | + inkscape:collect="always" | ||
187 | + id="linearGradient3245-7"> | ||
188 | + <stop | ||
189 | + style="stop-color:#204a87;stop-opacity:1" | ||
190 | + offset="0" | ||
191 | + id="stop3247-0" /> | ||
192 | + <stop | ||
193 | + style="stop-color:#729fcf;stop-opacity:1" | ||
194 | + offset="1" | ||
195 | + id="stop3249-7" /> | ||
196 | + </linearGradient> | ||
197 | + <linearGradient | ||
198 | + inkscape:collect="always" | ||
199 | + xlink:href="#linearGradient3245-70" | ||
200 | + id="linearGradient3251-55" | ||
201 | + x1="11.5" | ||
202 | + y1="60.5" | ||
203 | + x2="3.5" | ||
204 | + y2="3.5" | ||
205 | + gradientUnits="userSpaceOnUse" | ||
206 | + gradientTransform="matrix(1.0025263,0,0,0.76423683,344.68831,300.13218)" /> | ||
207 | + <linearGradient | ||
208 | + inkscape:collect="always" | ||
209 | + id="linearGradient3245-70"> | ||
210 | + <stop | ||
211 | + style="stop-color:#204a87;stop-opacity:1" | ||
212 | + offset="0" | ||
213 | + id="stop3247-2" /> | ||
214 | + <stop | ||
215 | + style="stop-color:#729fcf;stop-opacity:1" | ||
216 | + offset="1" | ||
217 | + id="stop3249-87" /> | ||
218 | + </linearGradient> | ||
219 | + <linearGradient | ||
220 | + inkscape:collect="always" | ||
221 | + xlink:href="#linearGradient3245-1" | ||
222 | + id="linearGradient5832" | ||
223 | + gradientUnits="userSpaceOnUse" | ||
224 | + gradientTransform="translate(249.71429,298.93361)" | ||
225 | + x1="11.5" | ||
226 | + y1="60.5" | ||
227 | + x2="3.5" | ||
228 | + y2="3.5" /> | ||
229 | + <linearGradient | ||
230 | + inkscape:collect="always" | ||
231 | + xlink:href="#linearGradient3263-5-8" | ||
232 | + id="linearGradient5834" | ||
233 | + gradientUnits="userSpaceOnUse" | ||
234 | + gradientTransform="matrix(1.4160224,0,0,0.76166072,243.22589,313.33388)" | ||
235 | + x1="42.5" | ||
236 | + y1="60.5" | ||
237 | + x2="19.5" | ||
238 | + y2="3.5" /> | ||
239 | + <linearGradient | ||
240 | + inkscape:collect="always" | ||
241 | + xlink:href="#linearGradient3245-7" | ||
242 | + id="linearGradient5836" | ||
243 | + gradientUnits="userSpaceOnUse" | ||
244 | + gradientTransform="matrix(1.0025263,0,0,0.76423683,344.68831,300.13218)" | ||
245 | + x1="11.5" | ||
246 | + y1="60.5" | ||
247 | + x2="3.5" | ||
248 | + y2="3.5" /> | ||
249 | + <linearGradient | ||
250 | + inkscape:collect="always" | ||
251 | + xlink:href="#linearGradient3245-70" | ||
252 | + id="linearGradient5838" | ||
253 | + gradientUnits="userSpaceOnUse" | ||
254 | + gradientTransform="matrix(1.0025263,0,0,0.76423683,344.68831,300.13218)" | ||
255 | + x1="11.5" | ||
256 | + y1="60.5" | ||
257 | + x2="3.5" | ||
258 | + y2="3.5" /> | ||
259 | + </defs> | ||
260 | + <sodipodi:namedview | ||
261 | + id="base" | ||
262 | + pagecolor="#ffffff" | ||
263 | + bordercolor="#666666" | ||
264 | + borderopacity="1.0" | ||
265 | + inkscape:pageopacity="0.0" | ||
266 | + inkscape:pageshadow="2" | ||
267 | + inkscape:zoom="2.5351563" | ||
268 | + inkscape:cx="-16.066434" | ||
269 | + inkscape:cy="0.12147739" | ||
270 | + inkscape:current-layer="layer1" | ||
271 | + showgrid="true" | ||
272 | + inkscape:document-units="px" | ||
273 | + inkscape:grid-bbox="true" | ||
274 | + inkscape:window-width="1364" | ||
275 | + inkscape:window-height="678" | ||
276 | + inkscape:window-x="0" | ||
277 | + inkscape:window-y="27" | ||
278 | + objecttolerance="10" | ||
279 | + gridtolerance="10" | ||
280 | + guidetolerance="10" | ||
281 | + inkscape:window-maximized="0"> | ||
282 | + <inkscape:grid | ||
283 | + type="xygrid" | ||
284 | + id="grid2382" | ||
285 | + visible="true" | ||
286 | + enabled="true" | ||
287 | + originx="0.5px" | ||
288 | + originy="0.5px" | ||
289 | + empcolor="#0000ff" | ||
290 | + empopacity="0.1254902" | ||
291 | + dotted="true" /> | ||
292 | + </sodipodi:namedview> | ||
293 | + <metadata | ||
294 | + id="metadata2388"> | ||
295 | + <rdf:RDF> | ||
296 | + <cc:Work | ||
297 | + rdf:about=""> | ||
298 | + <dc:format>image/svg+xml</dc:format> | ||
299 | + <dc:type | ||
300 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||
301 | + </cc:Work> | ||
302 | + </rdf:RDF> | ||
303 | + </metadata> | ||
304 | + <g | ||
305 | + id="layer1" | ||
306 | + inkscape:label="Layer 1" | ||
307 | + inkscape:groupmode="layer"> | ||
308 | + <g | ||
309 | + transform="translate(-247.62879,-298.93361)" | ||
310 | + id="g5187"> | ||
311 | + <g | ||
312 | + id="g4846"> | ||
313 | + <g | ||
314 | + id="g3190-2" | ||
315 | + style="opacity:0.4;filter:url(#filter3241-2)" | ||
316 | + transform="translate(250.71429,299.93361)"> | ||
317 | + <rect | ||
318 | + y="1.5" | ||
319 | + x="1.5" | ||
320 | + height="59" | ||
321 | + width="11" | ||
322 | + id="rect3184-1" | ||
323 | + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
324 | + ry="2" | ||
325 | + rx="2" /> | ||
326 | + </g> | ||
327 | + <rect | ||
328 | + y="300.43362" | ||
329 | + x="251.21428" | ||
330 | + height="59" | ||
331 | + width="11" | ||
332 | + id="rect2395-8" | ||
333 | + style="fill:url(#linearGradient5832);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
334 | + ry="2" | ||
335 | + rx="2" /> | ||
336 | + <rect | ||
337 | + ry="1" | ||
338 | + style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
339 | + id="rect3158-7" | ||
340 | + width="9" | ||
341 | + height="57" | ||
342 | + x="252.21428" | ||
343 | + y="301.43362" | ||
344 | + rx="1" /> | ||
345 | + </g> | ||
346 | + <g | ||
347 | + transform="matrix(0.69260722,0,0,1,81.51265,0)" | ||
348 | + id="g5180"> | ||
349 | + <rect | ||
350 | + rx="2" | ||
351 | + ry="2" | ||
352 | + style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3241-4-8);enable-background:accumulate" | ||
353 | + id="rect3188-8" | ||
354 | + width="31" | ||
355 | + height="59" | ||
356 | + x="16.5" | ||
357 | + y="2.5" | ||
358 | + transform="matrix(1.4160224,0,0,0.76166071,243.80989,314.09132)" /> | ||
359 | + <rect | ||
360 | + y="314.47638" | ||
361 | + x="265.17426" | ||
362 | + height="44.937984" | ||
363 | + width="43.896694" | ||
364 | + id="rect3156-3" | ||
365 | + style="fill:url(#linearGradient5834);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:1.03852236;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
366 | + ry="1.5233214" /> | ||
367 | + <rect | ||
368 | + y="315.23804" | ||
369 | + x="266.59027" | ||
370 | + height="43.414661" | ||
371 | + width="41.064651" | ||
372 | + id="rect3162-1" | ||
373 | + style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1.03852236;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
374 | + ry="0.7616607" | ||
375 | + inkscape:export-xdpi="90" | ||
376 | + inkscape:export-ydpi="90" /> | ||
377 | + </g> | ||
378 | + <g | ||
379 | + transform="matrix(0.9761091,0,0,1,6.3333026,0)" | ||
380 | + id="g5108"> | ||
381 | + <rect | ||
382 | + rx="2" | ||
383 | + ry="2" | ||
384 | + style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3241-0);enable-background:accumulate" | ||
385 | + id="rect3184-5" | ||
386 | + width="11" | ||
387 | + height="59" | ||
388 | + x="2.5" | ||
389 | + y="2.5" | ||
390 | + transform="matrix(0,1.0025263,-0.76423683,0,312.09322,298.92289)" /> | ||
391 | + <g | ||
392 | + transform="matrix(0,1,-1,0,611.46116,-45.820829)" | ||
393 | + id="g4877-9"> | ||
394 | + <rect | ||
395 | + ry="1.5284736" | ||
396 | + style="fill:url(#linearGradient5836);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:0.87531;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
397 | + id="rect2395-95" | ||
398 | + width="11.02779" | ||
399 | + height="45.089973" | ||
400 | + x="346.19211" | ||
401 | + y="301.27853" /> | ||
402 | + <rect | ||
403 | + y="302.04276" | ||
404 | + x="347.19461" | ||
405 | + height="43.561501" | ||
406 | + width="9.0227375" | ||
407 | + id="rect3158-2" | ||
408 | + style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:0.87531;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
409 | + ry="0.76423681" /> | ||
410 | + </g> | ||
411 | + </g> | ||
412 | + <g | ||
413 | + id="g4877-8" | ||
414 | + transform="translate(-47.956003,13.002947)"> | ||
415 | + <rect | ||
416 | + y="301.27853" | ||
417 | + x="346.19211" | ||
418 | + height="45.089973" | ||
419 | + width="11.02779" | ||
420 | + id="rect2395-1" | ||
421 | + style="fill:url(#linearGradient5838);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:0.87531;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
422 | + ry="1.5284736" /> | ||
423 | + <rect | ||
424 | + ry="0.76423681" | ||
425 | + style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:0.87531;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
426 | + id="rect3158-71" | ||
427 | + width="9.0227375" | ||
428 | + height="43.561501" | ||
429 | + x="347.19461" | ||
430 | + y="302.04276" /> | ||
431 | + </g> | ||
432 | + </g> | ||
433 | + </g> | ||
434 | +</svg> |
public/designs/templates/topleft/stylesheets/style.css
1.14 KB
@@ -0,0 +1,83 @@ | @@ -0,0 +1,83 @@ | ||
1 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||
2 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> | ||
3 | + | ||
4 | +<svg | ||
5 | + xmlns:dc="http://purl.org/dc/elements/1.1/" | ||
6 | + xmlns:cc="http://creativecommons.org/ns#" | ||
7 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||
8 | + xmlns:svg="http://www.w3.org/2000/svg" | ||
9 | + xmlns="http://www.w3.org/2000/svg" | ||
10 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||
11 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||
12 | + width="64" | ||
13 | + height="64" | ||
14 | + id="svg2" | ||
15 | + sodipodi:version="0.32" | ||
16 | + inkscape:version="0.48.3.1 r9886" | ||
17 | + version="1.0" | ||
18 | + sodipodi:docname="4.svg" | ||
19 | + inkscape:output_extension="org.inkscape.output.svg.inkscape" | ||
20 | + inkscape:export-filename="/home/noosfero/sites/noosfero/public/images/blocks/4.png" | ||
21 | + inkscape:export-xdpi="87.968124" | ||
22 | + inkscape:export-ydpi="87.968124"> | ||
23 | + <defs | ||
24 | + id="defs4" /> | ||
25 | + <sodipodi:namedview | ||
26 | + id="base" | ||
27 | + pagecolor="#ffffff" | ||
28 | + bordercolor="#666666" | ||
29 | + borderopacity="1.0" | ||
30 | + inkscape:pageopacity="0.0" | ||
31 | + inkscape:pageshadow="2" | ||
32 | + inkscape:zoom="5.921875" | ||
33 | + inkscape:cx="32" | ||
34 | + inkscape:cy="32" | ||
35 | + inkscape:document-units="px" | ||
36 | + inkscape:current-layer="layer1" | ||
37 | + width="64px" | ||
38 | + height="64px" | ||
39 | + inkscape:window-width="1366" | ||
40 | + inkscape:window-height="681" | ||
41 | + inkscape:window-x="0" | ||
42 | + inkscape:window-y="27" | ||
43 | + showgrid="false" | ||
44 | + inkscape:window-maximized="1" /> | ||
45 | + <metadata | ||
46 | + id="metadata7"> | ||
47 | + <rdf:RDF> | ||
48 | + <cc:Work | ||
49 | + rdf:about=""> | ||
50 | + <dc:format>image/svg+xml</dc:format> | ||
51 | + <dc:type | ||
52 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||
53 | + <dc:title></dc:title> | ||
54 | + </cc:Work> | ||
55 | + </rdf:RDF> | ||
56 | + </metadata> | ||
57 | + <g | ||
58 | + inkscape:label="Camada 1" | ||
59 | + inkscape:groupmode="layer" | ||
60 | + id="layer1"> | ||
61 | + <path | ||
62 | + sodipodi:type="arc" | ||
63 | + style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:4.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.19607843" | ||
64 | + id="path2162" | ||
65 | + sodipodi:cx="24.12665" | ||
66 | + sodipodi:cy="24.063324" | ||
67 | + sodipodi:rx="21.593668" | ||
68 | + sodipodi:ry="21.277044" | ||
69 | + d="M 45.720318 24.063324 A 21.593668 21.277044 0 1 1 2.5329819,24.063324 A 21.593668 21.277044 0 1 1 45.720318 24.063324 z" | ||
70 | + transform="translate(7.8733501,7.936676)" /> | ||
71 | + <text | ||
72 | + xml:space="preserve" | ||
73 | + style="font-size:42.00993729px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:0.19607843;stroke:none;font-family:FreeSans" | ||
74 | + x="16.267668" | ||
75 | + y="47.399117" | ||
76 | + id="text3134" | ||
77 | + sodipodi:linespacing="125%"><tspan | ||
78 | + sodipodi:role="line" | ||
79 | + id="tspan3136" | ||
80 | + x="16.267668" | ||
81 | + y="47.399117">4</tspan></text> | ||
82 | + </g> | ||
83 | +</svg> |
2.07 KB
3.63 KB
public/javascripts/application.js
@@ -27,6 +27,7 @@ | @@ -27,6 +27,7 @@ | ||
27 | *= require manage-products.js | 27 | *= require manage-products.js |
28 | *= require catalog.js | 28 | *= require catalog.js |
29 | *= require autogrow.js | 29 | *= require autogrow.js |
30 | +*= require require_login.js | ||
30 | */ | 31 | */ |
31 | 32 | ||
32 | // scope for noosfero stuff | 33 | // scope for noosfero stuff |
@@ -0,0 +1,19 @@ | @@ -0,0 +1,19 @@ | ||
1 | +(function($){ | ||
2 | + 'use strict'; | ||
3 | + | ||
4 | + function toggle_assignment_method() { | ||
5 | + if (this.value != "roles") { | ||
6 | + $('.assign_by_roles').hide(); | ||
7 | + $('.assign_by_members').show(); | ||
8 | + } else { | ||
9 | + $('.assign_by_members').hide(); | ||
10 | + $('.assign_by_roles').show(); | ||
11 | + } | ||
12 | + } | ||
13 | + | ||
14 | + $(document).ready(function() { | ||
15 | + $('.assign_by_roles').hide(); | ||
16 | + // Event triggers | ||
17 | + $('.assign_role_by').click(toggle_assignment_method); | ||
18 | + }); | ||
19 | +})(jQuery); |
public/javascripts/manage-fields.js
@@ -57,7 +57,7 @@ jQuery(document).ready(function(){ | @@ -57,7 +57,7 @@ jQuery(document).ready(function(){ | ||
57 | } | 57 | } |
58 | 58 | ||
59 | var checkbox = jQuery(checkboxes[i+3]).attr("id").split("_") | 59 | var checkbox = jQuery(checkboxes[i+3]).attr("id").split("_") |
60 | - jQuery("#" + checkbox.first() + "_" + checkbox.last()).attr("checked", allchecked) | 60 | + jQuery("#" + checkbox[0] + "_" + checkbox[checkbox.length-1]).attr("checked", allchecked) |
61 | } | 61 | } |
62 | } | 62 | } |
63 | 63 | ||
@@ -74,10 +74,10 @@ jQuery(document).ready(function(){ | @@ -74,10 +74,10 @@ jQuery(document).ready(function(){ | ||
74 | 74 | ||
75 | jQuery("input[type='checkbox']").click(function (){ | 75 | jQuery("input[type='checkbox']").click(function (){ |
76 | var checkbox = jQuery(this).attr("id").split("_") | 76 | var checkbox = jQuery(this).attr("id").split("_") |
77 | - verify_checked(checkbox.first()) | 77 | + verify_checked(checkbox[0]) |
78 | 78 | ||
79 | if(this.checked == false) { | 79 | if(this.checked == false) { |
80 | - jQuery("#" + checkbox.first() + "_" + checkbox.last()).attr("checked", false) | 80 | + jQuery("#" + checkbox[0] + "_" + checkbox[checkbox.length-1]).attr("checked", false) |
81 | } | 81 | } |
82 | }) | 82 | }) |
83 | }) | 83 | }) |
public/javascripts/report-abuse.js
1 | jQuery(function($) { | 1 | jQuery(function($) { |
2 | $('.report-abuse-action').live('click', function() { | 2 | $('.report-abuse-action').live('click', function() { |
3 | - if($(this).attr('href')){ | ||
4 | - noosfero.modal.inline($(this).attr('href'), { | ||
5 | - innerHeight: '300px', | ||
6 | - innerWidth: '445px' | ||
7 | - }); | ||
8 | - } | 3 | + if($(this).attr('href')) |
4 | + noosfero.modal.url($(this).attr('href')); | ||
5 | + | ||
9 | return false; | 6 | return false; |
10 | }); | 7 | }); |
11 | 8 |
@@ -0,0 +1,25 @@ | @@ -0,0 +1,25 @@ | ||
1 | +(function($) { | ||
2 | + $(window).bind('userDataLoaded', function(event, data) { | ||
3 | + $(".require-login-popup").live('click', function(){ | ||
4 | + clicked = $(this); | ||
5 | + url = clicked.attr("href"); | ||
6 | + if(url!=undefined && url!='' && url!='#') { | ||
7 | + if(!data.login) { | ||
8 | + url = $.param.querystring(url, "require_login_popup=true"); | ||
9 | + } | ||
10 | + loading_for_button(this); | ||
11 | + $.post(url, function(data){ | ||
12 | + if(data.require_login_popup) { | ||
13 | + $('#link_login').click(); //TODO see a better way to show login popup | ||
14 | + } | ||
15 | + }).complete(function() { | ||
16 | + clicked.css("cursor",""); | ||
17 | + $(".small-loading").remove(); | ||
18 | + }); | ||
19 | + } else { | ||
20 | + $('#link_login').click(); | ||
21 | + } | ||
22 | + return false; | ||
23 | + }); | ||
24 | + }); | ||
25 | +})(jQuery); |
public/stylesheets/application.css
@@ -1501,6 +1501,14 @@ a.comment-picture { | @@ -1501,6 +1501,14 @@ a.comment-picture { | ||
1501 | #content .title { | 1501 | #content .title { |
1502 | margin-bottom: 2px; | 1502 | margin-bottom: 2px; |
1503 | } | 1503 | } |
1504 | +.blog-post .post-pic { | ||
1505 | + background-position: 50% 40%; | ||
1506 | + background-size: cover; | ||
1507 | + height: 150px; | ||
1508 | +} | ||
1509 | +.blog-post .post-pic.empty { | ||
1510 | + display: none; | ||
1511 | +} | ||
1504 | .metadata, .blog-post .metadata { | 1512 | .metadata, .blog-post .metadata { |
1505 | display: block; | 1513 | display: block; |
1506 | text-align: center; | 1514 | text-align: center; |
@@ -1834,6 +1842,9 @@ a.button.disabled, input.disabled { | @@ -1834,6 +1842,9 @@ a.button.disabled, input.disabled { | ||
1834 | #box-organizer div.box-3 { | 1842 | #box-organizer div.box-3 { |
1835 | background-image: url(../images/blocks/3.png); | 1843 | background-image: url(../images/blocks/3.png); |
1836 | } | 1844 | } |
1845 | +#box-organizer div.box-4 { | ||
1846 | + background-image: url(../images/blocks/4.png); | ||
1847 | +} | ||
1837 | #box-organizer .block { | 1848 | #box-organizer .block { |
1838 | cursor: move; | 1849 | cursor: move; |
1839 | } | 1850 | } |
@@ -4677,6 +4688,12 @@ h1#agenda-title { | @@ -4677,6 +4688,12 @@ h1#agenda-title { | ||
4677 | .controller-profile_editor a.control-panel-welcome-page { | 4688 | .controller-profile_editor a.control-panel-welcome-page { |
4678 | background-image: url(../images/control-panel/welcome-page.png) | 4689 | background-image: url(../images/control-panel/welcome-page.png) |
4679 | } | 4690 | } |
4691 | +.controller-profile_editor a.control-panel-roles { | ||
4692 | + background-image: url(../images/control-panel/role-management.png) | ||
4693 | +} | ||
4694 | +.controller-profile_editor .msie6 a.control-panel-roles { | ||
4695 | + background-image: url(../images/control-panel/role-management.gif) | ||
4696 | +} | ||
4680 | /* ==> public/stylesheets/controller_profile_members.css <== */ | 4697 | /* ==> public/stylesheets/controller_profile_members.css <== */ |
4681 | .controller-profile_members .no-boxes { | 4698 | .controller-profile_members .no-boxes { |
4682 | margin: 30px | 4699 | margin: 30px |
script/install-dependencies/debian-wheezy.sh
1 | -binary_packages='deb http://download.noosfero.org/debian/wheezy-1.1 ./' | 1 | +binary_packages='deb http://download.noosfero.org/debian/wheezy-1.2 ./' |
2 | 2 | ||
3 | source_packages=$(echo "$binary_packages" | sed -e 's/^deb/deb-src/') | 3 | source_packages=$(echo "$binary_packages" | sed -e 's/^deb/deb-src/') |
4 | 4 | ||
@@ -53,6 +53,13 @@ FPQAoNmiMgP6zGF9rgOEWMEiFEryayrz | @@ -53,6 +53,13 @@ FPQAoNmiMgP6zGF9rgOEWMEiFEryayrz | ||
53 | EOF | 53 | EOF |
54 | fi | 54 | fi |
55 | 55 | ||
56 | +if grep -qrl wheezy /etc/apt/sources.list* && ! grep -qrl wheezy-backports /etc/apt/sources.list*; then | ||
57 | + sudo tee /etc/apt/sources.list.d/backports.list <<EOF | ||
58 | +deb http://httpredir.debian.org/debian wheezy-backports main | ||
59 | +EOF | ||
60 | +fi | ||
61 | + | ||
62 | + | ||
56 | if test -f tmp/debian/Release.gpg; then | 63 | if test -f tmp/debian/Release.gpg; then |
57 | echo "deb file://$(pwd)/tmp/debian/ ./" | sudo tee /etc/apt/sources.list.d/local.list | 64 | echo "deb file://$(pwd)/tmp/debian/ ./" | sudo tee /etc/apt/sources.list.d/local.list |
58 | sudo apt-key add tmp/debian/signing-key.asc | 65 | sudo apt-key add tmp/debian/signing-key.asc |
@@ -65,6 +72,9 @@ run sudo apt-get -qy dist-upgrade | @@ -65,6 +72,9 @@ run sudo apt-get -qy dist-upgrade | ||
65 | 72 | ||
66 | run sudo apt-get -y install dctrl-tools | 73 | run sudo apt-get -y install dctrl-tools |
67 | 74 | ||
75 | +# *sigh* need ruby-rspec from backports | ||
76 | +run sudo apt-get -y install -t wheezy-backports ruby-rspec | ||
77 | + | ||
68 | # needed to run noosfero | 78 | # needed to run noosfero |
69 | packages=$(grep-dctrl -n -s Build-Depends,Depends,Recommends -S -X noosfero debian/control | sed -e '/^\s*#/d; s/([^)]*)//g; s/,\s*/\n/g' | grep -v 'memcached\|debconf\|dbconfig-common\|misc:Depends\|adduser\|mail-transport-agent') | 79 | packages=$(grep-dctrl -n -s Build-Depends,Depends,Recommends -S -X noosfero debian/control | sed -e '/^\s*#/d; s/([^)]*)//g; s/,\s*/\n/g' | grep -v 'memcached\|debconf\|dbconfig-common\|misc:Depends\|adduser\|mail-transport-agent') |
70 | run sudo apt-get -y install $packages | 80 | run sudo apt-get -y install $packages |
script/production
@@ -85,7 +85,7 @@ environments_loop() { | @@ -85,7 +85,7 @@ environments_loop() { | ||
85 | } | 85 | } |
86 | 86 | ||
87 | do_running() { | 87 | do_running() { |
88 | - pids=$(sed "s/.*/& /" tmp/pids/thin.*.pid | tr -d '\n' 2>/dev/null || true) | 88 | + pids=$(sed "s/.*/& /" tmp/pids/thin.*.pid 2>/dev/null | tr -d '\n') |
89 | # passes if any of $pids exist, fails otherwise | 89 | # passes if any of $pids exist, fails otherwise |
90 | kill -0 $pids > /dev/null 2>&1 | 90 | kill -0 $pids > /dev/null 2>&1 |
91 | } | 91 | } |
test/factories.rb
@@ -454,7 +454,7 @@ module Noosfero::Factory | @@ -454,7 +454,7 @@ module Noosfero::Factory | ||
454 | end | 454 | end |
455 | 455 | ||
456 | def defaults_for_suggest_article | 456 | def defaults_for_suggest_article |
457 | - { :name => 'Sender', :email => 'sender@example.com', :article_name => 'Some title', :article_body => 'some body text', :article_abstract => 'some abstract text'} | 457 | + { :name => 'Sender', :email => 'sender@example.com', :article => {:name => 'Some title', :body => 'some body text', :abstract => 'some abstract text'}} |
458 | end | 458 | end |
459 | 459 | ||
460 | def defaults_for_comment(params = {}) | 460 | def defaults_for_comment(params = {}) |
test/functional/application_controller_test.rb
@@ -578,4 +578,22 @@ class ApplicationControllerTest < ActionController::TestCase | @@ -578,4 +578,22 @@ class ApplicationControllerTest < ActionController::TestCase | ||
578 | assert_response :success | 578 | assert_response :success |
579 | end | 579 | end |
580 | 580 | ||
581 | + should "redirect to 404 if profile is '~' and user is not logged in" do | ||
582 | + get :index, :profile => '~' | ||
583 | + assert_response :missing | ||
584 | + end | ||
585 | + | ||
586 | + should "redirect to action when profile is '~' " do | ||
587 | + login_as('ze') | ||
588 | + get :index, :profile => '~' | ||
589 | + assert_response 302 | ||
590 | + end | ||
591 | + | ||
592 | + should "substitute '~' by current user and redirect properly " do | ||
593 | + login_as('ze') | ||
594 | + profile = Profile.where(:identifier => 'ze').first | ||
595 | + get :index, :profile => '~' | ||
596 | + assert_redirected_to :controller => 'test', :action => 'index', :profile => profile.identifier | ||
597 | + end | ||
598 | + | ||
581 | end | 599 | end |
test/functional/cms_controller_test.rb
@@ -1407,22 +1407,57 @@ class CmsControllerTest < ActionController::TestCase | @@ -1407,22 +1407,57 @@ class CmsControllerTest < ActionController::TestCase | ||
1407 | assert_template 'suggest_an_article' | 1407 | assert_template 'suggest_an_article' |
1408 | end | 1408 | end |
1409 | 1409 | ||
1410 | + should 'display name and email when a not logged in user suggest an article' do | ||
1411 | + logout | ||
1412 | + get :suggest_an_article, :profile => profile.identifier, :back_to => 'action_view' | ||
1413 | + | ||
1414 | + assert_select '#task_name' | ||
1415 | + assert_select '#task_email' | ||
1416 | + end | ||
1417 | + | ||
1418 | + should 'do not display name and email when a logged in user suggest an article' do | ||
1419 | + get :suggest_an_article, :profile => profile.identifier, :back_to => 'action_view' | ||
1420 | + | ||
1421 | + assert_select '#task_name', 0 | ||
1422 | + assert_select '#task_email', 0 | ||
1423 | + end | ||
1424 | + | ||
1425 | + should 'display captcha when suggest an article for not logged in users' do | ||
1426 | + logout | ||
1427 | + get :suggest_an_article, :profile => profile.identifier, :back_to => 'action_view' | ||
1428 | + | ||
1429 | + assert_select '#dynamic_recaptcha' | ||
1430 | + end | ||
1431 | + | ||
1432 | + should 'not display captcha when suggest an article for logged in users' do | ||
1433 | + get :suggest_an_article, :profile => profile.identifier, :back_to => 'action_view' | ||
1434 | + | ||
1435 | + assert_select '#dynamic_recaptcha', 0 | ||
1436 | + end | ||
1437 | + | ||
1410 | should 'render TinyMce Editor on suggestion of article' do | 1438 | should 'render TinyMce Editor on suggestion of article' do |
1411 | logout | 1439 | logout |
1412 | get :suggest_an_article, :profile => profile.identifier | 1440 | get :suggest_an_article, :profile => profile.identifier |
1413 | 1441 | ||
1414 | - assert_tag :tag => 'textarea', :attributes => { :name => /article_abstract/, :class => 'mceEditor' } | ||
1415 | - assert_tag :tag => 'textarea', :attributes => { :name => /article_body/, :class => 'mceEditor' } | 1442 | + assert_tag :tag => 'textarea', :attributes => { :name => /task\[article\]\[abstract\]/, :class => 'mceEditor' } |
1443 | + assert_tag :tag => 'textarea', :attributes => { :name => /task\[article\]\[body\]/, :class => 'mceEditor' } | ||
1416 | end | 1444 | end |
1417 | 1445 | ||
1418 | should 'create a task suggest task to a profile' do | 1446 | should 'create a task suggest task to a profile' do |
1419 | c = Community.create!(:name => 'test comm', :identifier => 'test_comm', :moderated_articles => true) | 1447 | c = Community.create!(:name => 'test comm', :identifier => 'test_comm', :moderated_articles => true) |
1420 | 1448 | ||
1421 | assert_difference 'SuggestArticle.count' do | 1449 | assert_difference 'SuggestArticle.count' do |
1422 | - post :suggest_an_article, :profile => c.identifier, :back_to => 'action_view', :task => {:article_name => 'some name', :article_body => 'some body', :email => 'some@localhost.com', :name => 'some name'} | 1450 | + post :suggest_an_article, :profile => c.identifier, :back_to => 'action_view', :task => {:article => {:name => 'some name', :body => 'some body'}, :email => 'some@localhost.com', :name => 'some name'} |
1423 | end | 1451 | end |
1424 | end | 1452 | end |
1425 | 1453 | ||
1454 | + should 'create suggest task with logged in user as the article author' do | ||
1455 | + c = Community.create!(:name => 'test comm', :identifier => 'test_comm', :moderated_articles => true) | ||
1456 | + | ||
1457 | + post :suggest_an_article, :profile => c.identifier, :back_to => 'action_view', :task => {:article => {:name => 'some name', :body => 'some body'}} | ||
1458 | + assert_equal profile, SuggestArticle.last.requestor | ||
1459 | + end | ||
1460 | + | ||
1426 | should 'suggest an article from a profile' do | 1461 | should 'suggest an article from a profile' do |
1427 | c = Community.create!(:name => 'test comm', :identifier => 'test_comm', :moderated_articles => true) | 1462 | c = Community.create!(:name => 'test comm', :identifier => 'test_comm', :moderated_articles => true) |
1428 | get :suggest_an_article, :profile => c.identifier, :back_to => c.identifier | 1463 | get :suggest_an_article, :profile => c.identifier, :back_to => c.identifier |
test/functional/content_viewer_controller_test.rb
@@ -175,7 +175,7 @@ class ContentViewerControllerTest < ActionController::TestCase | @@ -175,7 +175,7 @@ class ContentViewerControllerTest < ActionController::TestCase | ||
175 | admin = fast_create(Person) | 175 | admin = fast_create(Person) |
176 | community.add_member(admin) | 176 | community.add_member(admin) |
177 | 177 | ||
178 | - folder = fast_create(Folder, :profile_id => community.id, :published => false) | 178 | + folder = fast_create(Folder, :profile_id => community.id, :published => false, :show_to_followers => false) |
179 | community.add_member(profile) | 179 | community.add_member(profile) |
180 | login_as(profile.identifier) | 180 | login_as(profile.identifier) |
181 | 181 | ||
@@ -278,7 +278,7 @@ class ContentViewerControllerTest < ActionController::TestCase | @@ -278,7 +278,7 @@ class ContentViewerControllerTest < ActionController::TestCase | ||
278 | should 'not give access to private articles if logged in and only member' do | 278 | should 'not give access to private articles if logged in and only member' do |
279 | person = create_user('test_user').person | 279 | person = create_user('test_user').person |
280 | profile = Profile.create!(:name => 'test profile', :identifier => 'test_profile') | 280 | profile = Profile.create!(:name => 'test profile', :identifier => 'test_profile') |
281 | - intranet = Folder.create!(:name => 'my_intranet', :profile => profile, :published => false) | 281 | + intranet = Folder.create!(:name => 'my_intranet', :profile => profile, :published => false, :show_to_followers => false) |
282 | profile.affiliate(person, Profile::Roles.member(profile.environment.id)) | 282 | profile.affiliate(person, Profile::Roles.member(profile.environment.id)) |
283 | login_as('test_user') | 283 | login_as('test_user') |
284 | 284 | ||
@@ -780,6 +780,20 @@ class ContentViewerControllerTest < ActionController::TestCase | @@ -780,6 +780,20 @@ class ContentViewerControllerTest < ActionController::TestCase | ||
780 | assert_no_tag :tag => 'div', :attributes => { :class => 'short-post'}, :content => /Anything/ | 780 | assert_no_tag :tag => 'div', :attributes => { :class => 'short-post'}, :content => /Anything/ |
781 | end | 781 | end |
782 | 782 | ||
783 | + should 'show only first paragraph with picture of posts if visualization_format is short+pic' do | ||
784 | + login_as(profile.identifier) | ||
785 | + | ||
786 | + blog = Blog.create!(:name => 'A blog test', :profile => profile, :visualization_format => 'short+pic') | ||
787 | + | ||
788 | + blog.posts << TinyMceArticle.create!(:name => 'first post', :parent => blog, :profile => profile, :body => '<p>Content to be displayed.</p> <img src="pic.jpg">') | ||
789 | + | ||
790 | + get :view_page, :profile => profile.identifier, :page => blog.path | ||
791 | + | ||
792 | + assert_select '.blog-post .post-pic' do |el| | ||
793 | + assert_match /background-image:url\(pic.jpg\)/, el.to_s | ||
794 | + end | ||
795 | + end | ||
796 | + | ||
783 | should 'display link to edit blog for allowed' do | 797 | should 'display link to edit blog for allowed' do |
784 | blog = fast_create(Blog, :profile_id => profile.id, :path => 'blog') | 798 | blog = fast_create(Blog, :profile_id => profile.id, :path => 'blog') |
785 | login_as(profile.identifier) | 799 | login_as(profile.identifier) |
test/functional/profile_design_controller_test.rb
@@ -737,9 +737,9 @@ class ProfileDesignControllerTest < ActionController::TestCase | @@ -737,9 +737,9 @@ class ProfileDesignControllerTest < ActionController::TestCase | ||
737 | end | 737 | end |
738 | end | 738 | end |
739 | 739 | ||
740 | - test 'should forbid POST to save for fixed blocks' do | 740 | + test 'should forbid POST to save for uneditable blocks' do |
741 | block = profile.blocks.last | 741 | block = profile.blocks.last |
742 | - block.fixed = true | 742 | + block.edit_modes = "none" |
743 | block.save! | 743 | block.save! |
744 | 744 | ||
745 | post :save, id: block.id, profile: profile.identifier | 745 | post :save, id: block.id, profile: profile.identifier |
@@ -748,7 +748,7 @@ class ProfileDesignControllerTest < ActionController::TestCase | @@ -748,7 +748,7 @@ class ProfileDesignControllerTest < ActionController::TestCase | ||
748 | 748 | ||
749 | test 'should forbid POST to move_block for fixed blocks' do | 749 | test 'should forbid POST to move_block for fixed blocks' do |
750 | block = profile.blocks.last | 750 | block = profile.blocks.last |
751 | - block.fixed = true | 751 | + block.move_modes = "none" |
752 | block.save! | 752 | block.save! |
753 | 753 | ||
754 | post :move_block, id: block.id, profile: profile.identifier, target: "end-of-box-#{@box3.id}" | 754 | post :move_block, id: block.id, profile: profile.identifier, target: "end-of-box-#{@box3.id}" |
@@ -0,0 +1,106 @@ | @@ -0,0 +1,106 @@ | ||
1 | +require_relative "../test_helper" | ||
2 | +require 'profile_roles_controller' | ||
3 | + | ||
4 | +class ProfileRolesControllerTest < ActionController::TestCase | ||
5 | + | ||
6 | + def setup | ||
7 | + @controller = ProfileRolesController.new | ||
8 | + @request = ActionController::TestRequest.new | ||
9 | + @response = ActionController::TestResponse.new | ||
10 | + @role = Role.find(:first) | ||
11 | + end | ||
12 | + | ||
13 | + should 'create a custom role' do | ||
14 | + community = fast_create(Community) | ||
15 | + admin = create_user_with_permission('admin_user', 'manage_custom_roles', community) | ||
16 | + login_as :admin_user | ||
17 | + post :create, :profile => community.identifier, :role => {:name => "some_role", :permissions => ["edit_profile"] } | ||
18 | + role = Role.where(:name => 'some_role').first | ||
19 | + | ||
20 | + assert_not_nil role | ||
21 | + assert_equal community.id, role.profile_id | ||
22 | + end | ||
23 | + | ||
24 | + should 'not create a custom role without permission' do | ||
25 | + community = fast_create(Community) | ||
26 | + moderator = create_user_with_permission('profile_admin', 'edit_profile', community) | ||
27 | + login_as :profile_admin | ||
28 | + post :create, :profile => community.identifier, :role => {:name => "new_admin", :permissions => ["edit_profile"] } | ||
29 | + | ||
30 | + assert_response 403 | ||
31 | + assert_template 'access_denied' | ||
32 | + | ||
33 | + role = Role.where(:name => 'new_admin') | ||
34 | + | ||
35 | + assert_empty role | ||
36 | + end | ||
37 | + | ||
38 | + | ||
39 | + should 'delete a custom role not used' do | ||
40 | + community = fast_create(Community) | ||
41 | + admin = create_user_with_permission('admin_user', 'manage_custom_roles', community) | ||
42 | + login_as :admin_user | ||
43 | + role = Role.create!({:name => 'delete_article', :key => 'profile_delete_article', :profile_id => community.id, :environment => Environment.default}, :without_protection => true) | ||
44 | + post :remove , :profile => community.identifier, :id => role.id | ||
45 | + | ||
46 | + assert_response :redirect | ||
47 | + assert_redirected_to :action => 'index' | ||
48 | + | ||
49 | + assert_not_includes Role.all, role | ||
50 | + end | ||
51 | + | ||
52 | + should 'delete a custom role being used' do | ||
53 | + community = fast_create(Community) | ||
54 | + admin = create_user_with_permission('admin_user', 'manage_custom_roles', community) | ||
55 | + login_as :admin_user | ||
56 | + role = Role.create!({:name => 'delete_article', :key => 'profile_delete_article', :profile_id => community.id, :environment => Environment.default}, :without_protection => true) | ||
57 | + admin.add_role(role, community) | ||
58 | + moderator_role = Role.find_by_name("moderator") | ||
59 | + | ||
60 | + assert_not_includes community.members_by_role(moderator_role), admin | ||
61 | + | ||
62 | + post :remove , :profile => community.identifier, :id => role.id, :roles => [moderator_role.id] | ||
63 | + | ||
64 | + assert_response :redirect | ||
65 | + assert_redirected_to :action => 'index' | ||
66 | + | ||
67 | + assert_not_includes Role.all, role | ||
68 | + assert_includes community.members_by_role(moderator_role), admin | ||
69 | + end | ||
70 | + | ||
71 | + should 'assign a custom role to single user' do | ||
72 | + community = fast_create(Community) | ||
73 | + admin = create_user_with_permission('admin_user', 'manage_custom_roles', community) | ||
74 | + login_as :admin_user | ||
75 | + role = Role.create!({:name => 'delete_article', :key => 'profile_delete_article', :profile_id => community.id, :environment => Environment.default}, :without_protection => true) | ||
76 | + | ||
77 | + assert_not_includes community.members_by_role(role), admin | ||
78 | + | ||
79 | + post :define, :profile => community.identifier, :id => role.id, :assign_role_by => "members", :person_id => admin.id | ||
80 | + | ||
81 | + assert_includes community.members_by_role(role), admin | ||
82 | + end | ||
83 | + | ||
84 | + should 'replace a role with a custom role' do | ||
85 | + community = fast_create(Community) | ||
86 | + admin = create_user_with_permission('admin_user', 'manage_custom_roles', community) | ||
87 | + moderator = create_user_with_permission('profile_admin', 'edit_profile', community) | ||
88 | + login_as :admin_user | ||
89 | + role = Role.create!({:name => 'delete_article', :key => 'profile_delete_article', :profile_id => community.id, :environment => Environment.default}, :without_protection => true) | ||
90 | + moderator_role = Role.find_by_name("moderator") | ||
91 | + admin.add_role(moderator_role, community) | ||
92 | + | ||
93 | + assert_not_includes community.members_by_role(role), admin | ||
94 | + | ||
95 | + assert_not_includes community.members_by_role(role), moderator | ||
96 | + assert_not_includes community.members_by_role(moderator_role), moderator | ||
97 | + | ||
98 | + post :define, :profile => community.identifier, :id => role.id, :assign_role_by => "roles", :selected_role => moderator_role.id | ||
99 | + | ||
100 | + assert_not_includes community.members_by_role(moderator_role), admin | ||
101 | + assert_includes community.members_by_role(role), admin | ||
102 | + | ||
103 | + assert_not_includes community.members_by_role(role), moderator | ||
104 | + assert_not_includes community.members_by_role(moderator_role), moderator | ||
105 | + end | ||
106 | +end |
test/functional/spam_controller_test.rb
@@ -10,7 +10,7 @@ class SpamControllerTest < ActionController::TestCase | @@ -10,7 +10,7 @@ class SpamControllerTest < ActionController::TestCase | ||
10 | @article = fast_create(TextileArticle, :profile_id => @community.id) | 10 | @article = fast_create(TextileArticle, :profile_id => @community.id) |
11 | @spam_comment = fast_create(Comment, :source_id => @article.id, :spam => true, :name => 'foo', :email => 'foo@example.com') | 11 | @spam_comment = fast_create(Comment, :source_id => @article.id, :spam => true, :name => 'foo', :email => 'foo@example.com') |
12 | 12 | ||
13 | - @spam_suggest_article = SuggestArticle.create!(:name => 'spammer', :article_name => 'Spam article', :email => 'spammer@shady.place', :article_body => "Something you don't need", :target => @community, :spam => true) | 13 | + @spam_suggest_article = SuggestArticle.create!(:name => 'spammer', :article => {:name => 'Spam article', :body => "Something you don't need"}, :email => 'spammer@shady.place', :target => @community, :spam => true) |
14 | login_as @profile.identifier | 14 | login_as @profile.identifier |
15 | end | 15 | end |
16 | 16 |
test/functional/tasks_controller_test.rb
@@ -264,11 +264,11 @@ class TasksControllerTest < ActionController::TestCase | @@ -264,11 +264,11 @@ class TasksControllerTest < ActionController::TestCase | ||
264 | c = fast_create(Community) | 264 | c = fast_create(Community) |
265 | c.add_admin profile | 265 | c.add_admin profile |
266 | @controller.stubs(:profile).returns(c) | 266 | @controller.stubs(:profile).returns(c) |
267 | - t = SuggestArticle.create!(:article_name => 'test name', :article_abstract => 'test abstract', :article_body => 'test body', :name => 'some name', :email => 'test@localhost.com', :target => c) | 267 | + t = SuggestArticle.create!(:article => {:name => 'test name', :abstract => 'test abstract', :body => 'test body'}, :name => 'some name', :email => 'test@localhost.com', :target => c) |
268 | 268 | ||
269 | get :index | 269 | get :index |
270 | - assert_tag :tag => 'textarea', :content => /test abstract/, :attributes => { :name => /article_abstract/, :class => 'mceEditor' } | ||
271 | - assert_tag :tag => 'textarea', :content => /test body/, :attributes => { :name => /article_body/, :class => 'mceEditor' } | 270 | + assert_tag :tag => 'textarea', :content => /test abstract/, :attributes => { :name => /tasks\[#{t.id}\]\[task\]\[article\]\[abstract\]/, :class => 'mceEditor' } |
271 | + assert_tag :tag => 'textarea', :content => /test body/, :attributes => { :name => /tasks\[#{t.id}\]\[task\]\[article\]\[body\]/, :class => 'mceEditor' } | ||
272 | end | 272 | end |
273 | 273 | ||
274 | should 'create TinyMceArticle article after finish approve suggested article task' do | 274 | should 'create TinyMceArticle article after finish approve suggested article task' do |
@@ -276,7 +276,7 @@ class TasksControllerTest < ActionController::TestCase | @@ -276,7 +276,7 @@ class TasksControllerTest < ActionController::TestCase | ||
276 | c = fast_create(Community) | 276 | c = fast_create(Community) |
277 | c.affiliate(profile, Profile::Roles.all_roles(profile.environment.id)) | 277 | c.affiliate(profile, Profile::Roles.all_roles(profile.environment.id)) |
278 | @controller.stubs(:profile).returns(c) | 278 | @controller.stubs(:profile).returns(c) |
279 | - t = SuggestArticle.create!(:article_name => 'test name', :article_body => 'test body', :name => 'some name', :email => 'test@localhost.com', :target => c) | 279 | + t = SuggestArticle.create!(:article => {:name => 'test name', :body => 'test body'}, :name => 'some name', :email => 'test@localhost.com', :target => c) |
280 | 280 | ||
281 | post :close, :tasks => {t.id => { :task => {}, :decision => "finish"}} | 281 | post :close, :tasks => {t.id => { :task => {}, :decision => "finish"}} |
282 | assert_not_nil TinyMceArticle.find(:first) | 282 | assert_not_nil TinyMceArticle.find(:first) |
@@ -288,16 +288,13 @@ class TasksControllerTest < ActionController::TestCase | @@ -288,16 +288,13 @@ class TasksControllerTest < ActionController::TestCase | ||
288 | c.affiliate(profile, Profile::Roles.all_roles(profile.environment.id)) | 288 | c.affiliate(profile, Profile::Roles.all_roles(profile.environment.id)) |
289 | @controller.stubs(:profile).returns(c) | 289 | @controller.stubs(:profile).returns(c) |
290 | t = SuggestArticle.new | 290 | t = SuggestArticle.new |
291 | - t.article_name = 'test name' | ||
292 | - t.article_body = 'test body' | 291 | + t.article = {:name => 'test name', :body => 'test body', :source => 'http://test.com', :source_name => 'some source name'} |
293 | t.name = 'some name' | 292 | t.name = 'some name' |
294 | - t.source = 'http://test.com' | ||
295 | - t.source_name = 'some source name' | ||
296 | t.email = 'test@localhost.com' | 293 | t.email = 'test@localhost.com' |
297 | t.target = c | 294 | t.target = c |
298 | t.save! | 295 | t.save! |
299 | 296 | ||
300 | - post :close, :tasks => {t.id => { :task => {:article_name => 'new article name', :article_body => 'new body', :source => 'http://www.noosfero.com', :source_name => 'new source', :name => 'new name'}, :decision => "finish"}} | 297 | + post :close, :tasks => {t.id => { :task => {:article => {:name => 'new article name', :body => 'new body', :source => 'http://www.noosfero.com', :source_name => 'new source'}, :name => 'new name'}, :decision => "finish"}} |
301 | assert_equal 'new article name', TinyMceArticle.find(:first).name | 298 | assert_equal 'new article name', TinyMceArticle.find(:first).name |
302 | assert_equal 'new name', TinyMceArticle.find(:first).author_name | 299 | assert_equal 'new name', TinyMceArticle.find(:first).author_name |
303 | assert_equal 'new body', TinyMceArticle.find(:first).body | 300 | assert_equal 'new body', TinyMceArticle.find(:first).body |
@@ -305,6 +302,51 @@ class TasksControllerTest < ActionController::TestCase | @@ -305,6 +302,51 @@ class TasksControllerTest < ActionController::TestCase | ||
305 | assert_equal 'new source', TinyMceArticle.find(:first).source_name | 302 | assert_equal 'new source', TinyMceArticle.find(:first).source_name |
306 | end | 303 | end |
307 | 304 | ||
305 | + should "display name from article suggestion when requestor was not setted" do | ||
306 | + Task.destroy_all | ||
307 | + c = fast_create(Community) | ||
308 | + c.add_admin profile | ||
309 | + @controller.stubs(:profile).returns(c) | ||
310 | + t = SuggestArticle.create!(:article => {:name => 'test name', :abstract => 'test abstract', :body => 'test body'}, :name => 'some name', :email => 'test@localhost.com', :target => c) | ||
311 | + | ||
312 | + get :index | ||
313 | + assert_select "#tasks_#{t.id}_task_name" | ||
314 | + end | ||
315 | + | ||
316 | + should "append hidden tag with type value from article suggestion" do | ||
317 | + Task.destroy_all | ||
318 | + c = fast_create(Community) | ||
319 | + c.add_admin profile | ||
320 | + @controller.stubs(:profile).returns(c) | ||
321 | + t = SuggestArticle.create!(:article => {:name => 'test name', :abstract => 'test abstract', :body => 'test body', :type => 'TextArticle'}, :name => 'some name', :email => 'test@localhost.com', :target => c) | ||
322 | + | ||
323 | + get :index | ||
324 | + assert_select "#tasks_#{t.id}_task_article_type[value=TextArticle]" | ||
325 | + end | ||
326 | + | ||
327 | + should "display parent_id selection from article suggestion with predefined value" do | ||
328 | + Task.destroy_all | ||
329 | + c = fast_create(Community) | ||
330 | + c.add_admin profile | ||
331 | + @controller.stubs(:profile).returns(c) | ||
332 | + parent = fast_create(Folder, :profile_id => c.id) | ||
333 | + t = SuggestArticle.create!(:article => {:name => 'test name', :abstract => 'test abstract', :body => 'test body', :parent_id => parent.id}, :name => 'some name', :email => 'test@localhost.com', :target => c) | ||
334 | + | ||
335 | + get :index | ||
336 | + assert_select "#tasks_#{t.id}_task_article_parent_id option[value=#{parent.id}]" | ||
337 | + end | ||
338 | + | ||
339 | + should "not display name from article suggestion when requestor was setted" do | ||
340 | + Task.destroy_all | ||
341 | + c = fast_create(Community) | ||
342 | + c.add_admin profile | ||
343 | + @controller.stubs(:profile).returns(c) | ||
344 | + t = SuggestArticle.create!(:article => {:name => 'test name', :abstract => 'test abstract', :body => 'test body'}, :requestor => fast_create(Person), :target => c) | ||
345 | + | ||
346 | + get :index | ||
347 | + assert_select "#tasks_#{t.id}_task_name", 0 | ||
348 | + end | ||
349 | + | ||
308 | should "not crash if accessing close without tasks parameter" do | 350 | should "not crash if accessing close without tasks parameter" do |
309 | assert_nothing_raised do | 351 | assert_nothing_raised do |
310 | post :close | 352 | post :close |
test/integration/routing_test.rb
@@ -272,4 +272,8 @@ class RoutingTest < ActionController::IntegrationTest | @@ -272,4 +272,8 @@ class RoutingTest < ActionController::IntegrationTest | ||
272 | assert_routing('/embed/block/12345', :controller => 'embed', :action => 'block', :id => '12345') | 272 | assert_routing('/embed/block/12345', :controller => 'embed', :action => 'block', :id => '12345') |
273 | end | 273 | end |
274 | 274 | ||
275 | + should 'accept ~ as placeholder for current user' do | ||
276 | + assert_routing('/profile/~', :controller => 'profile', :profile => '~', :action => 'index') | ||
277 | + end | ||
278 | + | ||
275 | end | 279 | end |
test/unit/article_test.rb
@@ -1715,6 +1715,18 @@ class ArticleTest < ActiveSupport::TestCase | @@ -1715,6 +1715,18 @@ class ArticleTest < ActiveSupport::TestCase | ||
1715 | assert_equal 'bar.png', a.first_image | 1715 | assert_equal 'bar.png', a.first_image |
1716 | end | 1716 | end |
1717 | 1717 | ||
1718 | + should 'get first image from having_image' do | ||
1719 | + a = fast_create(Article, | ||
1720 | + :body => '<p>Foo</p><p><img src="bar.png" /></p>', | ||
1721 | + :abstract => '<p>Lead</p><p><img src="lead.png" /></p>' | ||
1722 | + ) | ||
1723 | + img = {} | ||
1724 | + img.expects(:present?).returns true | ||
1725 | + img.expects(:public_filename).returns 'pic.jpg' | ||
1726 | + a.expects(:image).at_least_once.returns img | ||
1727 | + assert_equal 'pic.jpg', a.first_image | ||
1728 | + end | ||
1729 | + | ||
1718 | should 'not get first image from anywhere' do | 1730 | should 'not get first image from anywhere' do |
1719 | a = fast_create(Article, :body => '<p>Foo</p><p>Bar</p>') | 1731 | a = fast_create(Article, :body => '<p>Foo</p><p>Bar</p>') |
1720 | assert_equal '', a.first_image | 1732 | assert_equal '', a.first_image |
test/unit/block_test.rb
@@ -35,6 +35,24 @@ class BlockTest < ActiveSupport::TestCase | @@ -35,6 +35,24 @@ class BlockTest < ActiveSupport::TestCase | ||
35 | assert Block.new.editable? | 35 | assert Block.new.editable? |
36 | end | 36 | end |
37 | 37 | ||
38 | + should 'be editable if edit modes is all' do | ||
39 | + block = Block.new | ||
40 | + block.edit_modes = 'all' | ||
41 | + | ||
42 | + assert block.editable? | ||
43 | + end | ||
44 | + | ||
45 | + should 'be movable by default' do | ||
46 | + assert Block.new.movable? | ||
47 | + end | ||
48 | + | ||
49 | + should 'be movable if move modes is all' do | ||
50 | + block = Block.new | ||
51 | + block.move_modes = 'all' | ||
52 | + | ||
53 | + assert block.movable? | ||
54 | + end | ||
55 | + | ||
38 | should 'have default titles' do | 56 | should 'have default titles' do |
39 | b = Block.new | 57 | b = Block.new |
40 | b.expects(:default_title).returns('my title') | 58 | b.expects(:default_title).returns('my title') |
@@ -330,4 +348,11 @@ class BlockTest < ActiveSupport::TestCase | @@ -330,4 +348,11 @@ class BlockTest < ActiveSupport::TestCase | ||
330 | block.save! | 348 | block.save! |
331 | assert !block.display_to_user?(person_friend) | 349 | assert !block.display_to_user?(person_friend) |
332 | end | 350 | end |
351 | + | ||
352 | + should 'get limit as a number when limit is string' do | ||
353 | + block = RecentDocumentsBlock.new | ||
354 | + block.settings[:limit] = '5' | ||
355 | + assert block.get_limit.is_a?(Fixnum) | ||
356 | + end | ||
357 | + | ||
333 | end | 358 | end |
test/unit/blog_helper_test.rb
@@ -20,30 +20,36 @@ class BlogHelperTest < ActionView::TestCase | @@ -20,30 +20,36 @@ class BlogHelperTest < ActionView::TestCase | ||
20 | def _(s); s; end | 20 | def _(s); s; end |
21 | def h(s); s; end | 21 | def h(s); s; end |
22 | 22 | ||
23 | - should 'list published posts with class blog-post' do | ||
24 | - blog.children << published_post = create(TextileArticle, :name => 'Post', :profile => profile, :parent => blog, :published => true) | ||
25 | - | ||
26 | - expects(:display_post).with(anything, anything).returns('POST') | ||
27 | - expects(:content_tag).with('div', "POST<br style=\"clear:both\"/>", :class => 'blog-post position-1 first last odd-post-inner', :id => "post-#{published_post.id}").returns('POST') | ||
28 | - expects(:content_tag).with('div', 'POST', {:class => 'odd-post'}).returns('RESULT') | ||
29 | - | ||
30 | - assert_equal 'RESULT', list_posts(blog.posts) | ||
31 | - end | ||
32 | - | ||
33 | - should 'list even/odd posts with a different class' do | ||
34 | - blog.children << older_post = create(TextileArticle, :name => 'First post', :profile => profile, :parent => blog, :published => true) | ||
35 | - | ||
36 | - blog.children << newer_post = create(TextileArticle, :name => 'Second post', :profile => profile, :parent => blog, :published => true) | ||
37 | - | ||
38 | - expects(:display_post).with(anything, anything).returns('POST').times(2) | ||
39 | - | ||
40 | - expects(:content_tag).with('div', "POST<br style=\"clear:both\"/>", :class => 'blog-post position-1 first odd-post-inner', :id => "post-#{newer_post.id}").returns('POST 1') | ||
41 | - expects(:content_tag).with('div', "POST 1", :class => 'odd-post').returns('ODD-POST') | ||
42 | - | ||
43 | - expects(:content_tag).with('div', "POST<br style=\"clear:both\"/>", :class => 'blog-post position-2 last even-post-inner', :id => "post-#{older_post.id}").returns('POST 2') | ||
44 | - expects(:content_tag).with('div', "POST 2", :class => 'even-post').returns('EVEN-POST') | ||
45 | - | ||
46 | - assert_equal "ODD-POST\n<hr class='sep-posts'/>\nEVEN-POST", list_posts(blog.posts) | 23 | + should 'list blog posts with identifiers and classes' do |
24 | + blog.children << older_post = create(TextileArticle, :name => 'First post', | ||
25 | + :profile => profile, :parent => blog, :published => true) | ||
26 | + blog.children << some_post = create(TextileArticle, :name => 'Some post', | ||
27 | + :profile => profile, :parent => blog, :published => true) | ||
28 | + blog.children << hidden_post = create(TextileArticle, :name => 'Hidden post', | ||
29 | + :profile => profile, :parent => blog, :published => false) | ||
30 | + blog.children << newer_post = create(TextileArticle, :name => 'Last post', | ||
31 | + :profile => profile, :parent => blog, :published => true) | ||
32 | + | ||
33 | + def content_tag(tag, content_or_options_with_block = nil, options = nil, &block) | ||
34 | + if block_given? | ||
35 | + options = content_or_options_with_block | ||
36 | + content = block.call | ||
37 | + else | ||
38 | + content = content_or_options_with_block | ||
39 | + end | ||
40 | + options ||= {} | ||
41 | + "<#{tag}#{options.map{|k,v| " #{k}=\"#{[v].flatten.join(' ')}\""}.join}>#{content}</#{tag}>" | ||
42 | + end | ||
43 | + | ||
44 | + html = HTML::Document.new(list_posts(blog.posts)).root | ||
45 | + assert_select html, "div#post-#{newer_post.id}.blog-post.position-1.first.odd-post" + | ||
46 | + " > div.odd-post-inner.blog-post-inner > .title", 'Last post' | ||
47 | + assert_select html, "div#post-#{hidden_post.id}.blog-post.position-2.not-published.even-post" + | ||
48 | + " > div.even-post-inner.blog-post-inner > .title", 'Hidden post' | ||
49 | + assert_select html, "div#post-#{some_post.id}.blog-post.position-3.odd-post" + | ||
50 | + " > div.odd-post-inner.blog-post-inner > .title", 'Some post' | ||
51 | + assert_select html, "div#post-#{older_post.id}.blog-post.position-4.last.even-post" + | ||
52 | + " > div.even-post-inner.blog-post-inner > .title", 'First post' | ||
47 | end | 53 | end |
48 | 54 | ||
49 | 55 |
test/unit/boxes_helper_test.rb
@@ -123,24 +123,24 @@ class BoxesHelperTest < ActionView::TestCase | @@ -123,24 +123,24 @@ class BoxesHelperTest < ActionView::TestCase | ||
123 | display_box_content(box, '') | 123 | display_box_content(box, '') |
124 | end | 124 | end |
125 | 125 | ||
126 | - should 'not show move options on block when block is fixed' do | 126 | + should 'not show move options on block when block has no permission to edit' do |
127 | p = create_user_with_blocks | 127 | p = create_user_with_blocks |
128 | 128 | ||
129 | b = p.blocks.select{|bk| !bk.kind_of?(MainBlock) }[0] | 129 | b = p.blocks.select{|bk| !bk.kind_of?(MainBlock) }[0] |
130 | - b.fixed = true | 130 | + b.move_modes = "none" |
131 | b.save! | 131 | b.save! |
132 | 132 | ||
133 | stubs(:environment).returns(p.environment) | 133 | stubs(:environment).returns(p.environment) |
134 | stubs(:user).returns(p) | 134 | stubs(:user).returns(p) |
135 | 135 | ||
136 | - assert_equal false, modifiable?(b) | 136 | + assert_equal false, movable?(b) |
137 | end | 137 | end |
138 | 138 | ||
139 | - should 'show move options on block when block is fixed and user is admin' do | 139 | + should 'show move options on block when block has no permission to edit and user is admin' do |
140 | p = create_user_with_blocks | 140 | p = create_user_with_blocks |
141 | 141 | ||
142 | b = p.blocks.select{|bk| !bk.kind_of?(MainBlock) }[0] | 142 | b = p.blocks.select{|bk| !bk.kind_of?(MainBlock) }[0] |
143 | - b.fixed = true | 143 | + b.edit_modes = "none" |
144 | b.save! | 144 | b.save! |
145 | 145 | ||
146 | p.environment.add_admin(p) | 146 | p.environment.add_admin(p) |
@@ -148,7 +148,7 @@ class BoxesHelperTest < ActionView::TestCase | @@ -148,7 +148,7 @@ class BoxesHelperTest < ActionView::TestCase | ||
148 | stubs(:environment).returns(p.environment) | 148 | stubs(:environment).returns(p.environment) |
149 | stubs(:user).returns(p) | 149 | stubs(:user).returns(p) |
150 | 150 | ||
151 | - assert_equal true, modifiable?(b) | 151 | + assert_equal true, movable?(b) |
152 | end | 152 | end |
153 | 153 | ||
154 | should 'consider boxes_limit without custom_design' do | 154 | should 'consider boxes_limit without custom_design' do |
@@ -198,4 +198,16 @@ class BoxesHelperTest < ActionView::TestCase | @@ -198,4 +198,16 @@ class BoxesHelperTest < ActionView::TestCase | ||
198 | assert_no_tag_in_string block_edit_buttons(block), :tag => 'a', :attributes => {:class => 'button icon-button icon-embed '} | 198 | assert_no_tag_in_string block_edit_buttons(block), :tag => 'a', :attributes => {:class => 'button icon-button icon-embed '} |
199 | end | 199 | end |
200 | 200 | ||
201 | + should 'only show edit option on block' do | ||
202 | + p = create_user_with_blocks | ||
203 | + | ||
204 | + b = p.blocks.select{|bk| !bk.kind_of?(MainBlock) }[0] | ||
205 | + b.edit_modes = "only_edit" | ||
206 | + b.save! | ||
207 | + | ||
208 | + stubs(:environment).returns(p.environment) | ||
209 | + stubs(:user).returns(p) | ||
210 | + | ||
211 | + assert_equal false, b.editable? | ||
212 | + end | ||
201 | end | 213 | end |
test/unit/enterprise_test.rb
@@ -188,7 +188,7 @@ class EnterpriseTest < ActiveSupport::TestCase | @@ -188,7 +188,7 @@ class EnterpriseTest < ActiveSupport::TestCase | ||
188 | inactive_template.save! | 188 | inactive_template.save! |
189 | 189 | ||
190 | active_template = create(Enterprise, :name => 'enteprise template', :identifier => 'enterprise_template') | 190 | active_template = create(Enterprise, :name => 'enteprise template', :identifier => 'enterprise_template') |
191 | - assert_equal 3, active_template.boxes.size | 191 | + assert_equal 4, active_template.boxes.size |
192 | 192 | ||
193 | e = Environment.default | 193 | e = Environment.default |
194 | e.inactive_enterprise_template = inactive_template | 194 | e.inactive_enterprise_template = inactive_template |
@@ -400,7 +400,7 @@ class EnterpriseTest < ActiveSupport::TestCase | @@ -400,7 +400,7 @@ class EnterpriseTest < ActiveSupport::TestCase | ||
400 | e.save! | 400 | e.save! |
401 | 401 | ||
402 | ent = create(Enterprise, :name => 'test enteprise', :identifier => 'test_ent') | 402 | ent = create(Enterprise, :name => 'test enteprise', :identifier => 'test_ent') |
403 | - assert_equal 3, ent.boxes.size | 403 | + assert_equal 4, ent.boxes.size |
404 | end | 404 | end |
405 | 405 | ||
406 | should 'collect the highlighted products with image' do | 406 | should 'collect the highlighted products with image' do |
test/unit/highlights_block_test.rb
@@ -109,33 +109,14 @@ class HighlightsBlockTest < ActiveSupport::TestCase | @@ -109,33 +109,14 @@ class HighlightsBlockTest < ActiveSupport::TestCase | ||
109 | end | 109 | end |
110 | 110 | ||
111 | should 'list images randomically' do | 111 | should 'list images randomically' do |
112 | - f1 = mock() | ||
113 | - f1.expects(:public_filename).returns('address') | ||
114 | - UploadedFile.expects(:find).with(1).returns(f1) | ||
115 | - f2 = mock() | ||
116 | - f2.expects(:public_filename).returns('address') | ||
117 | - UploadedFile.expects(:find).with(2).returns(f2) | ||
118 | - f3 = mock() | ||
119 | - f3.expects(:public_filename).returns('address') | ||
120 | - UploadedFile.expects(:find).with(3).returns(f3) | ||
121 | - f4 = mock() | ||
122 | - f4.expects(:public_filename).returns('address') | ||
123 | - UploadedFile.expects(:find).with(4).returns(f4) | ||
124 | - f5 = mock() | ||
125 | - f5.expects(:public_filename).returns('address') | ||
126 | - UploadedFile.expects(:find).with(5).returns(f5) | ||
127 | block = HighlightsBlock.new | 112 | block = HighlightsBlock.new |
128 | - i1 = {:image_id => 1, :address => '/address', :position => 3, :title => 'address'} | ||
129 | - i2 = {:image_id => 2, :address => '/address', :position => 1, :title => 'address'} | ||
130 | - i3 = {:image_id => 3, :address => '/address', :position => 2, :title => 'address'} | ||
131 | - i4 = {:image_id => 4, :address => '/address', :position => 5, :title => 'address'} | ||
132 | - i5 = {:image_id => 5, :address => '/address', :position => 4, :title => 'address'} | ||
133 | - block.images = [i1,i2,i3,i4,i5] | ||
134 | block.shuffle = true | 113 | block.shuffle = true |
135 | - block.save! | ||
136 | - block.reload | ||
137 | - assert_equal [i1,i2,i3,i4,i5], block.images | ||
138 | - assert_not_equal [i2,i3,i1,i4,i5], block.featured_images | 114 | + |
115 | + images = [] | ||
116 | + block.expects(:get_images).returns(images) | ||
117 | + images.expects(:shuffle).returns(images) | ||
118 | + | ||
119 | + block.featured_images | ||
139 | end | 120 | end |
140 | 121 | ||
141 | [Environment, Profile].each do |klass| | 122 | [Environment, Profile].each do |klass| |
test/unit/layout_helper_test.rb
@@ -30,4 +30,17 @@ class LayoutHelperTest < ActionView::TestCase | @@ -30,4 +30,17 @@ class LayoutHelperTest < ActionView::TestCase | ||
30 | assert_match /<link [^<]*href="\/designs\/themes\/my-theme\/global.css"/, css | 30 | assert_match /<link [^<]*href="\/designs\/themes\/my-theme\/global.css"/, css |
31 | end | 31 | end |
32 | 32 | ||
33 | + should 'append javascript files of enabled plugins in noosfero javascripts' do | ||
34 | + plugin1 = Noosfero::Plugin.new | ||
35 | + plugin1.expects(:js_files).returns(['plugin1.js']) | ||
36 | + plugin2 = Noosfero::Plugin.new | ||
37 | + plugin2.expects(:js_files).returns('plugin2.js') | ||
38 | + @plugins = [plugin1, plugin2] | ||
39 | + expects(:environment).returns(Environment.default).at_least_once | ||
40 | + expects(:profile).returns(nil).at_least_once | ||
41 | + js_tag = noosfero_javascript | ||
42 | + assert_match /plugin1\.js/, js_tag | ||
43 | + assert_match /plugin2\.js/, js_tag | ||
44 | + end | ||
45 | + | ||
33 | end | 46 | end |
test/unit/profile_test.rb
@@ -901,6 +901,8 @@ class ProfileTest < ActiveSupport::TestCase | @@ -901,6 +901,8 @@ class ProfileTest < ActiveSupport::TestCase | ||
901 | 901 | ||
902 | should 'copy set of articles from a template' do | 902 | should 'copy set of articles from a template' do |
903 | template = create_user('test_template').person | 903 | template = create_user('test_template').person |
904 | + template.is_template = true | ||
905 | + template.save | ||
904 | template.articles.destroy_all | 906 | template.articles.destroy_all |
905 | a1 = fast_create(Article, :profile_id => template.id, :name => 'some xyz article') | 907 | a1 = fast_create(Article, :profile_id => template.id, :name => 'some xyz article') |
906 | a2 = fast_create(Article, :profile_id => template.id, :name => 'some child article', :parent_id => a1.id) | 908 | a2 = fast_create(Article, :profile_id => template.id, :name => 'some child article', :parent_id => a1.id) |
@@ -934,6 +936,8 @@ class ProfileTest < ActiveSupport::TestCase | @@ -934,6 +936,8 @@ class ProfileTest < ActiveSupport::TestCase | ||
934 | 936 | ||
935 | should 'copy homepage from template' do | 937 | should 'copy homepage from template' do |
936 | template = create_user('test_template').person | 938 | template = create_user('test_template').person |
939 | + template.is_template = true | ||
940 | + template.save | ||
937 | template.articles.destroy_all | 941 | template.articles.destroy_all |
938 | a1 = fast_create(Article, :profile_id => template.id, :name => 'some xyz article') | 942 | a1 = fast_create(Article, :profile_id => template.id, :name => 'some xyz article') |
939 | template.home_page = a1 | 943 | template.home_page = a1 |
@@ -949,6 +953,8 @@ class ProfileTest < ActiveSupport::TestCase | @@ -949,6 +953,8 @@ class ProfileTest < ActiveSupport::TestCase | ||
949 | 953 | ||
950 | should 'not advertise the articles copied from templates' do | 954 | should 'not advertise the articles copied from templates' do |
951 | template = create_user('test_template').person | 955 | template = create_user('test_template').person |
956 | + template.is_template = true | ||
957 | + template.save | ||
952 | template.articles.destroy_all | 958 | template.articles.destroy_all |
953 | a = fast_create(Article, :profile_id => template.id, :name => 'some xyz article') | 959 | a = fast_create(Article, :profile_id => template.id, :name => 'some xyz article') |
954 | 960 | ||
@@ -962,7 +968,7 @@ class ProfileTest < ActiveSupport::TestCase | @@ -962,7 +968,7 @@ class ProfileTest < ActiveSupport::TestCase | ||
962 | end | 968 | end |
963 | 969 | ||
964 | should 'copy set of boxes from profile template' do | 970 | should 'copy set of boxes from profile template' do |
965 | - template = fast_create(Profile) | 971 | + template = fast_create(Profile, :is_template => true) |
966 | template.boxes.destroy_all | 972 | template.boxes.destroy_all |
967 | template.boxes << Box.new | 973 | template.boxes << Box.new |
968 | template.boxes[0].blocks << Block.new | 974 | template.boxes[0].blocks << Block.new |
@@ -977,7 +983,7 @@ class ProfileTest < ActiveSupport::TestCase | @@ -977,7 +983,7 @@ class ProfileTest < ActiveSupport::TestCase | ||
977 | end | 983 | end |
978 | 984 | ||
979 | should 'copy layout template when applying template' do | 985 | should 'copy layout template when applying template' do |
980 | - template = fast_create(Profile) | 986 | + template = fast_create(Profile, :is_template => true) |
981 | template.layout_template = 'leftbar' | 987 | template.layout_template = 'leftbar' |
982 | template.save! | 988 | template.save! |
983 | 989 | ||
@@ -989,7 +995,7 @@ class ProfileTest < ActiveSupport::TestCase | @@ -989,7 +995,7 @@ class ProfileTest < ActiveSupport::TestCase | ||
989 | end | 995 | end |
990 | 996 | ||
991 | should 'copy blocks when applying template' do | 997 | should 'copy blocks when applying template' do |
992 | - template = fast_create(Profile) | 998 | + template = fast_create(Profile, :is_template => true) |
993 | template.boxes.destroy_all | 999 | template.boxes.destroy_all |
994 | template.boxes << Box.new | 1000 | template.boxes << Box.new |
995 | template.boxes[0].blocks << Block.new | 1001 | template.boxes[0].blocks << Block.new |
@@ -1004,7 +1010,7 @@ class ProfileTest < ActiveSupport::TestCase | @@ -1004,7 +1010,7 @@ class ProfileTest < ActiveSupport::TestCase | ||
1004 | end | 1010 | end |
1005 | 1011 | ||
1006 | should 'copy articles when applying template' do | 1012 | should 'copy articles when applying template' do |
1007 | - template = fast_create(Profile) | 1013 | + template = fast_create(Profile, :is_template => true) |
1008 | template.articles.create(:name => 'template article') | 1014 | template.articles.create(:name => 'template article') |
1009 | template.save! | 1015 | template.save! |
1010 | 1016 | ||
@@ -1016,7 +1022,7 @@ class ProfileTest < ActiveSupport::TestCase | @@ -1016,7 +1022,7 @@ class ProfileTest < ActiveSupport::TestCase | ||
1016 | end | 1022 | end |
1017 | 1023 | ||
1018 | should 'rename existing articles when applying template' do | 1024 | should 'rename existing articles when applying template' do |
1019 | - template = fast_create(Profile) | 1025 | + template = fast_create(Profile, :is_template => true) |
1020 | template.boxes.destroy_all | 1026 | template.boxes.destroy_all |
1021 | template.boxes << Box.new | 1027 | template.boxes << Box.new |
1022 | template.boxes[0].blocks << Block.new | 1028 | template.boxes[0].blocks << Block.new |
@@ -1033,7 +1039,7 @@ class ProfileTest < ActiveSupport::TestCase | @@ -1033,7 +1039,7 @@ class ProfileTest < ActiveSupport::TestCase | ||
1033 | end | 1039 | end |
1034 | 1040 | ||
1035 | should 'copy header when applying template' do | 1041 | should 'copy header when applying template' do |
1036 | - template = fast_create(Profile) | 1042 | + template = fast_create(Profile, :is_template => true) |
1037 | template[:custom_header] = '{name}' | 1043 | template[:custom_header] = '{name}' |
1038 | template.save! | 1044 | template.save! |
1039 | 1045 | ||
@@ -1047,7 +1053,7 @@ class ProfileTest < ActiveSupport::TestCase | @@ -1047,7 +1053,7 @@ class ProfileTest < ActiveSupport::TestCase | ||
1047 | end | 1053 | end |
1048 | 1054 | ||
1049 | should 'copy footer when applying template' do | 1055 | should 'copy footer when applying template' do |
1050 | - template = create(Profile, :address => 'Template address', :custom_footer => '{address}') | 1056 | + template = create(Profile, :address => 'Template address', :custom_footer => '{address}', :is_template => true) |
1051 | 1057 | ||
1052 | p = create(Profile, :address => 'Profile address') | 1058 | p = create(Profile, :address => 'Profile address') |
1053 | p.apply_template(template) | 1059 | p.apply_template(template) |
@@ -1058,7 +1064,7 @@ class ProfileTest < ActiveSupport::TestCase | @@ -1058,7 +1064,7 @@ class ProfileTest < ActiveSupport::TestCase | ||
1058 | end | 1064 | end |
1059 | 1065 | ||
1060 | should 'ignore failing validation when applying template' do | 1066 | should 'ignore failing validation when applying template' do |
1061 | - template = create(Profile, :layout_template => 'leftbar', :custom_footer => 'my custom footer', :custom_header => 'my custom header') | 1067 | + template = create(Profile, :layout_template => 'leftbar', :custom_footer => 'my custom footer', :custom_header => 'my custom header', :is_template => true) |
1062 | 1068 | ||
1063 | p = create(Profile) | 1069 | p = create(Profile) |
1064 | def p.validate | 1070 | def p.validate |
@@ -1074,7 +1080,7 @@ class ProfileTest < ActiveSupport::TestCase | @@ -1074,7 +1080,7 @@ class ProfileTest < ActiveSupport::TestCase | ||
1074 | end | 1080 | end |
1075 | 1081 | ||
1076 | should 'copy homepage when applying template' do | 1082 | should 'copy homepage when applying template' do |
1077 | - template = fast_create(Profile) | 1083 | + template = fast_create(Profile, :is_template => true) |
1078 | a1 = fast_create(Article, :profile_id => template.id, :name => 'some xyz article') | 1084 | a1 = fast_create(Article, :profile_id => template.id, :name => 'some xyz article') |
1079 | template.home_page = a1 | 1085 | template.home_page = a1 |
1080 | template.save! | 1086 | template.save! |
@@ -1161,7 +1167,7 @@ class ProfileTest < ActiveSupport::TestCase | @@ -1161,7 +1167,7 @@ class ProfileTest < ActiveSupport::TestCase | ||
1161 | end | 1167 | end |
1162 | 1168 | ||
1163 | should 'copy public/private setting from template' do | 1169 | should 'copy public/private setting from template' do |
1164 | - template = fast_create(Profile, :public_profile => false) | 1170 | + template = fast_create(Profile, :public_profile => false, :is_template => true) |
1165 | p = fast_create(Profile) | 1171 | p = fast_create(Profile) |
1166 | p.apply_template(template) | 1172 | p.apply_template(template) |
1167 | assert_equal false, p.public_profile | 1173 | assert_equal false, p.public_profile |
test/unit/suggest_article_test.rb
@@ -13,16 +13,9 @@ class SuggestArticleTest < ActiveSupport::TestCase | @@ -13,16 +13,9 @@ class SuggestArticleTest < ActiveSupport::TestCase | ||
13 | 13 | ||
14 | should 'have the article_name' do | 14 | should 'have the article_name' do |
15 | t = SuggestArticle.new | 15 | t = SuggestArticle.new |
16 | - assert !t.errors[:article_name.to_s].present? | ||
17 | - t.valid? | ||
18 | - assert t.errors[:article_name.to_s].present? | ||
19 | - end | ||
20 | - | ||
21 | - should 'have the article_body' do | ||
22 | - t = SuggestArticle.new | ||
23 | - assert !t.errors[:article_body.to_s].present? | ||
24 | - t.valid? | ||
25 | - assert t.errors[:article_body.to_s].present? | 16 | + assert !t.article_object.errors[:name].present? |
17 | + t.article_object.valid? | ||
18 | + assert t.article_object.errors[:name].present? | ||
26 | end | 19 | end |
27 | 20 | ||
28 | should 'have the email' do | 21 | should 'have the email' do |
@@ -46,19 +39,12 @@ class SuggestArticleTest < ActiveSupport::TestCase | @@ -46,19 +39,12 @@ class SuggestArticleTest < ActiveSupport::TestCase | ||
46 | assert t.errors[:target_id.to_s].present? | 39 | assert t.errors[:target_id.to_s].present? |
47 | end | 40 | end |
48 | 41 | ||
49 | - should 'have the article_abstract' do | ||
50 | - t = SuggestArticle.new | ||
51 | - assert t.respond_to?(:article_abstract) | ||
52 | - end | ||
53 | - | ||
54 | - should 'have the article_parent_id' do | ||
55 | - t = SuggestArticle.new | ||
56 | - assert t.respond_to?(:article_parent_id) | ||
57 | - end | ||
58 | - | ||
59 | - should 'source be defined' do | 42 | + should 'have the article' do |
60 | t = SuggestArticle.new | 43 | t = SuggestArticle.new |
61 | - assert t.respond_to?(:source) | 44 | + assert t.respond_to?(:article_object) |
45 | + assert !t.errors[:article_object].present? | ||
46 | + t.valid? | ||
47 | + assert t.errors[:article_object].present? | ||
62 | end | 48 | end |
63 | 49 | ||
64 | should 'create an article on with perfom method' do | 50 | should 'create an article on with perfom method' do |
@@ -66,9 +52,7 @@ class SuggestArticleTest < ActiveSupport::TestCase | @@ -66,9 +52,7 @@ class SuggestArticleTest < ActiveSupport::TestCase | ||
66 | name = 'some name' | 52 | name = 'some name' |
67 | body = 'some body' | 53 | body = 'some body' |
68 | abstract = 'some abstract' | 54 | abstract = 'some abstract' |
69 | - t.article_name = name | ||
70 | - t.article_body = body | ||
71 | - t.article_abstract = abstract | 55 | + t.article = {:name => name, :body => body, :abstract => abstract} |
72 | t.target = @profile | 56 | t.target = @profile |
73 | count = TinyMceArticle.count | 57 | count = TinyMceArticle.count |
74 | t.perform | 58 | t.perform |
@@ -77,8 +61,7 @@ class SuggestArticleTest < ActiveSupport::TestCase | @@ -77,8 +61,7 @@ class SuggestArticleTest < ActiveSupport::TestCase | ||
77 | 61 | ||
78 | should 'fill source name and URL into created article' do | 62 | should 'fill source name and URL into created article' do |
79 | t = build(SuggestArticle, :target => @profile) | 63 | t = build(SuggestArticle, :target => @profile) |
80 | - t.source_name = 'GNU project' | ||
81 | - t.source = 'http://www.gnu.org/' | 64 | + t.article.merge!({:source_name => 'GNU project', :source => 'http://www.gnu.org/'}) |
82 | t.perform | 65 | t.perform |
83 | 66 | ||
84 | article = TinyMceArticle.last | 67 | article = TinyMceArticle.last |
@@ -95,7 +78,7 @@ class SuggestArticleTest < ActiveSupport::TestCase | @@ -95,7 +78,7 @@ class SuggestArticleTest < ActiveSupport::TestCase | ||
95 | 78 | ||
96 | should 'highlight created article' do | 79 | should 'highlight created article' do |
97 | t = build(SuggestArticle, :target => @profile) | 80 | t = build(SuggestArticle, :target => @profile) |
98 | - t.highlighted = true | 81 | + t.article[:highlighted] = true |
99 | t.perform | 82 | t.perform |
100 | 83 | ||
101 | article = TinyMceArticle.last(:conditions => { :name => t.article_name}) # just to be sure | 84 | article = TinyMceArticle.last(:conditions => { :name => t.article_name}) # just to be sure |
@@ -132,19 +115,19 @@ class SuggestArticleTest < ActiveSupport::TestCase | @@ -132,19 +115,19 @@ class SuggestArticleTest < ActiveSupport::TestCase | ||
132 | end | 115 | end |
133 | 116 | ||
134 | should 'have target notification message' do | 117 | should 'have target notification message' do |
135 | - task = build(SuggestArticle, :target => @profile, :article_name => 'suggested article', :name => 'johndoe') | 118 | + task = build(SuggestArticle, :target => @profile, :article => {:name => 'suggested article'}, :name => 'johndoe') |
136 | 119 | ||
137 | assert_match(/#{task.name}.*suggested the publication of the article: #{task.subject}.*[\n]*.*to approve or reject/, task.target_notification_message) | 120 | assert_match(/#{task.name}.*suggested the publication of the article: #{task.subject}.*[\n]*.*to approve or reject/, task.target_notification_message) |
138 | end | 121 | end |
139 | 122 | ||
140 | should 'have target notification description' do | 123 | should 'have target notification description' do |
141 | - task = build(SuggestArticle,:target => @profile, :article_name => 'suggested article', :name => 'johndoe') | 124 | + task = build(SuggestArticle,:target => @profile, :article => {:name => 'suggested article'}, :name => 'johndoe') |
142 | 125 | ||
143 | assert_match(/#{task.name}.*suggested the publication of the article: #{task.subject}/, task.target_notification_description) | 126 | assert_match(/#{task.name}.*suggested the publication of the article: #{task.subject}/, task.target_notification_description) |
144 | end | 127 | end |
145 | 128 | ||
146 | should 'deliver target notification message' do | 129 | should 'deliver target notification message' do |
147 | - task = build(SuggestArticle, :target => @profile, :article_name => 'suggested article', :name => 'johndoe', :email => 'johndoe@example.com') | 130 | + task = build(SuggestArticle, :target => @profile, :article => {:name => 'suggested article'}, :name => 'johndoe', :email => 'johndoe@example.com') |
148 | 131 | ||
149 | email = TaskMailer.target_notification(task, task.target_notification_message).deliver | 132 | email = TaskMailer.target_notification(task, task.target_notification_message).deliver |
150 | 133 | ||
@@ -160,7 +143,7 @@ class SuggestArticleTest < ActiveSupport::TestCase | @@ -160,7 +143,7 @@ class SuggestArticleTest < ActiveSupport::TestCase | ||
160 | should 'delegate spam detection to plugins' do | 143 | should 'delegate spam detection to plugins' do |
161 | Environment.default.enable_plugin(EverythingIsSpam) | 144 | Environment.default.enable_plugin(EverythingIsSpam) |
162 | 145 | ||
163 | - t1 = build(SuggestArticle, :target => @profile, :article_name => 'suggested article', :name => 'johndoe', :email => 'johndoe@example.com') | 146 | + t1 = build(SuggestArticle, :target => @profile, :article => {:name => 'suggested article'}, :name => 'johndoe', :email => 'johndoe@example.com') |
164 | 147 | ||
165 | EverythingIsSpam.any_instance.expects(:check_for_spam) | 148 | EverythingIsSpam.any_instance.expects(:check_for_spam) |
166 | 149 | ||
@@ -189,7 +172,7 @@ class SuggestArticleTest < ActiveSupport::TestCase | @@ -189,7 +172,7 @@ class SuggestArticleTest < ActiveSupport::TestCase | ||
189 | should 'notify plugins of suggest_articles being marked as spam' do | 172 | should 'notify plugins of suggest_articles being marked as spam' do |
190 | Environment.default.enable_plugin(SpamNotification) | 173 | Environment.default.enable_plugin(SpamNotification) |
191 | 174 | ||
192 | - t = SuggestArticle.create!(:target => @profile, :article_name => 'suggested article', :name => 'johndoe', :article_body => 'wanna feel my body? my body baaaby', :email => 'johndoe@example.com') | 175 | + t = SuggestArticle.create!(:target => @profile, :article => {:name => 'suggested article', :body => 'wanna feel my body? my body baaaby'}, :name => 'johndoe', :email => 'johndoe@example.com') |
193 | 176 | ||
194 | t.spam! | 177 | t.spam! |
195 | process_delayed_job_queue | 178 | process_delayed_job_queue |
@@ -200,7 +183,7 @@ class SuggestArticleTest < ActiveSupport::TestCase | @@ -200,7 +183,7 @@ class SuggestArticleTest < ActiveSupport::TestCase | ||
200 | should 'notify plugins of suggest_articles being marked as ham' do | 183 | should 'notify plugins of suggest_articles being marked as ham' do |
201 | Environment.default.enable_plugin(SpamNotification) | 184 | Environment.default.enable_plugin(SpamNotification) |
202 | 185 | ||
203 | - t = SuggestArticle.create!(:target => @profile, :article_name => 'suggested article', :name => 'johndoe', :article_body => 'wanna feel my body? my body baaaby', :email => 'johndoe@example.com') | 186 | + t = SuggestArticle.create!(:target => @profile, :article => {:name => 'suggested article', :body => 'wanna feel my body? my body baaaby'}, :name => 'johndoe', :email => 'johndoe@example.com') |
204 | 187 | ||
205 | t.ham! | 188 | t.ham! |
206 | process_delayed_job_queue | 189 | process_delayed_job_queue |
@@ -219,10 +202,44 @@ class SuggestArticleTest < ActiveSupport::TestCase | @@ -219,10 +202,44 @@ class SuggestArticleTest < ActiveSupport::TestCase | ||
219 | end | 202 | end |
220 | 203 | ||
221 | should 'log spammer ip after marking comment as spam' do | 204 | should 'log spammer ip after marking comment as spam' do |
222 | - t = SuggestArticle.create!(:target => @profile, :article_name => 'suggested article', :name => 'johndoe', :article_body => 'wanna feel my body? my body baaaby', :email => 'johndoe@example.com', :ip_address => '192.168.0.1') | 205 | + t = SuggestArticle.create!(:target => @profile, :article => {:name => 'suggested article', :body => 'wanna feel my body? my body baaaby'}, :name => 'johndoe', :email => 'johndoe@example.com', :ip_address => '192.168.0.1') |
223 | t.spam! | 206 | t.spam! |
224 | log = File.open('log/test_spammers.log') | 207 | log = File.open('log/test_spammers.log') |
225 | assert_match "SuggestArticle-id: #{t.id} IP: 192.168.0.1", log.read | 208 | assert_match "SuggestArticle-id: #{t.id} IP: 192.168.0.1", log.read |
226 | end | 209 | end |
227 | 210 | ||
211 | + should 'not require name and email when requestor is present' do | ||
212 | + t = SuggestArticle.new(:requestor => fast_create(Person)) | ||
213 | + t.valid? | ||
214 | + assert t.errors[:email].blank? | ||
215 | + assert t.errors[:name].blank? | ||
216 | + end | ||
217 | + | ||
218 | + should 'return name as sender when requestor is setted' do | ||
219 | + person = fast_create(Person) | ||
220 | + t = SuggestArticle.new(:requestor => person) | ||
221 | + assert_equal person.name, t.sender | ||
222 | + end | ||
223 | + | ||
224 | + should 'create an event on perfom method' do | ||
225 | + t = SuggestArticle.new | ||
226 | + t.article = {:name => 'name', :body => 'body', :type => 'Event'} | ||
227 | + t.target = @profile | ||
228 | + assert_difference "Event.count" do | ||
229 | + t.perform | ||
230 | + end | ||
231 | + end | ||
232 | + | ||
233 | + should 'accept article type parameter' do | ||
234 | + t = SuggestArticle.new | ||
235 | + t.article = {:name => 'name', :body => 'body', :type => 'TextArticle'} | ||
236 | + t.article_type == TextArticle | ||
237 | + end | ||
238 | + | ||
239 | + should 'fallback to tinymce when type parameter is invalid' do | ||
240 | + t = SuggestArticle.new | ||
241 | + t.article = {:name => 'name', :body => 'body', :type => 'Comment'} | ||
242 | + t.article_type == TinyMceArticle | ||
243 | + end | ||
244 | + | ||
228 | end | 245 | end |
test/unit/user_mailer_test.rb
@@ -18,6 +18,14 @@ class UserMailerTest < ActiveSupport::TestCase | @@ -18,6 +18,14 @@ class UserMailerTest < ActiveSupport::TestCase | ||
18 | end | 18 | end |
19 | end | 19 | end |
20 | 20 | ||
21 | + should 'deliver profiles suggestions email' do | ||
22 | + person = create_user('some-user').person | ||
23 | + ProfileSuggestion.create!(:person => person, :suggestion => | ||
24 | +fast_create(Person)) | ||
25 | + email = UserMailer.profiles_suggestions_email(person).deliver | ||
26 | + assert_match /profile\/some-user\/friends\/suggest/, email.body.to_s | ||
27 | + end | ||
28 | + | ||
21 | private | 29 | private |
22 | 30 | ||
23 | def read_fixture(action) | 31 | def read_fixture(action) |
test/unit/user_test.rb
@@ -87,6 +87,14 @@ class UserTest < ActiveSupport::TestCase | @@ -87,6 +87,14 @@ class UserTest < ActiveSupport::TestCase | ||
87 | assert_equal person_count + 1, Person.count | 87 | assert_equal person_count + 1, Person.count |
88 | end | 88 | end |
89 | 89 | ||
90 | + def test_should_create_person_with_identifier_different_from_login | ||
91 | + user = User.create!(:login => 'new_user', :email => 'new_user@example.com', :password => 'test', :password_confirmation => 'test', :person_data => {:identifier => "new_test"}) | ||
92 | + | ||
93 | + assert Person.exists?(['user_id = ?', user.id]) | ||
94 | + | ||
95 | + assert user.login != user.person.identifier | ||
96 | + end | ||
97 | + | ||
90 | def test_login_validation | 98 | def test_login_validation |
91 | u = User.new | 99 | u = User.new |
92 | u.valid? | 100 | u.valid? |
@@ -355,7 +363,7 @@ class UserTest < ActiveSupport::TestCase | @@ -355,7 +363,7 @@ class UserTest < ActiveSupport::TestCase | ||
355 | Person.any_instance.stubs(:created_at).returns(DateTime.parse('16-08-2010')) | 363 | Person.any_instance.stubs(:created_at).returns(DateTime.parse('16-08-2010')) |
356 | expected_hash = { | 364 | expected_hash = { |
357 | 'login' => 'x_and_y', 'is_admin' => true, 'since_month' => 8, | 365 | 'login' => 'x_and_y', 'is_admin' => true, 'since_month' => 8, |
358 | - 'chat_enabled' => false, 'since_year' => 2010, 'email_domain' => nil, | 366 | + 'chat_enabled' => false, 'since_year' => 2010, 'email_domain' => nil, |
359 | 'amount_of_friends' => 0, 'friends_list' => {}, 'enterprises' => [], | 367 | 'amount_of_friends' => 0, 'friends_list' => {}, 'enterprises' => [], |
360 | } | 368 | } |
361 | 369 | ||
@@ -546,6 +554,7 @@ class UserTest < ActiveSupport::TestCase | @@ -546,6 +554,7 @@ class UserTest < ActiveSupport::TestCase | ||
546 | 554 | ||
547 | should 'delay activation check with custom time' do | 555 | should 'delay activation check with custom time' do |
548 | NOOSFERO_CONF.stubs(:[]).with('hours_until_user_activation_check').returns(240) | 556 | NOOSFERO_CONF.stubs(:[]).with('hours_until_user_activation_check').returns(240) |
557 | + NOOSFERO_CONF.stubs(:[]).with('exclude_profile_identifier_pattern') | ||
549 | user = new_user | 558 | user = new_user |
550 | job = Delayed::Job.last | 559 | job = Delayed::Job.last |
551 | assert_match /UserActivationJob/, job.handler | 560 | assert_match /UserActivationJob/, job.handler |
util/debian-install/Vagrantfile
@@ -13,9 +13,11 @@ else | @@ -13,9 +13,11 @@ else | ||
13 | local_debs = Dir.glob('*.deb') | 13 | local_debs = Dir.glob('*.deb') |
14 | debs.each do |f| | 14 | debs.each do |f| |
15 | fn = File.basename(f) | 15 | fn = File.basename(f) |
16 | - if local_debs.include?(fn) | ||
17 | - local_debs.delete(fn) | ||
18 | - else | 16 | + |
17 | + local_debs.delete(fn) | ||
18 | + | ||
19 | + if File.stat(f) != File.stat(fn) | ||
20 | + FileUtils::Verbose.rm_f(fn) | ||
19 | FileUtils::Verbose.ln f, '.' | 21 | FileUtils::Verbose.ln f, '.' |
20 | end | 22 | end |
21 | end | 23 | end |
util/debian-install/install
@@ -61,19 +61,35 @@ deb http://download.noosfero.org/debian/wheezy-test ./ | @@ -61,19 +61,35 @@ deb http://download.noosfero.org/debian/wheezy-test ./ | ||
61 | deb-src http://download.noosfero.org/debian/wheezy-test ./ | 61 | deb-src http://download.noosfero.org/debian/wheezy-test ./ |
62 | EOF | 62 | EOF |
63 | 63 | ||
64 | +sed -e 's/wheezy/&-backports/' \ | ||
65 | + /etc/apt/sources.list > /etc/apt/sources.list.d/backports.list | ||
66 | + | ||
64 | export DEBIAN_FRONTEND=noninteractive | 67 | export DEBIAN_FRONTEND=noninteractive |
65 | 68 | ||
69 | +# local debs | ||
70 | +if [ -n "$(find /vagrant -name '*.deb')" ]; then | ||
71 | + apt-get install -qy apt-utils bzip2 | ||
72 | + ( | ||
73 | + rm -rf /opt/noosfero | ||
74 | + mkdir /opt/noosfero | ||
75 | + cp /vagrant/*.deb /opt/noosfero | ||
76 | + cd /opt/noosfero | ||
77 | + apt-ftparchive packages . > Packages | ||
78 | + cat Packages | gzip - > Packages.gz | ||
79 | + cat Packages | bzip2 - > Packages.bz2 | ||
80 | + apt-ftparchive release . > Release | ||
81 | + echo 'deb [trusted=yes] file:///opt/noosfero ./' > /etc/apt/sources.list.d/local.list | ||
82 | + ) | ||
83 | +else | ||
84 | + rm -f /etc/apt/sources.list.d/local.list | ||
85 | +fi | ||
86 | + | ||
66 | apt-get update | 87 | apt-get update |
67 | apt-get dist-upgrade -qy | 88 | apt-get dist-upgrade -qy |
68 | -apt-get install -qy postgresql ruby1.8 | 89 | +apt-get install -qy postgresql |
69 | 90 | ||
70 | -if dpkg --unpack /vagrant/noosfero_*.deb /vagrant/noosfero-apache_*.deb; then | ||
71 | - apt-cache policy noosfero | ||
72 | - apt-get install -qyf | ||
73 | -else | ||
74 | - apt-cache policy noosfero | ||
75 | - apt-get install -qy noosfero noosfero-apache | ||
76 | -fi | 91 | +apt-cache policy noosfero |
92 | +apt-get install -qy noosfero noosfero-apache | ||
77 | 93 | ||
78 | a2dissite 000-default | 94 | a2dissite 000-default |
79 | service apache2 reload | 95 | service apache2 reload |
vendor/plugins/access_control/lib/role.rb
@@ -4,6 +4,7 @@ class Role < ActiveRecord::Base | @@ -4,6 +4,7 @@ class Role < ActiveRecord::Base | ||
4 | 4 | ||
5 | has_many :role_assignments, :dependent => :destroy | 5 | has_many :role_assignments, :dependent => :destroy |
6 | belongs_to :environment | 6 | belongs_to :environment |
7 | + belongs_to :organization | ||
7 | serialize :permissions, Array | 8 | serialize :permissions, Array |
8 | validates_presence_of :name | 9 | validates_presence_of :name |
9 | validates_uniqueness_of :name, :scope => :environment_id | 10 | validates_uniqueness_of :name, :scope => :environment_id |