Commit 2d5abd83f444c11a87628abb5a60beec1d1ddce5

Authored by root
1 parent c9f4c639

mergin with master

Showing 420 changed files with 10963 additions and 7586 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 420 files displayed.

AUTHORS
... ... @@ -120,6 +120,7 @@ Larissa Reis <reiss.larissa@gmail.com>
120 120 Leandro Nunes dos Santos <leandronunes@gmail.com>
121 121 Leandro Nunes dos Santos <leandro.santos@serpro.gov.br>
122 122 LinguÁgil 2010 <linguagil.bahia@gmail.com>
  123 +Luis David Aguilar Carlos <ludwig9003@gmail.com>
123 124 Martín Olivera <molivera@solar.org.ar>
124 125 Moises Machado <moises@colivre.coop.br>
125 126 Nanda Lopes <nanda.listas+psl@gmail.com>
... ... @@ -147,6 +148,7 @@ Rodrigo Souto &lt;rodrigo@colivre.coop.br&gt;
147 148 Ronny Kursawe <kursawe.ronny@googlemail.com>
148 149 Samuel R. C. Vale <srcvale@holoscopio.com>
149 150 Valessio Brito <valessio@gmail.com>
  151 +Visita <visita@debian.(none)>
150 152 Yann Lugrin <yann.lugrin@liquid-concept.ch>
151 153  
152 154 Ideas, specifications and incentive
... ...
Gemfile
1   -source :rubygems
2   -gem 'cucumber', '0.4.0'
3   -gem 'webrat', '0.5.1'
4   -gem 'rspec', '1.2.9'
5   -gem 'rspec-rails', '1.2.9'
6   -gem 'Selenium', '>= 1.1.14'
7   -gem 'selenium-client', '>= 1.2.17'
8   -gem 'database_cleaner'
  1 +source "https://rubygems.org"
  2 +
9 3 gem 'exception_notification', '1.0.20090728'
10 4 gem 'system_timer'
11 5  
  6 +group :test do
  7 + gem 'rspec', '1.2.9'
  8 + gem 'rspec-rails', '1.2.9'
  9 +end
  10 +
  11 +group :cucumber do
  12 + gem 'rake', '0.8.7'
  13 + gem 'cucumber-rails', '0.3.2'
  14 + gem 'capybara', '1.1.1'
  15 + gem 'cucumber', '1.1.0'
  16 + gem 'database_cleaner'
  17 +end
  18 +
12 19 def program(name)
13 20 unless system("which #{name} > /dev/null")
14 21 puts "W: Program #{name} is needed, but was not found in your PATH"
... ...
Gemfile.lock
1 1 GEM
2   - remote: http://rubygems.org/
  2 + remote: https://rubygems.org/
3 3 specs:
4   - Selenium (1.1.14)
5   - builder (3.0.0)
6   - cucumber (0.4.0)
  4 + builder (3.1.4)
  5 + capybara (1.1.1)
  6 + mime-types (>= 1.16)
  7 + nokogiri (>= 1.3.3)
  8 + rack (>= 1.0.0)
  9 + rack-test (>= 0.5.4)
  10 + selenium-webdriver (~> 2.0)
  11 + xpath (~> 0.1.4)
  12 + childprocess (0.3.6)
  13 + ffi (~> 1.0, >= 1.0.6)
  14 + cucumber (1.1.0)
7 15 builder (>= 2.1.2)
8 16 diff-lcs (>= 1.1.2)
9   - polyglot (>= 0.2.9)
10   - term-ansicolor (>= 1.0.3)
11   - treetop (>= 1.4.2)
12   - database_cleaner (0.7.0)
  17 + gherkin (~> 2.5.0)
  18 + json (>= 1.4.6)
  19 + term-ansicolor (>= 1.0.6)
  20 + cucumber-rails (0.3.2)
  21 + cucumber (>= 0.8.0)
  22 + database_cleaner (0.9.1)
13 23 diff-lcs (1.1.3)
14 24 exception_notification (1.0.20090728)
15   - nokogiri (1.5.0)
16   - polyglot (0.3.3)
17   - rack (1.3.5)
  25 + ffi (1.2.0)
  26 + gherkin (2.5.4)
  27 + json (>= 1.4.6)
  28 + json (1.7.5)
  29 + libwebsocket (0.1.6.1)
  30 + websocket
  31 + mime-types (1.19)
  32 + multi_json (1.3.7)
  33 + nokogiri (1.5.5)
  34 + rack (1.1.0)
  35 + rack-test (0.6.2)
  36 + rack (>= 1.0)
  37 + rake (0.8.7)
18 38 rspec (1.2.9)
19 39 rspec-rails (1.2.9)
20 40 rack (>= 1.0.0)
21 41 rspec (>= 1.2.9)
22   - selenium-client (1.2.18)
  42 + rubyzip (0.9.9)
  43 + selenium-webdriver (2.26.0)
  44 + childprocess (>= 0.2.5)
  45 + libwebsocket (~> 0.1.3)
  46 + multi_json (~> 1.0)
  47 + rubyzip
23 48 system_timer (1.2.4)
24 49 term-ansicolor (1.0.7)
25   - treetop (1.4.10)
26   - polyglot
27   - polyglot (>= 0.3.1)
28   - webrat (0.5.1)
29   - nokogiri (>= 1.2.0)
30   - rack (>= 1.0)
  50 + websocket (1.0.4)
  51 + xpath (0.1.4)
  52 + nokogiri (~> 1.3)
31 53  
32 54 PLATFORMS
33 55 ruby
34 56  
35 57 DEPENDENCIES
36   - Selenium (>= 1.1.14)
37   - cucumber (= 0.4.0)
  58 + capybara (= 1.1.1)
  59 + cucumber (= 1.1.0)
  60 + cucumber-rails (= 0.3.2)
38 61 database_cleaner
39 62 exception_notification (= 1.0.20090728)
  63 + rake (= 0.8.7)
40 64 rspec (= 1.2.9)
41 65 rspec-rails (= 1.2.9)
42   - selenium-client (>= 1.2.17)
43 66 system_timer
44   - webrat (= 0.5.1)
... ...
INSTALL.varnish
... ... @@ -45,6 +45,10 @@ Install the RPAF apache module (or skip this step if not using apache):
45 45 On manual installations, change "/etc/noosfero/*" to
46 46 "{Rails.root}/etc/noosfero/*"
47 47  
  48 +NOTE: it is very important that the *.vcl files are included in that order,
  49 +i.e. *first* include "varnish-noosfero.vcl", and *after*
  50 +"noosfero-accept-language.cvl".
  51 +
48 52 4c) Restart Varnish
49 53  
50 54 # invoke-rc.d varnish restart
... ...
RELEASING
... ... @@ -31,6 +31,7 @@ To prepare a release of noosfero, you must follow the steps below:
31 31 sha1 of the package (with sha1sum and paste the SHA1 hash as comment in the
32 32 attachment form)
33 33 * Download the attached and verify the MD5 hash
  34 +* Push the new version tag (with git push --tags)
34 35 * Update an eventual demonstration version that you run.
35 36 * Write an announcement e-mail to the relevant mailing lists pointing to the
36 37 release notes, and maybe to the demonstration version.
... ...
app/controllers/admin/environment_design_controller.rb
... ... @@ -3,7 +3,7 @@ class EnvironmentDesignController &lt; BoxOrganizerController
3 3 protect 'edit_environment_design', :environment
4 4  
5 5 def available_blocks
6   - @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock ]
  6 + @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock, TagsBlock ]
7 7 @available_blocks = @available_blocks + plugins.dispatch(:extra_blocks, :type => Environment)
8 8 end
9 9  
... ...
app/controllers/admin/users_controller.rb
  1 +require 'csv'
  2 +
1 3 class UsersController < AdminController
2 4  
3 5 protect 'manage_environment_users', :environment
... ... @@ -15,8 +17,16 @@ class UsersController &lt; AdminController
15 17 :disposition => "attachment; filename=users.xml"
16 18 end
17 19 format.csv do
18   - @users = User.find(:all, :conditions => {:environment_id => environment.id}, :include => [:person])
19   - render :template => "users/index_csv.rhtml", :content_type => 'text/csv', :layout => false
  20 + # using a direct connection with the dbms to optimize
  21 + command = User.send(:sanitize_sql, ["SELECT profiles.name, users.email FROM profiles
  22 + INNER JOIN users ON profiles.user_id=users.id
  23 + WHERE profiles.environment_id = ?", environment.id])
  24 + users = User.connection.execute(command)
  25 + csv_content = "name;email\n"
  26 + users.each { |u|
  27 + CSV.generate_row([u['name'], u['email']], 2, csv_content, fs=';')
  28 + }
  29 + render :text => csv_content, :content_type => 'text/csv', :layout => false
20 30 end
21 31 end
22 32 end
... ...
app/controllers/my_profile/profile_members_controller.rb
... ... @@ -32,7 +32,6 @@ class ProfileMembersController &lt; MyProfileController
32 32  
33 33 def last_admin
34 34 @roles = [Profile::Roles.admin(environment.id)]
35   - @pre_population = [].to_json
36 35 end
37 36  
38 37 def add_role
... ...
app/controllers/public/account_controller.rb
... ... @@ -4,6 +4,7 @@ class AccountController &lt; ApplicationController
4 4  
5 5 before_filter :login_required, :only => [:activation_question, :accept_terms, :activate_enterprise]
6 6 before_filter :redirect_if_logged_in, :only => [:login, :signup]
  7 + before_filter :protect_from_bots, :only => :signup
7 8  
8 9 # say something nice, you goof! something sweet.
9 10 def index
... ... @@ -55,6 +56,11 @@ class AccountController &lt; ApplicationController
55 56 render :action => 'login', :layout => false
56 57 end
57 58  
  59 + def signup_time
  60 + key = set_signup_start_time_for_now
  61 + render :text => { :ok=>true, :key=>key }.to_json
  62 + end
  63 +
58 64 # action to register an user to the application
59 65 def signup
60 66 if @plugins.dispatch(:allow_user_registration).include?(false)
... ... @@ -62,12 +68,9 @@ class AccountController &lt; ApplicationController
62 68 session[:notice] = _("This environment doesn't allow user registration.")
63 69 end
64 70  
  71 + @block_bot = !!session[:may_be_a_bot]
65 72 @invitation_code = params[:invitation_code]
66 73 begin
67   - if params[:user]
68   - params[:user].delete(:password_confirmation_clear)
69   - params[:user].delete(:password_clear)
70   - end
71 74 @user = User.new(params[:user])
72 75 @user.terms_of_use = environment.terms_of_use
73 76 @user.environment = environment
... ... @@ -76,19 +79,28 @@ class AccountController &lt; ApplicationController
76 79 @person = Person.new(params[:profile_data])
77 80 @person.environment = @user.environment
78 81 if request.post?
79   - @user.signup!
80   - owner_role = Role.find_by_name('owner')
81   - @user.person.affiliate(@user.person, [owner_role]) if owner_role
82   - invitation = Task.find_by_code(@invitation_code)
83   - if invitation
84   - invitation.update_attributes!({:friend => @user.person})
85   - invitation.finish
86   - end
87   - if @user.activated?
88   - self.current_user = @user
89   - redirect_to '/'
  82 + if may_be_a_bot
  83 + set_signup_start_time_for_now
  84 + @block_bot = true
  85 + session[:may_be_a_bot] = true
90 86 else
91   - @register_pending = true
  87 + if session[:may_be_a_bot]
  88 + return false unless verify_recaptcha :model=>@user, :message=>_('Captcha (the human test)')
  89 + end
  90 + @user.signup!
  91 + owner_role = Role.find_by_name('owner')
  92 + @user.person.affiliate(@user.person, [owner_role]) if owner_role
  93 + invitation = Task.find_by_code(@invitation_code)
  94 + if invitation
  95 + invitation.update_attributes!({:friend => @user.person})
  96 + invitation.finish
  97 + end
  98 + if @user.activated?
  99 + self.current_user = @user
  100 + redirect_to '/'
  101 + else
  102 + @register_pending = true
  103 + end
92 104 end
93 105 end
94 106 rescue ActiveRecord::RecordInvalid
... ... @@ -97,6 +109,7 @@ class AccountController &lt; ApplicationController
97 109 @person.errors.delete(:user_id)
98 110 render :action => 'signup'
99 111 end
  112 + clear_signup_start_time
100 113 end
101 114  
102 115 # action to perform logout from the application
... ... @@ -271,7 +284,36 @@ class AccountController &lt; ApplicationController
271 284 def no_redirect
272 285 @cannot_redirect = true
273 286 end
274   -
  287 +
  288 + def set_signup_start_time_for_now
  289 + key = 'signup_start_time_' + rand.to_s.split('.')[1]
  290 + Rails.cache.write key, Time.now
  291 + key
  292 + end
  293 +
  294 + def get_signup_start_time
  295 + Rails.cache.read params[:signup_time_key]
  296 + end
  297 +
  298 + def clear_signup_start_time
  299 + Rails.cache.delete params[:signup_time_key] if params[:signup_time_key]
  300 + end
  301 +
  302 + def may_be_a_bot
  303 + # No minimum signup delay, no bot test.
  304 + return false if environment.min_signup_delay == 0
  305 +
  306 + # answering captcha, may be human!
  307 + return false if params[:recaptcha_response_field]
  308 +
  309 + # never set signup_time, hi wget!
  310 + signup_start_time = get_signup_start_time
  311 + return true if signup_start_time.nil?
  312 +
  313 + # so fast, so bot.
  314 + signup_start_time > ( Time.now - environment.min_signup_delay.seconds )
  315 + end
  316 +
275 317 def check_answer
276 318 unless answer_correct
277 319 @enterprise.block
... ...
app/controllers/public/catalog_controller.rb
... ... @@ -7,7 +7,7 @@ class CatalogController &lt; PublicController
7 7 def index
8 8 @category = params[:level] ? ProductCategory.find(params[:level]) : nil
9 9 @products = @profile.products.from_category(@category).paginate(:order => 'available desc, highlighted desc, name asc', :per_page => 9, :page => params[:page])
10   - @categories = ProductCategory.on_level(params[:level])
  10 + @categories = ProductCategory.on_level(params[:level]).order(:name)
11 11 end
12 12  
13 13 protected
... ...
app/helpers/application_helper.rb
... ... @@ -30,6 +30,12 @@ module ApplicationHelper
30 30  
31 31 include AccountHelper
32 32  
  33 + include BlogHelper
  34 +
  35 + include ContentViewerHelper
  36 +
  37 + include LayoutHelper
  38 +
33 39 def locale
34 40 (@page && !@page.language.blank?) ? @page.language : FastGettext.locale
35 41 end
... ... @@ -352,10 +358,6 @@ module ApplicationHelper
352 358 end
353 359 end
354 360  
355   - def theme_stylesheet_path
356   - theme_path + '/style.css'
357   - end
358   -
359 361 def current_theme
360 362 @current_theme ||=
361 363 begin
... ... @@ -493,23 +495,24 @@ module ApplicationHelper
493 495  
494 496 def profile_cat_icons( profile )
495 497 if profile.class == Enterprise
496   - icons =
497   - profile.product_categories.map{ |c| c.size > 1 ? c[1] : nil }.
498   - compact.uniq.map{ |c|
499   - cat_name = c.gsub( /[-_\s,.;'"]+/, '_' )
500   - cat_icon = "/images/icons-cat/#{cat_name}.png"
501   - if ! File.exists? RAILS_ROOT.to_s() + '/public/' + cat_icon
502   - cat_icon = '/images/icons-cat/undefined.png'
503   - end
504   - content_tag 'span',
505   - content_tag( 'span', c ),
506   - :title => c,
507   - :class => 'product-cat-icon cat_icon_' + cat_name,
508   - :style => "background-image:url(#{cat_icon})"
509   - }.join "\n"
510   - content_tag 'div',
511   - content_tag( 'span', _('Principal Product Categories'), :class => 'header' ) +"\n"+ icons,
512   - :class => 'product-category-icons'
  498 + icons = profile.product_categories.map{ |c| c.size > 1 ? c[1] : nil }.
  499 + compact.uniq.map do |c|
  500 + cat_name = c.gsub( /[-_\s,.;'"]+/, '_' )
  501 + cat_icon = "/images/icons-cat/#{cat_name}.png"
  502 + if ! File.exists? RAILS_ROOT.to_s() + '/public/' + cat_icon
  503 + cat_icon = '/images/icons-cat/undefined.png'
  504 + end
  505 + content_tag('span',
  506 + content_tag( 'span', c ),
  507 + :title => c,
  508 + :class => 'product-cat-icon cat_icon_' + cat_name,
  509 + :style => "background-image:url(#{cat_icon})"
  510 + )
  511 + end.join("\n").html_safe
  512 + content_tag('div',
  513 + content_tag( 'span', _('Principal Product Categories'), :class => 'header' ) +"\n"+ icons,
  514 + :class => 'product-category-icons'
  515 + )
513 516 else
514 517 ''
515 518 end
... ... @@ -633,10 +636,10 @@ module ApplicationHelper
633 636 # FIXME
634 637 ([toplevel] + toplevel.children_for_menu).each do |cat|
635 638 if cat.top_level?
636   - result << '<div class="categorie_box">'
  639 + result << '<div class="categorie_box">'.html_safe
637 640 result << icon_button( :down, _('open'), '#', :onclick => 'open_close_cat(this); return false' )
638 641 result << content_tag('h5', toplevel.name)
639   - result << '<div style="display:none"><ul class="categories">'
  642 + result << '<div style="display:none"><ul class="categories">'.html_safe
640 643 else
641 644 checkbox_id = "#{object_name}_#{cat.full_name.downcase.gsub(/\s+|\//, '_')}"
642 645 result << content_tag('li', labelled_check_box(
... ... @@ -647,7 +650,7 @@ module ApplicationHelper
647 650 :class => ( object.category_ids.include?(cat.id) ? 'cat_checked' : '' ) ) + "\n"
648 651 end
649 652 end
650   - result << '</ul></div></div>'
  653 + result << '</ul></div></div>'.html_safe
651 654 end
652 655  
653 656 content_tag('div', result)
... ... @@ -787,10 +790,10 @@ module ApplicationHelper
787 790 :class => 'lineitem' + (line_item+=1).to_s() ) +"\n"
788 791 if line_item == line_size
789 792 line_item = 0
790   - html += "<br />\n"
  793 + html += "<br />\n".html_safe
791 794 end
792 795 }
793   - html += "<br />\n" if line_size == 0 || ( values.size % line_size ) > 0
  796 + html += "<br />\n".html_safe if line_size == 0 || ( values.size % line_size ) > 0
794 797 column = object.class.columns_hash[method.to_s]
795 798 text =
796 799 ( column ?
... ... @@ -873,14 +876,6 @@ module ApplicationHelper
873 876 content_tag('div', labelled_check_box(_('Public'), 'profile_data[fields_privacy]['+name+']', 'public', profile.public_fields.include?(name)), :class => 'field-privacy-selector')
874 877 end
875 878  
876   - def template_stylesheet_path
877   - if profile.nil?
878   - "/designs/templates/#{environment.layout_template}/stylesheets/style.css"
879   - else
880   - "/designs/templates/#{profile.layout_template}/stylesheets/style.css"
881   - end
882   - end
883   -
884 879 def login_url
885 880 options = Noosfero.url_options.merge({ :controller => 'account', :action => 'login' })
886 881 url_for(options)
... ... @@ -919,18 +914,6 @@ module ApplicationHelper
919 914 end
920 915 end
921 916  
922   - def icon_theme_stylesheet_path
923   - icon_themes = []
924   - theme_icon_themes = theme_option(:icon_theme) || []
925   - for icon_theme in theme_icon_themes do
926   - theme_path = "/designs/icons/#{icon_theme}/style.css"
927   - if File.exists?(File.join(RAILS_ROOT, 'public', theme_path))
928   - icon_themes << theme_path
929   - end
930   - end
931   - icon_themes
932   - end
933   -
934 917 def page_title
935 918 (@page ? @page.title + ' - ' : '') +
936 919 (profile ? profile.short_name + ' - ' : '') +
... ... @@ -942,42 +925,13 @@ module ApplicationHelper
942 925 (@category ? " - #{@category.full_name}" : '')
943 926 end
944 927  
945   - def noosfero_javascript
946   - render :file => 'layouts/_javascript'
947   - end
948   -
949   - def noosfero_stylesheets
950   - [
951   - 'application',
952   - 'search',
953   - 'thickbox',
954   - 'lightbox',
955   - 'colorpicker',
956   - 'colorbox',
957   - pngfix_stylesheet_path,
958   - ] +
959   - tokeninput_stylesheets
960   - end
961   -
962 928 # DEPRECATED. Do not use this·
963 929 def import_controller_stylesheets(options = {})
964 930 stylesheet_import( "controller_"+ @controller.controller_name(), options )
965 931 end
966 932  
967   - def pngfix_stylesheet_path
968   - 'iepngfix/iepngfix.css'
969   - end
970   -
971   - def tokeninput_stylesheets
972   - ['token-input', 'token-input-facebook', 'token-input-mac', 'token-input-facet']
973   - end
974   -
975   - def noosfero_layout_features
976   - render :file => 'shared/noosfero_layout_features'
977   - end
978   -
979 933 def link_to_email(email)
980   - javascript_tag('var array = ' + email.split('@').to_json + '; document.write("<a href=\'mailto:" + array.join("@") + "\'>" + array.join("@") + "</a>")')
  934 + javascript_tag('var array = ' + email.split('@').to_json + '; document.write("<a href=\'mailto:" + array.join("@") + "\'>" + array.join("@") + "</a>")'.html_safe)
981 935 end
982 936  
983 937 def stylesheet(*args)
... ... @@ -987,13 +941,43 @@ module ApplicationHelper
987 941 def article_to_html(article, options = {})
988 942 options.merge!(:page => params[:npage])
989 943 content = article.to_html(options)
990   - content = content.kind_of?(Proc) ? self.instance_eval(&content) : content
  944 + content = content.kind_of?(Proc) ? self.instance_eval(&content).html_safe : content.html_safe
991 945 @plugins && @plugins.each do |plugin|
992 946 content = plugin.parse_content(content)
993 947 end
994 948 content
995 949 end
996 950  
  951 + # Please, use link_to by default!
  952 + # This method was created to work around to inexplicable
  953 + # chain of problems when display_short_format was called
  954 + # from Article model for an ArticleBlock.
  955 + def reference_to_article(text, article, anchor=nil)
  956 + if article.profile.domains.empty?
  957 + href = "/#{article.url[:profile]}/"
  958 + else
  959 + href = "http://#{article.profile.domains.first.name}/"
  960 + end
  961 + href += article.url[:page].join('/')
  962 + href += '#' + anchor if anchor
  963 + content_tag('a', text, :href => href)
  964 + end
  965 +
  966 + def display_short_format(article, options={})
  967 + options[:comments_link] ||= true
  968 + options[:read_more_link] ||= true
  969 + html = content_tag('div',
  970 + article.lead +
  971 + content_tag('div',
  972 + (options[:comments_link] ? link_to_comments(article) : '') +
  973 + (options[:read_more_link] ? reference_to_article( _('Read more'), article) : ''),
  974 + :class => 'read-more'
  975 + ),
  976 + :class => 'short-post'
  977 + )
  978 + html
  979 + end
  980 +
997 981 def colorpicker_field(object_name, method, options = {})
998 982 text_field(object_name, method, options.merge(:class => 'colorpicker_field'))
999 983 end
... ... @@ -1003,7 +987,7 @@ module ApplicationHelper
1003 987 end
1004 988  
1005 989 def ui_icon(icon_class, extra_class = '')
1006   - "<span class='ui-icon #{icon_class} #{extra_class}' style='float:left; margin-right:7px;'></span>"
  990 + "<span class='ui-icon #{icon_class} #{extra_class}' style='float:left; margin-right:7px;'></span>".html_safe
1007 991 end
1008 992  
1009 993 def ui_button(label, url, html_options = {})
... ... @@ -1018,10 +1002,6 @@ module ApplicationHelper
1018 1002 theme_option(:jquery_theme) || 'smoothness_mod'
1019 1003 end
1020 1004  
1021   - def jquery_ui_theme_stylesheet_path
1022   - 'jquery.ui/' + jquery_theme + '/jquery-ui-1.8.2.custom'
1023   - end
1024   -
1025 1005 def ui_error(message)
1026 1006 content_tag('div', ui_icon('ui-icon-alert') + message, :class => 'alert fg-state-error ui-state-error')
1027 1007 end
... ... @@ -1035,13 +1015,13 @@ module ApplicationHelper
1035 1015 end
1036 1016  
1037 1017 def collapsed_item_icon
1038   - "<span class='ui-icon ui-icon-circlesmall-plus' style='float:left;'></span>"
  1018 + "<span class='ui-icon ui-icon-circlesmall-plus' style='float:left;'></span>".html_safe
1039 1019 end
1040 1020 def expanded_item_icon
1041   - "<span class='ui-icon ui-icon-circlesmall-minus' style='float:left;'></span>"
  1021 + "<span class='ui-icon ui-icon-circlesmall-minus' style='float:left;'></span>".html_safe
1042 1022 end
1043 1023 def leaf_item_icon
1044   - "<span class='ui-icon ui-icon-arrow-1-e' style='float:left;'></span>"
  1024 + "<span class='ui-icon ui-icon-arrow-1-e' style='float:left;'></span>".html_safe
1045 1025 end
1046 1026  
1047 1027 def display_category_menu(block, categories, root = true)
... ... @@ -1300,9 +1280,7 @@ module ApplicationHelper
1300 1280 titles = tabs.inject(''){ |result, tab| result << content_tag(:li, link_to(tab[:title], '#'+tab[:id]), :class => 'tab') }
1301 1281 contents = tabs.inject(''){ |result, tab| result << content_tag(:div, tab[:content], :id => tab[:id]) }
1302 1282  
1303   - content_tag :div, :class => 'ui-tabs' do
1304   - content_tag(:ul, titles) + contents
1305   - end
  1283 + content_tag(:div, content_tag(:ul, titles) + raw(contents), :class => 'ui-tabs')
1306 1284 end
1307 1285  
1308 1286 def jquery_token_input_messages_json(hintText = _('Type in an keyword'), noResultsText = _('No results'), searchingText = _('Searching...'))
... ... @@ -1331,11 +1309,12 @@ module ApplicationHelper
1331 1309 end
1332 1310  
1333 1311 def template_options(klass, field_name)
1334   - return '' if klass.templates.count == 0
1335   - return hidden_field_tag("#{field_name}[template_id]", klass.templates.first.id) if klass.templates.count == 1
  1312 + templates = klass.templates(environment)
  1313 + return '' if templates.count == 0
  1314 + return hidden_field_tag("#{field_name}[template_id]", templates.first.id) if templates.count == 1
1336 1315  
1337 1316 counter = 0
1338   - radios = klass.templates.map do |template|
  1317 + radios = templates.map do |template|
1339 1318 counter += 1
1340 1319 content_tag('li', labelled_radio_button(link_to(template.name, template.url, :target => '_blank'), "#{field_name}[template_id]", template.id, counter==1))
1341 1320 end.join("\n")
... ... @@ -1423,4 +1402,14 @@ module ApplicationHelper
1423 1402 @no_design_blocks = true
1424 1403 end
1425 1404  
  1405 + def default_folder_for_image_upload(profile)
  1406 + default_folder = profile.folders.find_by_type('Gallery')
  1407 + default_folder = profile.folders.find_by_type('Folder') if default_folder.nil?
  1408 + default_folder
  1409 + end
  1410 +
  1411 + def content_id_to_str(content)
  1412 + content.nil? ? '' : content.id.to_s
  1413 + end
  1414 +
1426 1415 end
... ...
app/helpers/block_helper.rb
... ... @@ -3,7 +3,7 @@ module BlockHelper
3 3 def block_title(title)
4 4 tag_class = 'block-title'
5 5 tag_class += ' empty' if title.empty?
6   - content_tag 'h3', content_tag('span', title), :class => tag_class
  6 + content_tag 'h3', content_tag('span', h(title)), :class => tag_class
7 7 end
8 8  
9 9 end
... ...
app/helpers/blog_helper.rb
... ... @@ -18,8 +18,9 @@ module BlogHelper
18 18 pagination = will_paginate(articles, {
19 19 :param_name => 'npage',
20 20 :previous_label => _('&laquo; Newer posts'),
21   - :next_label => _('Older posts &raquo;')
22   - })
  21 + :next_label => _('Older posts &raquo;'),
  22 + :params => {:action=>"view_page", :page=>articles.first.parent.path.split('/'), :controller=>"content_viewer"}
  23 + }) if articles.present?
23 24 content = []
24 25 artic_len = articles.length
25 26 articles.each_with_index{ |art,i|
... ... @@ -46,18 +47,6 @@ module BlogHelper
46 47 article_title(article, :no_comments => no_comments) + html
47 48 end
48 49  
49   - def display_short_format(article)
50   - html = content_tag('div',
51   - article.lead +
52   - content_tag('div',
53   - link_to_comments(article) +
54   - link_to( _('Read more'), article.url),
55   - :class => 'read-more'),
56   - :class => 'short-post'
57   - )
58   - html
59   - end
60   -
61 50 def display_full_format(article)
62 51 html = article_to_html(article)
63 52 html = content_tag('p', html) if ! html.include?('</p>')
... ...
app/helpers/catalog_helper.rb
... ... @@ -21,7 +21,7 @@ module CatalogHelper
21 21  
22 22 def category_sub_links(category)
23 23 sub_categories = []
24   - category.children.each do |sub_category|
  24 + category.children.order(:name).each do |sub_category|
25 25 sub_categories << category_link(sub_category, true)
26 26 end
27 27 content_tag('ul', sub_categories) if sub_categories.size > 1
... ...
app/helpers/content_viewer_helper.rb
... ... @@ -36,7 +36,7 @@ module ContentViewerHelper
36 36  
37 37 def link_to_comments(article, args = {})
38 38 return '' unless article.accept_comments?
39   - link_to(number_of_comments(article), article.url.merge(:anchor => 'comments_list') )
  39 + reference_to_article number_of_comments(article), article, 'comments_list'
40 40 end
41 41  
42 42 def article_translations(article)
... ... @@ -45,7 +45,7 @@ module ContentViewerHelper
45 45 { article.environment.locales[translation.language] => { :href => url_for(translation.url) } }
46 46 end
47 47 content_tag(:div, link_to(_('Translations'), '#',
48   - :onclick => "toggleSubmenu(this, '#{_('Translations')}', #{links.to_json}); return false",
  48 + :onmouseover => "toggleSubmenu(this, '#{_('Translations')}', #{links.to_json}); return false",
49 49 :class => 'article-translations-menu simplemenu-trigger up'),
50 50 :class => 'article-translations')
51 51 end
... ...
app/helpers/dates_helper.rb
... ... @@ -23,11 +23,13 @@ module DatesHelper
23 23 end
24 24  
25 25 # formats a date for displaying.
26   - def show_date(date, use_numbers = false)
  26 + def show_date(date, use_numbers = false, year=true)
27 27 if date && use_numbers
28   - _('%{month}/%{day}/%{year}') % { :day => date.day, :month => date.month, :year => date.year }
  28 + date_format = year ? _('%{month}/%{day}/%{year}') : _('%{month}/%{day}')
  29 + date_format % { :day => date.day, :month => date.month, :year => date.year }
29 30 elsif date
30   - _('%{month} %{day}, %{year}') % { :day => date.day, :month => month_name(date.month), :year => date.year }
  31 + date_format = year ? _('%{month_name} %{day}, %{year}') : _('%{month_name} %{day}')
  32 + date_format % { :day => date.day, :month_name => month_name(date.month), :year => date.year }
31 33 else
32 34 ''
33 35 end
... ... @@ -46,7 +48,27 @@ module DatesHelper
46 48 if (date1 == date2) || (date2.nil?)
47 49 show_date(date1, use_numbers)
48 50 else
49   - _('from %{date1} to %{date2}') % {:date1 => show_date(date1, use_numbers), :date2 => show_date(date2, use_numbers)}
  51 + if date1.year == date2.year
  52 + if date1.month == date2.month
  53 + _('from %{month} %{day1} to %{day2}, %{year}') % {
  54 + :day1 => date1.day,
  55 + :day2 => date2.day,
  56 + :month => use_numbers ? date1.month : month_name(date1.month),
  57 + :year => date1.year
  58 + }
  59 + else
  60 + _('from %{date1} to %{date2}, %{year}') % {
  61 + :date1 => show_date(date1, use_numbers, false),
  62 + :date2 => show_date(date2, use_numbers, false),
  63 + :year => date1.year
  64 + }
  65 + end
  66 + else
  67 + _('from %{date1} to %{date2}') % {
  68 + :date1 => show_date(date1, use_numbers),
  69 + :date2 => show_date(date2, use_numbers)
  70 + }
  71 + end
50 72 end
51 73 end
52 74  
... ...
app/helpers/forms_helper.rb
... ... @@ -142,38 +142,6 @@ module FormsHelper
142 142 content_tag('table',rows.join("\n"))
143 143 end
144 144  
145   - def select_folder(label_text, field_id, collection, default_value=nil, html_options = {}, js_options = {})
146   - root = profile ? profile.identifier : _("root")
147   - labelled_form_field(
148   - label_text,
149   - select_tag(
150   - field_id,
151   - options_for_select(
152   - [[root, '']] +
153   - collection.collect {|f| [ root + '/' + f.full_name, f.id ] },
154   - default_value
155   - ),
156   - html_options.merge(js_options)
157   - )
158   - )
159   - end
160   -
161   - def select_profile_folder(label_text, field_id, profile, default_value='', html_options = {}, js_options = {})
162   - result = labelled_form_field(
163   - label_text,
164   - select_tag(
165   - field_id,
166   - options_for_select(
167   - [[profile.identifier, '']] +
168   - profile.folders.collect {|f| [ profile.identifier + '/' + f.full_name, f.id ] },
169   - default_value
170   - ),
171   - html_options.merge(js_options)
172   - )
173   - )
174   - return result
175   - end
176   -
177 145 def date_field(name, value, format = '%Y-%m-%d', datepicker_options = {}, html_options = {})
178 146 datepicker_options[:disabled] ||= false
179 147 datepicker_options[:alt_field] ||= ''
... ... @@ -295,23 +263,28 @@ module FormsHelper
295 263 field_id,
296 264 options_for_select(
297 265 [[root, '']] +
298   - collection.collect {|f| [ root + '/' + f.full_name, f.id ] },
299   - default_value
  266 + collection.collect {|f| [ root + '/' + f.full_name, f.id.to_s ] },
  267 + default_value.to_s
300 268 ),
301 269 html_options.merge(js_options)
302 270 )
303 271 )
304 272 end
305 273  
306   - def select_profile_folder(label_text, field_id, profile, default_value='', html_options = {}, js_options = {})
  274 + def select_profile_folder(label_text, field_id, profile, default_value='', html_options = {}, js_options = {}, find_options = {})
  275 + if find_options.empty?
  276 + folders = profile.folders
  277 + else
  278 + folders = profile.folders.where(find_options)
  279 + end
307 280 result = labelled_form_field(
308 281 label_text,
309 282 select_tag(
310 283 field_id,
311 284 options_for_select(
312 285 [[profile.identifier, '']] +
313   - profile.folders.collect {|f| [ profile.identifier + '/' + f.full_name, f.id ] },
314   - default_value
  286 + folders.collect {|f| [ profile.identifier + '/' + f.full_name, f.id.to_s ] },
  287 + default_value.to_s
315 288 ),
316 289 html_options.merge(js_options)
317 290 )
... ...
app/helpers/layout_helper.rb 0 → 100644
... ... @@ -0,0 +1,88 @@
  1 +module LayoutHelper
  2 +
  3 + def body_classes
  4 + # Identify the current controller and action for the CSS:
  5 + " controller-#{@controller.controller_name}" +
  6 + " action-#{@controller.controller_name}-#{@controller.action_name}" +
  7 + " template-#{profile.nil? ? "default" : profile.layout_template}" +
  8 + (!profile.nil? && profile.is_on_homepage?(request.path,@page) ? " profile-homepage" : "")
  9 + end
  10 +
  11 + def noosfero_javascript
  12 + plugins_javascripts = @plugins.map { |plugin| plugin.js_files.map { |js| plugin.class.public_path(js) } }.flatten
  13 +
  14 + output = ''
  15 + output += render :file => 'layouts/_javascript'
  16 + output += javascript_tag 'render_all_jquery_ui_widgets()'
  17 + unless plugins_javascripts.empty?
  18 + output += javascript_include_tag plugins_javascripts, :cache => "cache/plugins-#{Digest::MD5.hexdigest plugins_javascripts.to_s}"
  19 + end
  20 + output
  21 + end
  22 +
  23 + def noosfero_stylesheets
  24 + standard_stylesheets = [
  25 + 'application',
  26 + 'search',
  27 + 'thickbox',
  28 + 'lightbox',
  29 + 'colorpicker',
  30 + 'colorbox',
  31 + pngfix_stylesheet_path,
  32 + ] + tokeninput_stylesheets
  33 + plugins_stylesheets = @plugins.select(&:stylesheet?).map { |plugin| plugin.class.public_path('style.css') }
  34 +
  35 + output = ''
  36 + output += stylesheet_link_tag standard_stylesheets, :cache => 'cache'
  37 + output += stylesheet_link_tag template_stylesheet_path
  38 + output += stylesheet_link_tag icon_theme_stylesheet_path
  39 + output += stylesheet_link_tag jquery_ui_theme_stylesheet_path
  40 + unless plugins_stylesheets.empty?
  41 + output += stylesheet_link_tag plugins_stylesheets, :cache => "cache/plugins-#{Digest::MD5.hexdigest plugins_stylesheets.to_s}"
  42 + end
  43 + output += stylesheet_link_tag theme_stylesheet_path
  44 + output
  45 + end
  46 +
  47 + def pngfix_stylesheet_path
  48 + 'iepngfix/iepngfix.css'
  49 + end
  50 +
  51 + def tokeninput_stylesheets
  52 + ['token-input', 'token-input-facebook', 'token-input-mac', 'token-input-facet']
  53 + end
  54 +
  55 + def noosfero_layout_features
  56 + render :file => 'shared/noosfero_layout_features'
  57 + end
  58 +
  59 + def template_stylesheet_path
  60 + if profile.nil?
  61 + "/designs/templates/#{environment.layout_template}/stylesheets/style.css"
  62 + else
  63 + "/designs/templates/#{profile.layout_template}/stylesheets/style.css"
  64 + end
  65 + end
  66 +
  67 + def icon_theme_stylesheet_path
  68 + icon_themes = []
  69 + theme_icon_themes = theme_option(:icon_theme) || []
  70 + for icon_theme in theme_icon_themes do
  71 + theme_path = "/designs/icons/#{icon_theme}/style.css"
  72 + if File.exists?(File.join(RAILS_ROOT, 'public', theme_path))
  73 + icon_themes << theme_path
  74 + end
  75 + end
  76 + icon_themes
  77 + end
  78 +
  79 + def jquery_ui_theme_stylesheet_path
  80 + 'jquery.ui/' + jquery_theme + '/jquery-ui-1.8.2.custom'
  81 + end
  82 +
  83 + def theme_stylesheet_path
  84 + theme_path + '/style.css'
  85 + end
  86 +
  87 +end
  88 +
... ...
app/helpers/profile_editor_helper.rb
... ... @@ -136,7 +136,7 @@ module ProfileEditorHelper
136 136 concat(
137 137 content_tag(
138 138 'div',
139   - capture(&block) + '<br style="clear:left;"/>&nbsp;',
  139 + capture(&block) + content_tag('br', '', :style => 'clear: left'),
140 140 :class => 'control-panel')
141 141 )
142 142 end
... ...
app/helpers/tags_helper.rb
... ... @@ -68,7 +68,7 @@ module TagsHelper
68 68 :title => n_( 'one item', '%d items', count ) % count
69 69 end
70 70  
71   - end.join("\n")
  71 + end.join("\n").html_safe
72 72 end
73 73  
74 74 end
... ...
app/models/article.rb
... ... @@ -2,6 +2,9 @@ require &#39;hpricot&#39;
2 2  
3 3 class Article < ActiveRecord::Base
4 4  
  5 + #FIXME This is necessary because html is being generated on the model...
  6 + include ActionView::Helpers::TagHelper
  7 +
5 8 # use for internationalizable human type names in search facets
6 9 # reimplement on subclasses
7 10 def self.type_name
... ... @@ -236,8 +239,13 @@ class Article &lt; ActiveRecord::Base
236 239 # The implementation in this class just provides the +body+ attribute as the
237 240 # HTML. Other article types can override this method to provide customized
238 241 # views of themselves.
  242 + # (To override short format representation, override the lead method)
239 243 def to_html(options = {})
240   - body || ''
  244 + if options[:format] == 'short'
  245 + display_short_format(self)
  246 + else
  247 + body || ''
  248 + end
241 249 end
242 250  
243 251 include ApplicationHelper
... ...
app/models/article_block.rb
... ... @@ -12,7 +12,11 @@ class ArticleBlock &lt; Block
12 12 block = self
13 13 lambda do
14 14 block_title(block.title) +
15   - (block.article ? article_to_html(block.article, :gallery_view => false) : _('Article not selected yet.'))
  15 + (block.article ? article_to_html(block.article,
  16 + :gallery_view => false,
  17 + :inside_block => block, # For Blogs and folders
  18 + :format => block.visualization_format # For Articles and contents
  19 + ).html_safe : _('Article not selected yet.'))
16 20 end
17 21 end
18 22  
... ... @@ -49,4 +53,14 @@ class ArticleBlock &lt; Block
49 53 self.box.owner.kind_of?(Environment) ? self.box.owner.portal_community.articles : self.box.owner.articles
50 54 end
51 55  
  56 + def posts_per_page
  57 + self.settings[:posts_per_page] or 1
  58 + end
  59 +
  60 + def posts_per_page= value
  61 + value = value.to_i
  62 + self.settings[:posts_per_page] = value if value > 0
  63 + end
  64 +
  65 + settings_items :visualization_format, :type => :string, :default => 'short'
52 66 end
... ...
app/models/blog.rb
... ... @@ -24,8 +24,9 @@ class Blog &lt; Folder
24 24 # FIXME isn't this too much including just to be able to generate some HTML?
25 25 include ActionView::Helpers::TagHelper
26 26 def to_html(options = {})
  27 + me = self
27 28 lambda do
28   - render :file => 'content_viewer/blog_page'
  29 + render :file => 'content_viewer/blog_page', :locals => { :blog=>me, :inside_block=>options[:inside_block] }
29 30 end
30 31 end
31 32  
... ...
app/models/environment.rb
... ... @@ -233,6 +233,7 @@ class Environment &lt; ActiveRecord::Base
233 233 settings[:message_for_member_invitation] || InviteMember.mail_template
234 234 end
235 235  
  236 + settings_items :min_signup_delay, :type => Integer, :default => 3 #seconds
236 237 settings_items :activation_blocked_text, :type => String
237 238 settings_items :message_for_disabled_enterprise, :type => String,
238 239 :default => _('This enterprise needs to be enabled.')
... ... @@ -617,12 +618,10 @@ class Environment &lt; ActiveRecord::Base
617 618 end
618 619  
619 620 def top_url
620   - protocol = 'http'
621   - result = "#{protocol}://#{default_hostname}"
622   - if Noosfero.url_options.has_key?(:port)
623   - result << ':' << Noosfero.url_options[:port].to_s
624   - end
625   - result
  621 + url = 'http://'
  622 + url << (Noosfero.url_options.key?(:host) ? Noosfero.url_options[:host] : default_hostname)
  623 + url << ':' << Noosfero.url_options[:port].to_s if Noosfero.url_options.key?(:port)
  624 + url
626 625 end
627 626  
628 627 def to_s
... ...
app/models/event.rb
... ... @@ -104,18 +104,30 @@ class Event &lt; Article
104 104 }
105 105 }
106 106  
  107 + # TODO: some good soul, please clean this ugly hack:
107 108 if self.body
108 109 html.div('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', :class => 'event-description')
109 110 end
110 111 }
111 112  
112 113 if self.body
113   - result.sub!('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', self.body)
  114 + if options[:format] == 'short'
  115 + result.sub!('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', display_short_format(self))
  116 + else
  117 + result.sub!('_____XXXX_DESCRIPTION_GOES_HERE_XXXX_____', self.body)
  118 + end
114 119 end
115 120  
116 121 result
117 122 end
118 123  
  124 + def lead
  125 + content_tag('div',
  126 + show_period(start_date, end_date),
  127 + :class => 'event-dates'
  128 + ) + super
  129 + end
  130 +
119 131 def event?
120 132 true
121 133 end
... ...
app/models/feed_reader_block.rb
... ... @@ -47,11 +47,11 @@ class FeedReaderBlock &lt; Block
47 47  
48 48 def formatted_feed_content
49 49 if error_message.blank?
50   - "<ul>\n" +
51   - self.feed_items[0..(limit-1)].map{ |item| "<li><a href='#{item[:link]}'>#{item[:title]}</a></li>" }.join("\n") +
52   - "</ul>"
  50 + "<ul>\n".html_safe +
  51 + self.feed_items[0..(limit-1)].map{ |item| "<li><a href='#{item[:link]}'>#{item[:title]}</a></li>" }.join("\n").html_safe +
  52 + "</ul>".html_safe
53 53 else
54   - '<p>' + error_message + '</p>'
  54 + "<p>#{error_message}</p>".html_safe
55 55 end
56 56 end
57 57  
... ...
app/models/link_list_block.rb
... ... @@ -80,7 +80,7 @@ class LinkListBlock &lt; Block
80 80  
81 81 def icons_options
82 82 ICONS.map do |i|
83   - "<span title=\"#{i[1]}\" class=\"icon-#{i[0]}\" onclick=\"changeIcon(this, '#{i[0]}')\"></span>"
  83 + "<span title=\"#{i[1]}\" class=\"icon-#{i[0]}\" onclick=\"changeIcon(this, '#{i[0]}')\"></span>".html_safe
84 84 end
85 85 end
86 86  
... ...
app/models/organization_mailing.rb
... ... @@ -5,7 +5,7 @@ class OrganizationMailing &lt; Mailing
5 5 end
6 6  
7 7 def recipients(offset=0, limit=100)
8   - source.members.all(:order => self.id, :offset => offset, :limit => limit, :joins => "LEFT OUTER JOIN mailing_sents m ON (m.mailing_id = #{id} AND m.person_id = profiles.id)", :conditions => { "m.person_id" => nil })
  8 + source.members.all(:order => :id, :offset => offset, :limit => limit, :joins => "LEFT OUTER JOIN mailing_sents m ON (m.mailing_id = #{id} AND m.person_id = profiles.id)", :conditions => { "m.person_id" => nil })
9 9 end
10 10  
11 11 def each_recipient
... ...
app/models/profile.rb
... ... @@ -68,7 +68,7 @@ class Profile &lt; ActiveRecord::Base
68 68 #FIXME: these will work only if the subclass is already loaded
69 69 named_scope :enterprises, lambda { {:conditions => (Enterprise.send(:subclasses).map(&:name) << 'Enterprise').map { |klass| "profiles.type = '#{klass}'"}.join(" OR ")} }
70 70 named_scope :communities, lambda { {:conditions => (Community.send(:subclasses).map(&:name) << 'Community').map { |klass| "profiles.type = '#{klass}'"}.join(" OR ")} }
71   - named_scope :templates, :conditions => {:is_template => true}
  71 + named_scope :templates, lambda { |environment| { :conditions => {:is_template => true, :environment_id => environment.id} } }
72 72  
73 73 def members
74 74 scopes = plugins.dispatch_scopes(:organization_members, self)
... ...
app/models/profile_list_block.rb
... ... @@ -49,13 +49,12 @@ class ProfileListBlock &lt; Block
49 49 send(:profile_image_link, item, :minor )
50 50 }.join("\n ")
51 51 if list.empty?
52   - list = '<div class="common-profile-list-block-none">'+ _('None') +'</div>'
  52 + list = content_tag 'div', _('None'), :class => 'common-profile-list-block-none'
53 53 else
54 54 list = content_tag 'ul', nl +' '+ list + nl
55 55 end
56 56 block_title(title) + nl +
57   - '<div class="common-profile-list-block">' +
58   - nl + list + nl + '<br style="clear:both" /></div>'
  57 + content_tag('div', nl + list + nl + content_tag('br', '', :style => 'clear:both'))
59 58 end
60 59 end
61 60  
... ...
app/models/spammer_logger.rb
... ... @@ -5,10 +5,10 @@ class SpammerLogger &lt; Logger
5 5 def self.log(spammer_ip, object=nil)
6 6 if object
7 7 if object.kind_of?(Comment)
8   - @logger << "[#{Time.now.strftime("%F %T %z")}] Comment-id: #{object.id} IP: #{spammer_ip}\n"
  8 + @logger << "[#{Time.now.strftime('%F %T %z')}] Comment-id: #{object.id} IP: #{spammer_ip}\n"
9 9 end
10 10 else
11   - @logger << "[#{Time.now.strftime("%F %T %z")}] IP: #{spammer_ip}\n"
  11 + @logger << "[#{Time.now.strftime('%F %T %z')}] IP: #{spammer_ip}\n"
12 12 end
13 13 end
14 14  
... ...
app/models/tags_block.rb
... ... @@ -20,7 +20,8 @@ class TagsBlock &lt; Block
20 20 end
21 21  
22 22 def content(args={})
23   - tags = owner.article_tags
  23 + is_env = owner.class == Environment
  24 + tags = is_env ? owner.tag_counts : owner.article_tags
24 25 return '' if tags.empty?
25 26  
26 27 if limit
... ... @@ -29,18 +30,28 @@ class TagsBlock &lt; Block
29 30 tags_tmp.map{ |k,v| tags[k] = v }
30 31 end
31 32  
  33 + url = is_env ? {:host=>owner.default_hostname, :controller=>'search', :action => 'tag'} :
  34 + owner.public_profile_url.merge(:controller => 'profile', :action => 'tags')
  35 + tagname_option = is_env ? :tag : :id
  36 +
32 37 block_title(title) +
33   - "\n<div class='tag_cloud'>\n"+
34   - tag_cloud( tags, :id,
35   - owner.public_profile_url.merge(:controller => 'profile', :action => 'tags'),
36   - :max_size => 16, :min_size => 9 ) +
37   - "\n</div><!-- end class='tag_cloud' -->\n";
  38 + "\n<div class='tag_cloud'>\n".html_safe+
  39 + tag_cloud( tags, tagname_option, url, :max_size => 16, :min_size => 9 ) +
  40 + "\n</div><!-- end class='tag_cloud' -->\n".html_safe
38 41 end
39 42  
40 43 def footer
41   - owner_id = owner.identifier
42   - lambda do
43   - link_to s_('tags|View all'), :profile => owner_id, :controller => 'profile', :action => 'tags'
  44 + if owner.class == Environment
  45 + lambda do
  46 + link_to s_('tags|View all'),
  47 + :controller => 'search', :action => 'tags'
  48 + end
  49 + else
  50 + owner_id = owner.identifier
  51 + lambda do
  52 + link_to s_('tags|View all'),
  53 + :profile => owner_id, :controller => 'profile', :action => 'tags'
  54 + end
44 55 end
45 56 end
46 57  
... ...
app/models/uploaded_file.rb
... ... @@ -113,7 +113,7 @@ class UploadedFile &lt; Article
113 113  
114 114 content_tag(
115 115 'div',
116   - link_to_previous + content_tag('span', _('image %d of %d'), :class => 'total-of-images') % [current_index + 1, total_of_images] + link_to_next,
  116 + link_to_previous + (content_tag('span', _('image %d of %d'), :class => 'total-of-images') % [current_index + 1, total_of_images]).html_safe + link_to_next,
117 117 :class => 'gallery-navigation'
118 118 )
119 119 end.to_s +
... ...
app/models/user.rb
... ... @@ -15,7 +15,7 @@ class User &lt; ActiveRecord::Base
15 15 # FIXME ugly workaround
16 16 def self.human_attribute_name(attrib)
17 17 case attrib.to_sym
18   - when :login: return _('Username')
  18 + when :login: return [_('Username'), _('Email')].join(' / ')
19 19 when :email: return _('e-Mail')
20 20 else _(self.superclass.human_attribute_name(attrib))
21 21 end
... ... @@ -116,10 +116,11 @@ class User &lt; ActiveRecord::Base
116 116  
117 117 validates_inclusion_of :terms_accepted, :in => [ '1' ], :if => lambda { |u| ! u.terms_of_use.blank? }, :message => N_('%{fn} must be checked in order to signup.').fix_i18n
118 118  
119   - # Authenticates a user by their login name and unencrypted password. Returns the user or nil.
  119 + # Authenticates a user by their login name or email and unencrypted password. Returns the user or nil.
120 120 def self.authenticate(login, password, environment = nil)
121 121 environment ||= Environment.default
122   - u = first :conditions => ['login = ? AND environment_id = ? AND activated_at IS NOT NULL', login, environment.id] # need to get the salt
  122 + u = self.first :conditions => ['(login = ? OR email = ?) AND environment_id = ? AND activated_at IS NOT NULL',
  123 + login, login, environment.id] # need to get the salt
123 124 u && u.authenticated?(password) ? u : nil
124 125 end
125 126  
... ...
app/views/account/_signup_form.rhtml
  1 +<% if @block_bot %>
  2 + <div class="atention" style="font-size: 150%;">
  3 + <strong><%=_('Are you a robot?')%></strong> <br />
  4 + <%=_('Please, prove that you are human by filling the captcha.')%>
  5 + </div>
  6 +<% end %>
  7 +
1 8 <% @profile_data = @person %>
2 9  
3 10 <%= error_messages_for :user, :person, :header_message => _('The account could not be created') %>
4 11  
5   -<% labelled_form_for :user, @user, :html => { :multipart => true, :id => 'signup-form' } do |f| %>
  12 +<% labelled_form_for :user, @user, :html => { :multipart => true, :id => 'signup-form', :honeypot => true } do |f| %>
  13 +
  14 +<input type="hidden" id="signup_time_key" name="signup_time_key" />
  15 +<script type="text/javascript">
  16 + jQuery.ajax({
  17 + type: "POST",
  18 + url: "<%= url_for :controller=>'account', :action=>'signup_time' %>",
  19 + dataType: 'json',
  20 + success: function(data) {
  21 + if (data.ok) jQuery('#signup_time_key').val(data.key);
  22 + }
  23 + });
  24 +</script>
6 25  
7 26 <%= hidden_field_tag :invitation_code, @invitation_code %>
8 27  
... ... @@ -13,7 +32,8 @@
13 32 <span id="signup-domain"><%= environment.default_hostname %>/</span>
14 33 <div id='signup-login'>
15 34 <div id='signup-login-field' class='formfield'>
16   - <%= required text_field(:user, :login, :id => 'user_login', :onchange => 'this.value = convToValidLogin(this.value);') %>
  35 + <%= required text_field(:user, :login, :id => 'user_login',
  36 + :onchange => 'this.value = convToValidUsername(this.value);') %>
17 37 <div id='url-check'><p>&nbsp;</p></div>
18 38 </div>
19 39 <%= content_tag(:small, _('Choose your login name carefully! It will be your network access and you will not be able to change it later.'), :id => 'signup-balloon') %>
... ... @@ -97,6 +117,8 @@
97 117 <% end %>
98 118 </div>
99 119  
  120 +<%= recaptcha_tags :ajax => true, :display => {:theme => 'clean'} if @block_bot %>
  121 +
100 122 <p style="text-align: center">
101 123 <%= submit_button('save', _('Create my account')) %>
102 124 </p>
... ...
app/views/account/forgot_password.rhtml
... ... @@ -5,7 +5,7 @@
5 5 <% labelled_form_for :change_password, @change_password, :url => { :action => 'forgot_password' } do |f| %>
6 6  
7 7 <%= f.text_field :login,
8   - :onchange => 'this.value = convToValidLogin( this.value )' %>
  8 + :onchange => 'this.value = convToValidUsername( this.value )' %>
9 9  
10 10 <%= f.text_field :email %>
11 11  
... ...
app/views/admin_panel/site_info.rhtml
... ... @@ -4,7 +4,7 @@
4 4  
5 5 <%= render :file => 'shared/tiny_mce' %>
6 6  
7   -<% labelled_form_for :environment, @environment, :url => {:host => @environment.default_hostname, :port => request.port} do |f| %>
  7 +<% labelled_form_for :environment, @environment do |f| %>
8 8 <% tabs = [] %>
9 9 <% tabs << {:title => _('Site info'), :id => 'site-info',
10 10 :content => (render :partial => 'site_info', :locals => {:f => f})} %>
... ...
app/views/box_organizer/_article_block.rhtml
1   -<div class='article-block-edition'>
  1 +<div class="article-block-edition">
2 2 <% if @block.box.owner.kind_of?(Environment) and @block.box.owner.portal_community.nil? %>
3   - <p id='no_portal_community'>
  3 + <p id="no_portal_community">
4 4 <%= _("You don't have an community defined as the portal community. Define it before use this block properly.") %>
5 5 </p>
6 6 <% else %>
7   - <% articles = @block.available_articles.select {|article| !article.folder? } %>
8   - <%= select_tag('block[article_id]', options_for_select_with_title(articles.map {|item| [item.path, item.id]}, @block.article ? @block.article.id : nil)) %>
  7 + <%
  8 + articles = @block.available_articles.select {|a| !a.folder? || a.blog? }
  9 + first_text = articles[articles.find_index{|a| a.kind_of? TextArticle}||-1]
  10 + selected = @block.article || first_text
  11 + %>
  12 + <%= select_tag(
  13 + 'block[article_id]',
  14 + options_for_select_with_title(articles.map {|item| [item.path, item.id]}, selected.id),
  15 + :onchange => 'this.changedTo(this.value)'
  16 + )%>
  17 + <div id="block_blog_options" style="display:none">
  18 + <%= labelled_form_field(
  19 + _('Number of posts:'),
  20 + text_field_tag('block[posts_per_page]', @block.posts_per_page)
  21 + )%>
  22 + </div>
  23 + <%= labelled_form_field(
  24 + _('How to display this content:'),
  25 + select_tag(
  26 + 'block[visualization_format]',
  27 + options_for_select([[_('Lead'), 'short'], [_('Full post'), 'full']], @block.visualization_format)
  28 + )
  29 + )%>
  30 + <% blogs = @block.available_articles.select{|a|a.blog?} %>
  31 + <script>
  32 + var select = jQuery("#block_article_id")[0];
  33 + select.blogs = <%= blogs.map{|b| b.id.to_s }.to_json %>;
  34 + select.changedTo = function(articleId) {
  35 + var blogSelected = this.blogs.indexOf(articleId) != -1;
  36 + jQuery("#block_blog_options").toggle(blogSelected);
  37 + }
  38 + select.changedTo('<%= selected.id %>');
  39 + </script>
9 40 <% end %>
10 41 </div>
... ...
app/views/box_organizer/_highlights_block.rhtml
... ... @@ -5,7 +5,7 @@
5 5 <% for image in @block.images do %>
6 6 <tr>
7 7 <td>
8   - <%= select_tag 'block[images][][image_id]', content_tag(:option) + option_groups_from_collection_for_select(@block.folder_choices, :images, :name, :id, :name, image[:image_id].to_i), :style => "width: 100px" %></p>
  8 + <%= select_tag 'block[images][][image_id]', content_tag(:option) + option_groups_from_collection_for_select(@block.folder_choices, :images, :name, :id, :name, image[:image_id].to_i).html_safe, :style => "width: 100px" %></p>
9 9 </td>
10 10 <td><%= text_field_tag 'block[images][][address]', image[:address], :class => 'highlight-address', :size => 10 %></td>
11 11 <td><%= text_field_tag 'block[images][][position]', image[:position], :class => 'highlight-position', :size => 3 %></td>
... ... @@ -17,7 +17,7 @@
17 17  
18 18 <%= link_to_function(_('New highlight'), nil, :class => 'button icon-add with-text') do |page|
19 19 page.insert_html :bottom, 'highlights', content_tag('tr',
20   - content_tag('td', select_tag('block[images][][image_id]', content_tag(:option) + option_groups_from_collection_for_select(@block.folder_choices, :images, :name, :id, :name), :style => "width: 100px")) +
  20 + content_tag('td', select_tag('block[images][][image_id]', content_tag(:option) + option_groups_from_collection_for_select(@block.folder_choices, :images, :name, :id, :name).html_safe, :style => "width: 100px")) +
21 21 content_tag('td', text_field_tag('block[images][][address]', nil, :class => 'highlight-address', :size => 10)) +
22 22 content_tag('td', text_field_tag('block[images][][position]', nil, :class => 'highlight-position', :size => 3)) +
23 23 content_tag('td', text_field_tag('block[images][][title]', nil, :class => 'highlight-position', :size => 10))
... ...
app/views/catalog/index.rhtml
... ... @@ -7,13 +7,16 @@
7 7  
8 8 <div class='l-sidebar-left-bar'>
9 9 <ul>
10   - <% if @categories.size > 0 %>
  10 + <%= content_tag('li', link_to(_('Enterprise homepage'), profile.public_profile_url), :id => 'catalog-categories-homepage-link') %>
  11 + <% if @categories.present? %>
11 12 <% @categories.each do |category| %>
12 13 <%= category_link(category) %>
13 14 <%= category_sub_links(category) %>
14 15 <% end %>
  16 + <% elsif @category.present? %>
  17 + <%= content_tag('li', _('There are no sub-categories for %s') % @category.name, :id => 'catalog-categories-notice') %>
15 18 <% else %>
16   - <%= content_tag('li', _('There are no sub-categories for %s') % @category.name, :style => 'color: #555753; padding-bottom: 0.5em;') %>
  19 + <%= content_tag('li', _('There are no categories available.'), :id => 'catalog-categories-notice') %>
17 20 <% end %>
18 21 </ul>
19 22 </div>
... ...
app/views/cms/_text_editor_sidebar.rhtml
... ... @@ -9,7 +9,12 @@
9 9 <div id='media-upload-form'>
10 10 <% form_tag({ :action => 'media_upload' }, :multipart => true) do %>
11 11 <div class='formfield'>
12   - <%= select_profile_folder(_('Choose folder to upload files:'), :parent_id, profile) %>
  12 + <% default_folder = content_id_to_str default_folder_for_image_upload(profile) %>
  13 + <%= select_profile_folder(
  14 + _('Choose folder to upload files:'),
  15 + :parent_id, profile, default_folder, {}, {},
  16 + 'type="Folder" or type="Gallery"'
  17 + ) %>
13 18 </div>
14 19 <p><%= file_field_tag('file1') %></p>
15 20 <p><%= file_field_tag('file2') %></p>
... ...
app/views/content_viewer/_comment_form.rhtml
... ... @@ -21,8 +21,6 @@ function submit_comment_form(button) {
21 21 }
22 22 </script>
23 23  
24   -<% focus_on = logged_in? ? 'title' : 'name' %>
25   -
26 24 <% if @comment && @comment.errors.any? && @comment.reply_of_id.blank? %>
27 25 <%= error_messages_for :comment %>
28 26 <script type="text/javascript">jQuery(function() { document.location.href = '#page-comment-form'; });</script>
... ... @@ -32,17 +30,7 @@ function submit_comment_form(button) {
32 30  
33 31 <div class="post_comment_box <%= @form_div %>">
34 32  
35   -<% if display_link %>
36   - <h4 onclick="var d = jQuery(this).parent('.post_comment_box');
37   - if (d.hasClass('closed')) {
38   - d.removeClass('closed');
39   - d.addClass('opened');
40   - d.find('input[name=comment[title]], textarea').val('');
41   - d.find('.comment_form input[name=comment[<%= focus_on %>]]').focus();
42   - }">
43   - <%= content_tag('a', '', :name => 'comment_form') + _('Post a comment') %>
44   - </h4>
45   -<% end %>
  33 + <%= link_to(_('Post a comment'), '#', :class => 'display-comment-form') if display_link %>
46 34  
47 35 <% unless pass_without_comment_captcha? %>
48 36 <div id="recaptcha-container" style="display: none">
... ... @@ -62,8 +50,6 @@ function submit_comment_form(button) {
62 50 <% end %>
63 51  
64 52 <% form_tag( url, { :class => 'comment_form' } ) do %>
65   - <%= hidden_field_tag(:confirm, 'false') %>
66   -
67 53 <%= required_fields_message %>
68 54  
69 55 <% unless logged_in? %>
... ... @@ -84,10 +70,13 @@ function submit_comment_form(button) {
84 70 <%= labelled_form_field(_('Title'), text_field(:comment, :title)) %>
85 71 <%= required labelled_form_field(_('Enter your comment'), text_area(:comment, :body, :rows => 5)) %>
86 72  
  73 + <%= hidden_field_tag(:confirm, 'false') %>
  74 + <%= hidden_field_tag(:view, params[:view])%>
  75 +
87 76 <% button_bar do %>
88 77 <%= submit_button('add', _('Post comment'), :onclick => "submit_comment_form(this); return false") %>
89 78 <% if cancel_triggers_hide %>
90   - <%= button_to_function :cancel, _('Cancel'), "f=jQuery(this).parents('.post_comment_box'); f.removeClass('opened'); f.addClass('closed'); return false" %>
  79 + <%= button :cancel, _('Cancel'), '', :id => 'cancel-comment' %>
91 80 <% else %>
92 81 <%= button('cancel', _('Cancel'), {:action => 'view_page', :profile => profile.identifier, :page => @comment.article.explode_path})%>
93 82 <% end %>
... ... @@ -95,3 +84,5 @@ function submit_comment_form(button) {
95 84 <% end %>
96 85  
97 86 </div><!-- end class="post_comment_box" -->
  87 +
  88 +<%= javascript_include_tag 'comment_form'%>
... ...
app/views/content_viewer/blog_page.rhtml
1   -<% add_rss_feed_to_head(@page.name, @page.feed.url) if @page.blog? && @page.feed %>
  1 +<% add_rss_feed_to_head(blog.name, blog.feed.url) if blog.blog? && blog.feed %>
2 2  
3   -<%= content_tag('em', _('(external feed was not loaded yet)'), :id => 'external-feed-info', :class => 'metadata') if @page.blog? && @page.external_feed && @page.external_feed.enabled && @page.external_feed.fetched_at.nil? %>
  3 +<%= content_tag('em', _('(external feed was not loaded yet)'), :id => 'external-feed-info', :class => 'metadata') if blog.blog? && blog.external_feed && blog.external_feed.enabled && blog.external_feed.fetched_at.nil? %>
4 4  
5 5 <div>
6 6 <div class='blog-description'>
7   - <%= @page.body %>
  7 + <%= blog.body %>
8 8 </div>
9 9 </div>
10 10 <hr class="pre-posts"/>
11 11 <div class="blog-posts">
12   - <%= (@page.empty? ? content_tag('em', _('(no posts)')) : list_posts(@posts, @page.visualization_format)) %>
  12 + <%=
  13 + posts = @posts
  14 + format = blog.visualization_format
  15 + if inside_block
  16 + posts = blog.posts.paginate(:page=>1, :per_page=>inside_block.posts_per_page)
  17 + format = inside_block.visualization_format
  18 + end
  19 + (blog.empty? ? content_tag('em', _('(no posts)')) : list_posts(posts, format))
  20 + %>
13 21 </div>
... ...
app/views/content_viewer/view_page.rhtml
... ... @@ -90,7 +90,7 @@
90 90 <% end %>
91 91  
92 92 <% if @page.accept_comments? && @comments_count > 1 %>
93   - <p class="post-comment-button"><a href="#comment_form" onclick="jQuery('#page-comment-form h4').first().trigger('click')"><%= _('Post a comment') %></a></p>
  93 + <%= link_to(_('Post a comment'), '#', :class => 'display-comment-form', :id => 'top-post-comment-button') %>
94 94 <% end %>
95 95  
96 96 <ul class="article-comments-list">
... ...
app/views/favorite_enterprises/index.rhtml
... ... @@ -5,7 +5,7 @@
5 5 <ul class="profile-list">
6 6 <% @favorite_enterprises.each do |enterprise| %>
7 7 <li>
8   - <%= link_to_profile profile_image(enterprise) + '<br/>' + enterprise.name,
  8 + <%= link_to_profile profile_image(enterprise) + '<br/>'.html_safe + enterprise.name,
9 9 enterprise.identifier, :class => 'profile-link' %>
10 10 <%# profile_image_link enterprise, :portrait, 'div' %>
11 11 <div class="controll">
... ...
app/views/layouts/_user.html.erb 0 → 100644
... ... @@ -0,0 +1,24 @@
  1 +<div id="user">
  2 + <span class='logged-in' style='display: none;'>
  3 + <%= usermenu_logged_in %>
  4 + </span>
  5 + <span class='not-logged-in' style='display: none'>
  6 +
  7 + <%= _("<span class='login'>%s</span>") % thickbox_inline_popup_link('<i class="icon-menu-login"></i><strong>' + _('Login') + '</strong>', login_url, 'inlineLoginBox', :id => 'link_login') %>
  8 + <%= @plugins.dispatch(:alternative_authentication_link).collect { |content| instance_eval(&content) }.join("") %>
  9 +
  10 + <div id='inlineLoginBox' style='display: none;'>
  11 + <%= render :file => 'account/login', :locals => { :is_thickbox => true } %>
  12 + </div>
  13 +
  14 + <% unless @plugins.dispatch(:allow_user_registration).include?(false) %>
  15 + <%= _("<span class='or'>or</span> <span class='signup'>%s</span>") % link_to('<strong>' + _('Sign up') + '</strong>', :controller => 'account', :action => 'signup')%>
  16 + <% end %>
  17 +
  18 + </span>
  19 + <form action="/search" id="top-search" class="search_form clean" method="get">
  20 + <input name="query" size="15" title="<%=_('Search...')%>" onfocus="this.form.className='focused';" onblur="this.form.className=''" />
  21 + <div><%=_('Press <strong>Enter</strong> to send the search query.')%></div>
  22 + <%= javascript_tag 'jQuery("#user form input").hint();' %>
  23 + </form>
  24 +</div><!-- end id="user" -->
... ...
app/views/layouts/application-ng.rhtml
... ... @@ -8,38 +8,19 @@
8 8 <meta name="description" content="<%= @environment.name %>" />
9 9 <link rel="shortcut icon" href="<%= image_path(theme_favicon) %>" type="image/x-icon" />
10 10 <%= noosfero_javascript %>
11   - <%= stylesheet_link_tag noosfero_stylesheets, :cache => 'cache' %>
12   - <%= stylesheet_link_tag template_stylesheet_path %>
13   - <%= stylesheet_link_tag icon_theme_stylesheet_path %>
14   - <%= stylesheet_link_tag jquery_ui_theme_stylesheet_path %>
15   - <%
16   - plugins_stylesheets = @plugins.select(&:stylesheet?).map { |plugin| plugin.class.public_path('style.css') }
17   - %>
18   - <%= stylesheet_link_tag(plugins_stylesheets, :cache => 'cache/plugins-' + Digest::MD5.hexdigest(plugins_stylesheets.to_s)) unless plugins_stylesheets.empty? %>
19   - <%= stylesheet_link_tag theme_stylesheet_path %>
  11 + <%= noosfero_stylesheets %>
20 12  
21 13 <%# Add custom tags/styles/etc via content_for %>
22 14 <%= yield :head %>
23   - <%= javascript_tag('render_all_jquery_ui_widgets()') %>
24   - <%
25   - plugins_javascripts = @plugins.map { |plugin| plugin.js_files.map { |js| plugin.class.public_path(js) } }.flatten
26   - %>
27   - <%= javascript_include_tag(plugins_javascripts, :cache => 'cache/plugins-' + Digest::MD5.hexdigest(plugins_javascripts.to_s)) unless plugins_javascripts.empty? %>
28 15 <%=
29 16 @plugins.dispatch(:head_ending).collect do |content|
30 17 content.respond_to?(:call) ? content.call : content
31 18 end.join("\n")
32 19 %>
33 20 </head>
34   - <body class="<%=
35   - # Identify the current controller and action for the CSS:
36   - " controller-"+ @controller.controller_name() +
37   - " action-"+ @controller.controller_name() +"-"+ @controller.action_name() +
38   - " template-"+ ( profile.nil? ? "default" : profile.layout_template ) +
39   - (!profile.nil? && profile.is_on_homepage?(request.path,@page) ? " profile-homepage" : "")
40   - %>" >
41   -
  21 + <body class="<%= body_classes %>">
42 22 <a href="#content" id="link-go-content"><span><%= _("Go to the content") %></span></a>
  23 +
43 24 <%=
44 25 @plugins.dispatch(:body_beginning).collect do |content|
45 26 content.respond_to?(:call) ? content.call : content
... ... @@ -51,30 +32,7 @@
51 32 <%= theme_header %>
52 33 </div>
53 34 <div id="wrap-2">
54   - <div id="user">
55   - <span class='logged-in' style='display: none;'>
56   - <%= usermenu_logged_in %>
57   - </span>
58   - <span class='not-logged-in' style='display: none'>
59   -
60   - <%= _("<span class='login'>%s</span>") % thickbox_inline_popup_link('<i class="icon-menu-login"></i><strong>' + _('Login') + '</strong>', login_url, 'inlineLoginBox', :id => 'link_login') %>
61   - <%= @plugins.dispatch(:alternative_authentication_link).collect { |content| instance_eval(&content) }.join("") %>
62   -
63   - <div id='inlineLoginBox' style='display: none;'>
64   - <%= render :file => 'account/login', :locals => { :is_thickbox => true } %>
65   - </div>
66   -
67   - <% unless @plugins.dispatch(:allow_user_registration).include?(false) %>
68   - <%= _("<span class='or'>or</span> <span class='signup'>%s</span>") % link_to('<strong>' + _('Sign up') + '</strong>', :controller => 'account', :action => 'signup')%>
69   - <% end %>
70   -
71   - </span>
72   - <form action="/search" class="search_form" method="get" class="clean">
73   - <input name="query" size="15" title="<%=_('Search...')%>" onfocus="this.form.className='focused';" onblur="this.form.className=''" />
74   - <div><%=_('Press <strong>Enter</strong> to send the search query.')%></div>
75   - <%= javascript_tag 'jQuery("#user form input").hint();' %>
76   - </form>
77   - </div><!-- end id="user" -->
  35 + <%= render :partial => 'layouts/user' %>
78 36  
79 37 <h1 id="site-title">
80 38 <%= theme_site_title %>
... ...
app/views/profile/_profile_wall.rhtml
1 1 <h3><%= _("%s's wall") % @profile.name %></h3>
2 2 <div id='leave_scrap'>
3 3 <%= flash[:error] %>
4   - <% form_remote_tag :url => {:controller => 'profile', :action => 'leave_scrap', :tab_action => 'wall' }, :update => 'profile_activities', :success => "$('leave_scrap_content').value=''" do %>
  4 + <% form_remote_tag :url => {:controller => 'profile', :action => 'leave_scrap', :tab_action => 'wall' }, :update => 'profile_activities', :success => "$('leave_scrap_content').value=''", :complete => "jQuery('#leave_scrap_form').removeClass('loading').find('*').attr('disabled', false)", :loading => "jQuery('#leave_scrap_form').addClass('loading').find('*').attr('disabled', true)", :html => {:id => 'leave_scrap_form' } do %>
5 5 <%= limited_text_area :scrap, :content, 420, 'leave_scrap_content', :cols => 50, :rows => 2 %>
6 6 <%= submit_button :new, _('Share') %>
7 7 <% end %>
... ...
app/views/profile_members/_manage_roles.html.erb
... ... @@ -13,11 +13,11 @@
13 13  
14 14 <% @roles.each do |role| %>
15 15 <% search_url = url_for(:action => 'search_user', :profile => profile.identifier, :role => role.id) %>
16   - <% @pre_population ||= profile.members_by_role_to_json(role) %>
  16 + <% pre_population = params[:action] == 'last_admin' ? [].to_json : profile.members_by_role_to_json(role) %>
17 17 <script type="text/javascript">
18 18 jQuery(<%= ('#search_' + role.key).to_json %>)
19 19 .tokenInput("<%= search_url %>", {
20   - prePopulate: <%= @pre_population %>,
  20 + prePopulate: <%= pre_population %>,
21 21 hintText: <%= _('Type in a search term for users').to_json %>,
22 22 noResultsText: <%= _('No results').to_json %>,
23 23 searchingText: <%= _('Searching...').to_json %>,
... ...
app/views/search/_image.rhtml
... ... @@ -28,8 +28,9 @@
28 28 <div class="search-gallery-items">
29 29 <% r = image.children.find(:all, :order => :updated_at, :conditions => ['type = ?', 'UploadedFile']).last(3) %>
30 30 <% if r.length > 0 %>
31   - <% r.each do |i| %>
32   - <%= link_to '', i.view_url, :class => "search-image-pic", :style => 'background-image: url(%s)'% i.public_filename(:thumb) %>
  31 + <% r.each_index do |i| img = r[i] %>
  32 + <%= link_to '', img.view_url, :class => "search-image-pic pic-num#{i+1}",
  33 + :style => 'background-image: url(%s)'% img.public_filename(:thumb) %>
33 34 <% end %>
34 35 <% else %>
35 36 <div class="search-no-image"><span><%= _('No image') %></span></div>
... ...
app/views/shared/tiny_mce.rhtml
... ... @@ -20,7 +20,7 @@ tinyMCE.init({
20 20 editor_selector : "mceEditor",
21 21 theme : "advanced",
22 22 relative_urls : false,
23   - remove_script_host : true,
  23 + remove_script_host : false,
24 24 document_base_url : <%= environment.top_url.to_json %>,
25 25 plugins: myplugins,
26 26 theme_advanced_toolbar_location : "top",
... ...
app/views/templates/index.html.erb
... ... @@ -2,9 +2,9 @@
2 2  
3 3 <%= _('Manage the templates used on creation of profiles') %>
4 4  
5   -<% list_of_templates = [[_('Person') , Person.templates , 'person' ],
6   - [_('Community') , Community.templates , 'community' ],
7   - [_('Enterprise'), Enterprise.templates, 'enterprise']] %>
  5 +<% list_of_templates = [[_('Person') , Person.templates(environment) , 'person' ],
  6 + [_('Community') , Community.templates(environment) , 'community' ],
  7 + [_('Enterprise'), Enterprise.templates(environment), 'enterprise']] %>
8 8  
9 9 <% list_of_templates.each do |title, templates, kind|%>
10 10 <div class='template-kind'>
... ...
app/views/themes/index.rhtml
... ... @@ -11,17 +11,17 @@
11 11 base_content = image_tag(
12 12 "/designs/templates/#{template.id}/thumbnail.png",
13 13 :alt => _('The "%s" template')) +
14   - '<div class="opt-info">' +
  14 + '<div class="opt-info">'.html_safe +
15 15 content_tag('strong', template.id, :class => 'name') +
16   - ' <br/> '
  16 + ' <br/> '.html_safe
17 17  
18 18 if @current_template == template.id # selected
19 19 content_tag( 'div',
20   - base_content + content_tag('big', _('(current)') ) +'</div>',
  20 + base_content + content_tag('big', _('(current)') ) +'</div>'.html_safe,
21 21 :class => 'template-opt list-opt selected')
22 22 else # Not selected
23 23 link_to(
24   - base_content +'</div>',
  24 + base_content +'</div>'.html_safe,
25 25 { :action => 'set_layout_template', :id => template.id },
26 26 :class => 'template-opt list-opt')
27 27 end
... ... @@ -48,17 +48,17 @@
48 48 base_content = image_tag(
49 49 "/designs/themes/#{theme.id}/preview.png",
50 50 :alt => (_('The "%s" theme.') % theme.name)) +
51   - '<div class="opt-info">' +
  51 + '<div class="opt-info">'.html_safe +
52 52 content_tag('strong', theme.name, :class => 'name') +
53   - ' <br/> '
  53 + ' <br/> '.html_safe
54 54  
55 55 if theme.id == @current_theme # selected
56 56 content_tag( 'div',
57   - base_content + content_tag('big', _('(current)') ) +'</div>',
  57 + base_content + content_tag('big', _('(current)') ) +'</div>'.html_safe,
58 58 :class => 'theme-opt list-opt selected')
59 59 else # Not selected
60 60 link_to(
61   - base_content + '</div>',
  61 + base_content + '</div>'.html_safe,
62 62 { :action => 'set', :id => theme.id },
63 63 :class => 'theme-opt list-opt')
64 64 end
... ...
app/views/users/_user_csv.rhtml
... ... @@ -1 +0,0 @@
1   -<%= user_csv.name %>;<%= user_csv.email %>
app/views/users/index_csv.rhtml
... ... @@ -1,2 +0,0 @@
1   -<%= _('name') %>;<%= _('email') %>
2   -<%= render :partial => 'user_csv', :collection => @users %>
app/views/users/send_mail.rhtml
... ... @@ -4,7 +4,7 @@
4 4  
5 5 <%= render :file => 'shared/tiny_mce' %>
6 6  
7   -<% form_for :mailing, :url => {:action => 'send_mail', :host => @environment.default_hostname} do |f| %>
  7 +<% form_for :mailing do |f| %>
8 8 <%= labelled_form_field(_('Subject:'), f.text_field(:subject)) %>
9 9 <%= labelled_form_field(_('Body:'), f.text_area(:body, :class => 'mceEditor')) %>
10 10 <%= submit_button(:send, _('Send')) %>
... ...
config/cucumber.yml
1   -default: --tags ~@selenium,~@wip --exclude features/support/selenium.rb --exclude features/step_definitions/selenium_steps.rb -r features/support -r features/step_definitions
2   -selenium: --tags @selenium,~@wip -r features/support -r features/step_definitions
  1 +<% base_requires = '-r features/support -r features/step_definitions' %>
  2 +<% default_options = "--color --format progress --strict --tags ~@selenium --tags ~@selenium-fixme --tags ~@fixme --exclude features/support/selenium.rb #{base_requires}" %>
  3 +<% selenium_options = "--strict --tags @selenium #{base_requires}" %>
  4 +
  5 +default: <%= default_options %>
  6 +selenium: <%= selenium_options %>
  7 +
  8 +<% enabled_plugins = Dir.glob(File.join('config', 'plugins', '*')).map{|path| plugin = File.basename(path); plugin if File.exist?(File.join('features', 'plugins', plugin)) }.compact %>
  9 +
  10 +<% enabled_plugins.each do |plugin| %>
  11 +<% plugin_features_path = File.join('features', 'plugins', plugin) %>
  12 +<% plugin_base_requires = '' %>
  13 +<% plugin_base_requires += " -r features/plugins/#{plugin}/support" if File.exist?(File.join(plugin_features_path, 'support')) %>
  14 +<% plugin_base_requires += " -r features/plugins/#{plugin}/step_definitions" if File.exist?(File.join(plugin_features_path, 'step_definitions')) %>
  15 +<%= "#{plugin}: #{default_options} #{plugin_base_requires}" %>
  16 +<%= "#{plugin}_selenium: #{selenium_options} #{plugin_base_requires}" %>
  17 +<% end %>
... ...
config/database.yml.sqlite3
... ... @@ -6,6 +6,7 @@ development:
6 6 test: &TEST
7 7 adapter: sqlite3
8 8 database: db/test.db
  9 + timeout: 2000
9 10  
10 11 production:
11 12 adapter: sqlite3
... ...
config/environments/cucumber.rb
1   -# IMPORTANT: This file was generated by Cucumber 0.4.0
2 1 # Edit at your own peril - it's recommended to regenerate this file
3 2 # in the future when you upgrade to a newer version of Cucumber.
4 3  
5   -config.cache_classes = true # This must be true for Cucumber to operate correctly!
  4 +# IMPORTANT: Setting config.cache_classes to false is known to
  5 +# break Cucumber's use_transactional_fixtures method.
  6 +# For more information see https://rspec.lighthouseapp.com/projects/16211/tickets/165
  7 +config.cache_classes = true
6 8  
7 9 # Log error messages when you accidentally call methods on nil.
8 10 config.whiny_nils = true
... ... @@ -18,3 +20,8 @@ config.action_controller.allow_forgery_protection = false
18 20 # The :test delivery method accumulates sent emails in the
19 21 # ActionMailer::Base.deliveries array.
20 22 config.action_mailer.delivery_method = :test
  23 +
  24 +config.gem 'cucumber-rails', :lib => false, :version => '>=0.3.2' unless File.directory?(File.join(Rails.root, 'vendor/plugins/cucumber-rails'))
  25 +config.gem 'database_cleaner', :lib => false, :version => '>=0.5.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/database_cleaner'))
  26 +config.gem 'capybara', :lib => false, :version => '>=0.3.5' unless File.directory?(File.join(Rails.root, 'vendor/plugins/capybara'))
  27 +
... ...
db/migrate/20130117132943_remove_index_articles_on_name.rb 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +class RemoveIndexArticlesOnName < ActiveRecord::Migration
  2 + def self.up
  3 + remove_index :articles, :name
  4 + end
  5 +
  6 + def self.down
  7 + add_index :articles, :name
  8 + end
  9 +end
... ...
db/migrate/20130304200849_add_default_value_to_product_highlighted.rb 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +class AddDefaultValueToProductHighlighted < ActiveRecord::Migration
  2 + def self.up
  3 + change_column :products, :highlighted, :boolean, :default => false
  4 + execute('UPDATE products SET highlighted=(0>1) WHERE highlighted IS NULL;')
  5 + end
  6 +
  7 + def self.down
  8 + say 'This migraiton is not reversible!'
  9 + end
  10 +end
... ...
db/schema.rb
... ... @@ -9,7 +9,7 @@
9 9 #
10 10 # It's strongly recommended to check this file into your version control system.
11 11  
12   -ActiveRecord::Schema.define(:version => 20130111232201) do
  12 +ActiveRecord::Schema.define(:version => 20130304200849) do
13 13  
14 14 create_table "abuse_reports", :force => true do |t|
15 15 t.integer "reporter_id"
... ... @@ -415,7 +415,7 @@ ActiveRecord::Schema.define(:version =&gt; 20130111232201) do
415 415 t.datetime "updated_at"
416 416 t.decimal "discount"
417 417 t.boolean "available", :default => true
418   - t.boolean "highlighted"
  418 + t.boolean "highlighted", :default => false
419 419 t.integer "unit_id"
420 420 t.integer "image_id"
421 421 end
... ...
debian/changelog
  1 +noosfero (0.41.2) unstable; urgency=low
  2 +
  3 + * Bugfixes release
  4 +
  5 + -- Rodrigo Souto <rodrigo@colivre.coop.br> Wed, 17 Apr 2013 16:22:53 -0300
  6 +
  7 +noosfero (0.41.1) unstable; urgency=low
  8 +
  9 + * Bugfixes release
  10 +
  11 + -- Rodrigo Souto <rodrigo@colivre.coop.br> Fri, 08 Mar 2013 11:33:11 -0300
  12 +
  13 +noosfero (0.41.0) unstable; urgency=low
  14 +
  15 + * Features version with anti spam-bot measures
  16 +
  17 + -- Rodrigo Souto <rodrigo@colivre.coop.br> Mon, 28 Jan 2013 10:20:21 +0000
  18 +
  19 +noosfero (0.40.0) unstable; urgency=low
  20 +
  21 + * Features version release
  22 +
  23 + -- Rodrigo Souto <rodrigo@colivre.coop.br> Sat, 19 Jan 2013 21:58:06 +0000
  24 +
1 25 noosfero (0.39.3) unstable; urgency=low
2 26  
3 27 * Bugfixes release
... ...
features/accept_member.feature
... ... @@ -14,10 +14,11 @@ Feature: accept member
14 14 And the community "My Community" is closed
15 15 And "Mario Souto" is admin of "My Community"
16 16  
  17 + @selenium
17 18 Scenario: approve a task to accept a member as admin in a closed community
18 19 Given "Marie Curie" asked to join "My Community"
19 20 And I am logged in as "mario"
20   - And I go to My Community's control panel
  21 + And I go to mycommunity's control panel
21 22 And I follow "Process requests"
22 23 And I should see "Marie Curie wants to be a member"
23 24 When I choose "Accept"
... ... @@ -25,10 +26,11 @@ Feature: accept member
25 26 And I press "Apply!"
26 27 Then "Marie Curie" should be admin of "My Community"
27 28  
  29 + @selenium
28 30 Scenario: approve a task to accept a member as member in a closed community
29 31 Given "Marie Curie" asked to join "My Community"
30 32 And I am logged in as "mario"
31   - And I go to My Community's control panel
  33 + And I go to mycommunity's control panel
32 34 And I follow "Process requests"
33 35 And I should see "Marie Curie wants to be a member"
34 36 When I choose "Accept"
... ... @@ -36,10 +38,11 @@ Feature: accept member
36 38 And I press "Apply!"
37 39 Then "Marie Curie" should be a member of "My Community"
38 40  
  41 + @selenium
39 42 Scenario: approve a task to accept a member as moderator in a closed community
40 43 Given "Marie Curie" asked to join "My Community"
41 44 And I am logged in as "mario"
42   - And I go to My Community's control panel
  45 + And I go to mycommunity's control panel
43 46 And I follow "Process requests"
44 47 And I should see "Marie Curie wants to be a member"
45 48 When I choose "Accept"
... ...
features/activate_enterprise.feature
... ... @@ -11,7 +11,7 @@ Feature: activate enterprise
11 11  
12 12 Scenario: added an unexistent code
13 13 Given feature "enterprise_activation" is enabled on environment
14   - And I am on Joao Silva's control panel
  14 + And I am on joaosilva's control panel
15 15 And I fill in "Enterprise activation code" with "abcde"
16 16 When I press "Activate"
17 17 Then I should see "Invalid enterprise code"
... ... @@ -21,7 +21,7 @@ Feature: activate enterprise
21 21 And the following enterprises
22 22 | identifier | name | enabled |
23 23 | products-factory | Products Factory | false |
24   - And I am on Joao Silva's control panel
  24 + And I am on joaosilva's control panel
25 25 And enterprise "Products Factory" is enabled
26 26 And I fill in "Enterprise activation code" with code of "Products Factory"
27 27 When I press "Activate"
... ... @@ -32,7 +32,7 @@ Feature: activate enterprise
32 32 And the following enterprises
33 33 | identifier | name | enabled |
34 34 | products-factory | Products Factory | false |
35   - And I am on Joao Silva's control panel
  35 + And I am on joaosilva's control panel
36 36 And I fill in "Enterprise activation code" with code of "Products Factory"
37 37 When I press "Activate"
38 38 Then I should see "We don't have enough information about your enterprise to identify you."
... ... @@ -43,7 +43,7 @@ Feature: activate enterprise
43 43 And the following enterprises
44 44 | identifier | name | enabled | foundation_year |
45 45 | services-provider | Services Provider | false | 2000 |
46   - And I am on Joao Silva's control panel
  46 + And I am on joaosilva's control panel
47 47 And I fill in "Enterprise activation code" with code of "Services Provider"
48 48 And I press "Activate"
49 49 And I fill in "What year your enterprise was founded? It must have 4 digits, eg 1990." with "1999"
... ... @@ -56,7 +56,7 @@ Feature: activate enterprise
56 56 And the following enterprises
57 57 | identifier | name | enabled | cnpj |
58 58 | services-provider | Services Provider | false | 94.132.024/0001-48 |
59   - And I am on Joao Silva's control panel
  59 + And I am on joaosilva's control panel
60 60 And I fill in "Enterprise activation code" with code of "Services Provider"
61 61 And I press "Activate"
62 62 And I fill in "What is the CNPJ of your enterprise?" with "12345678912345"
... ... @@ -70,9 +70,9 @@ Feature: activate enterprise
70 70 And the following enterprises
71 71 | identifier | name | enabled | foundation_year |
72 72 | services-provider | Services Provider | false | 2000 |
73   - And I visit "Joao Silva's control panel" and wait
  73 + And I go to joaosilva's control panel
74 74 And I fill in "Enterprise activation code" with code of "Services Provider"
75   - And I press "Activate" and wait
  75 + And I press "Activate"
76 76 And I fill in "What year your enterprise was founded? It must have 4 digits, eg 1990." with "2000"
77 77 And I press "Continue"
78 78 And I check "I read the terms of use and accepted them"
... ... @@ -91,9 +91,9 @@ Feature: activate enterprise
91 91 | active-template | Active Template | false | 2000 |
92 92 And "Active Template" is the active enterprise template
93 93 And "Services Provider 2" doesnt have "Active Template" as template
94   - And I visit "Joao Silva's control panel" and wait
  94 + And I go to joaosilva's control panel
95 95 And I fill in "Enterprise activation code" with code of "Services Provider 2"
96   - And I press "Activate" and wait
  96 + And I press "Activate"
97 97 And I fill in "What year your enterprise was founded? It must have 4 digits, eg 1990." with "2000"
98 98 And I press "Continue"
99 99 And I check "I read the terms of use and accepted them"
... ... @@ -113,9 +113,9 @@ Feature: activate enterprise
113 113 | active-template | Active Template | false | 2000 |
114 114 And "Active Template" is the active enterprise template
115 115 And "Services Provider 3" doesnt have "Active Template" as template
116   - When I visit "Joao Silva's control panel" and wait
  116 + When I go to joaosilva's control panel
117 117 And I fill in "Enterprise activation code" with code of "Services Provider 3"
118   - And I press "Activate" and wait
  118 + And I press "Activate"
119 119 And I fill in "What year your enterprise was founded? It must have 4 digits, eg 1990." with "2000"
120 120 And I press "Continue"
121 121 And I check "I read the terms of use and accepted them"
... ...
features/admin_categories.feature
... ... @@ -16,22 +16,22 @@ Feature: manage categories
16 16 @selenium
17 17 Scenario: admin user could access new category
18 18 Given I follow "Administration"
19   - When I follow "Manage Categories"
20   - And I follow "New category" and wait
  19 + When I follow "Categories"
  20 + And I follow "New category"
21 21 Then I should be on /admin/categories/new
22 22  
23 23 @selenium
24 24 Scenario: admin user could create a category
25   - Given I visit "/admin/categories/new" and wait
26   - When I fill in "Name" with "Category 1"
27   - And I press "Save"
28   - Then I should see "Categories"
29   - And I should see "Category 1"
  25 + Given I go to /admin/categories/new
  26 + And I fill in "Name" with "Category 1"
  27 + When I press "Save"
  28 + Then I should see "Categories"
  29 + And I should see "Category 1"
30 30  
31 31 @selenium
32 32 Scenario: admin user could see all the category tree
33 33 Given I follow "Administration"
34   - And I follow "Manage Categories"
  34 + And I follow "Categories"
35 35 When I follow "Show"
36 36 Then I should see "Vegetarian"
37 37 And I should see "Steak"
... ... @@ -39,13 +39,13 @@ Feature: manage categories
39 39 @selenium
40 40 Scenario: admin user could hide the category tree
41 41 Given I follow "Administration"
42   - And I follow "Manage Categories"
43   - When I follow "Show"
  42 + And I follow "Categories"
  43 + When I follow "Show" and wait while it hides
44 44 Then I should see "Vegetarian"
45 45 And I should see "Steak"
46   - When I follow "Hide" and sleep 1 second
47   - Then I should not see "Vegetarian"
48   - And I should not see "Steak"
  46 + When I follow "Hide" and wait while it hides
  47 + Then "Vegetarian" should not be visible within "div"
  48 + And "Steak" should not be visible within "div"
49 49  
50 50 @selenium
51 51 Scenario: the show link is available just for categories with category tree
... ... @@ -54,7 +54,7 @@ Feature: manage categories
54 54 | Steak | Pig | true |
55 55 And I am on the homepage
56 56 When I follow "Administration"
57   - And I follow "Manage Categories"
  57 + And I follow "Categories"
58 58 Then I should see "Food Show"
59 59 When I follow "Show"
60 60 Then I should see "Vegetarian"
... ...
features/approve_article.feature
... ... @@ -19,52 +19,52 @@ Feature: approve article
19 19 And "Maria Silva" is a member of "Sample Community"
20 20 And "Joao Silva" is admin of "Sample Community"
21 21  
22   - @selenium
  22 + @selenium-fixme
23 23 Scenario: edit an article before approval
24 24 Given I am logged in as "mariasilva"
25   - And I am on Maria Silva's homepage
26   - When I follow "Spread" and wait
  25 + And I am on mariasilva's homepage
  26 + When I follow "Spread"
27 27 And I check "Sample Community"
28 28 And I press "Spread this"
29 29 And I am logged in as "joaosilva"
30   - And I go to Sample Community's control panel
31   - And I follow "Process requests" and wait
  30 + And I go to sample-community's control panel
  31 + And I follow "Process requests"
32 32 And I fill in "Text" with "This is an article edited"
33 33 And I choose "Accept"
34 34 And I press "Apply!"
35   - And I go to Sample Community's sitemap
  35 + And I go to sample-community's sitemap
36 36 And I follow "Sample Article"
37 37 Then I should see "This is an article edited"
38 38  
39 39 @selenium
40 40 Scenario: reject an article with explanation
41 41 Given I am logged in as "mariasilva"
42   - And I go to Maria Silva's cms
  42 + And I go to mariasilva's cms
43 43 And I follow "Sample Article"
44   - And I follow "Spread" and wait
  44 + And I follow "Spread"
45 45 And I check "Sample Community"
46 46 And I press "Spread this"
47 47 And I am logged in as "joaosilva"
48   - And I go to Sample Community's control panel
49   - And I follow "Process requests" and wait
  48 + And I go to sample-community's control panel
  49 + And I follow "Process requests"
50 50 And I choose "Reject"
51 51 And I fill in "Rejection explanation" with "This is not an appropriate article for this community."
52 52 And I press "Apply!"
53   - When I go to Sample Community's sitemap
  53 + When I go to sample-community's sitemap
54 54 Then I should not see "Sample Article"
55 55  
56 56 @selenium
57 57 Scenario: reject an article that was removed
58 58 Given I am logged in as "mariasilva"
59 59 And I follow "Dub Wars"
60   - And I follow "Spread" and wait
  60 + And I follow "Spread"
61 61 And I check "Sample Community"
62 62 And I press "Spread this"
63 63 And I follow "Delete"
64   - And I press "Yes, I want."
  64 + And I confirm the browser dialog
65 65 When I am logged in as "joaosilva"
66   - And I go to Sample Community's control panel
67   - And I follow "Process requests" and wait
  66 + And I go to sample-community's control panel
  67 + And I follow "Process requests"
68 68 And I choose "Reject"
69 69 And I fill in "Rejection explanation" with "Article was removed."
70 70 And I press "Apply!"
... ...
features/balloon.feature
... ... @@ -12,33 +12,29 @@ Feature: balloon
12 12 @selenium
13 13 Scenario: I should not see trigger if not enabled
14 14 Given feature "show_balloon_with_profile_links_when_clicked" is disabled on environment
15   - When I go to /browse/people
  15 + When I go to /search/people
16 16 Then I should not see "Profile links"
17 17  
18 18 @selenium
19 19 Scenario: I should not see trigger by default
20   - Given the following blocks
21   - | owner | type |
22   - | environment | PeopleBlock |
23   - And feature "show_balloon_with_profile_links_when_clicked" is enabled on environment
24   - When I go to the homepage
  20 + Given feature "show_balloon_with_profile_links_when_clicked" is enabled on environment
  21 + When I go to /search/people
25 22 Then I should not see "Friends"
26 23  
27 24 @selenium
28 25 Scenario: I should see balloon when clicked on people block trigger
29   - Given the following blocks
30   - | owner | type |
31   - | environment | PeopleBlock |
32   - And feature "show_balloon_with_profile_links_when_clicked" is enabled on environment
33   - When I go to the homepage
34   - And I follow "Profile links"
  26 + Given feature "show_balloon_with_profile_links_when_clicked" is enabled on environment
  27 + And I go to /search/people
  28 + And display ".person-trigger"
  29 + When I follow "Profile links"
35 30 Then I should see "Friends"
36 31  
37 32 @selenium
38 33 Scenario: I should see balloon when clicked on community block trigger
39 34 Given feature "show_balloon_with_profile_links_when_clicked" is enabled on environment
40   - When I go to /browse/communities
41   - And I follow "Profile links"
  35 + And I go to /search/communities
  36 + And display ".community-trigger"
  37 + When I follow "Profile links"
42 38 Then I should see "Members"
43 39  
44 40 @selenium
... ... @@ -56,7 +52,8 @@ Feature: balloon
56 52 @selenium
57 53 Scenario: I should see balloon when clicked on page trigger
58 54 Given feature "show_balloon_with_profile_links_when_clicked" is enabled on environment
59   - When I go to /assets/communities
60   - And I follow "Profile links"
  55 + And I go to /assets/communities
  56 + And display ".community-trigger"
  57 + When I follow "Profile links"
61 58 Then I should see "Members"
62 59 And I should see "Agenda"
... ...
features/blog.feature
... ... @@ -11,16 +11,16 @@ Feature: blog
11 11 And I am logged in as "joaosilva"
12 12  
13 13 Scenario: create a blog
14   - Given I go to the Control panel
  14 + Given I go to joaosilva's control panel
15 15 And I follow "Create blog"
16 16 Then I should see "My Blog"
17 17 When I fill in "Title" with "My Blog"
18 18 And I press "Save"
19   - And I go to Joao Silva's control panel
  19 + And I go to joaosilva's control panel
20 20 Then I should see "Configure blog"
21 21  
22 22 Scenario: redirect to blog after create blog from control panel
23   - Given I go to the Control panel
  23 + Given I go to joaosilva's control panel
24 24 And I follow "Create blog"
25 25 Then I should see "My Blog"
26 26 When I fill in "Title" with "My Blog"
... ... @@ -28,7 +28,7 @@ Feature: blog
28 28 Then I should be on /joaosilva/my-blog
29 29  
30 30 Scenario: redirect to blog after create blog from cms
31   - Given I go to the Control panel
  31 + Given I go to joaosilva's control panel
32 32 And I follow "Manage Content"
33 33 And I follow "New content"
34 34 When I follow "Blog"
... ... @@ -37,13 +37,13 @@ Feature: blog
37 37 Then I should be on /joaosilva/blog-from-cms
38 38  
39 39 Scenario: create multiple blogs
40   - Given I go to the Control panel
  40 + Given I go to joaosilva's control panel
41 41 And I follow "Manage Content"
42 42 And I follow "New content"
43 43 And I follow "Blog"
44 44 And I fill in "Title" with "Blog One"
45 45 And I press "Save"
46   - Then I go to the Control panel
  46 + Then I go to joaosilva's control panel
47 47 And I follow "Manage Content"
48 48 And I follow "New content"
49 49 And I follow "Blog"
... ... @@ -53,7 +53,7 @@ Feature: blog
53 53 And I should be on /joaosilva/blog-two
54 54  
55 55 Scenario: cancel button back to cms
56   - Given I go to the Control panel
  56 + Given I go to joaosilva's control panel
57 57 And I follow "Manage Content"
58 58 And I follow "New content"
59 59 And I follow "Blog"
... ... @@ -61,7 +61,7 @@ Feature: blog
61 61 Then I should be on /myprofile/joaosilva/cms
62 62  
63 63 Scenario: cancel button back to myprofile
64   - Given I go to the Control panel
  64 + Given I go to joaosilva's control panel
65 65 And I follow "Create blog"
66 66 When I follow "Cancel" within ".main-block"
67 67 Then I should be on /myprofile/joaosilva
... ... @@ -71,7 +71,7 @@ Feature: blog
71 71 | owner | name |
72 72 | joaosilva | Blog One |
73 73 | joaosilva | Blog Two |
74   - And I go to the Control panel
  74 + And I go to joaosilva's control panel
75 75 When I follow "Configure blog"
76 76 Then I should be on /myprofile/joaosilva/cms
77 77  
... ... @@ -79,7 +79,7 @@ Feature: blog
79 79 Given the following blogs
80 80 | owner | name |
81 81 | joaosilva | Blog One |
82   - And I go to the Control panel
  82 + And I go to joaosilva's control panel
83 83 When I follow "Configure blog"
84 84 Then I should be on edit "Blog One" by joaosilva
85 85  
... ... @@ -89,14 +89,14 @@ Feature: blog
89 89 | owner | name |
90 90 | joaosilva | Blog One |
91 91 And I go to /joaosilva/blog-one
92   - When I follow "Configure blog" and wait
  92 + When I follow "Configure blog"
93 93 Then I should be on edit "Blog One" by joaosilva
94 94  
95 95 Scenario: change address of blog
96 96 Given the following blogs
97 97 | owner | name |
98 98 | joaosilva | Blog One |
99   - And I go to the Control panel
  99 + And I go to joaosilva's control panel
100 100 And I follow "Configure blog"
101 101 And I fill in "Address" with "blog-two"
102 102 And I press "Save"
... ... @@ -104,7 +104,7 @@ Feature: blog
104 104 Then I should see "Blog One"
105 105  
106 106 Scenario: display tag list field when creating new blog
107   - Given I go to the Control panel
  107 + Given I go to joaosilva's control panel
108 108 And I follow "Manage Content"
109 109 And I follow "New content"
110 110 When I follow "Blog"
... ...
features/browse.feature
... ... @@ -17,32 +17,34 @@ Feature: browse
17 17  
18 18 @selenium
19 19 Scenario: Show people browse menu
20   - Given I should not see "More Recent"
21   - And I should not see "More Active"
22   - And I should not see "More Popular"
23   - When I click "#submenu-people-trigger"
24   - Then I should see "More Recent"
25   - And I should see "More Active"
26   - And I should see "More Popular"
  20 + Given I should not see "More recent"
  21 + And I should not see "More active"
  22 + And I should not see "More popular"
  23 + And display "#submenu-people-trigger"
  24 + When I follow "submenu-people-trigger"
  25 + Then I should see "More recent"
  26 + And I should see "More active"
  27 + And I should see "More popular"
27 28  
28 29 @selenium
29 30 Scenario: People browse menu should add logged information
30 31 Given I am logged in as "joaosilva"
31   - And I should not see "More Recent"
32   - And I should not see "More Active"
33   - And I should not see "More Popular"
  32 + And I should not see "More recent"
  33 + And I should not see "More active"
  34 + And I should not see "More popular"
34 35 And I should not see "Invite friends"
35 36 And I should not see "My friends"
36   - When I click "#submenu-people-trigger"
37   - Then I should see "More Recent"
38   - And I should see "More Active"
39   - And I should see "More Popular"
  37 + And display "#submenu-people-trigger"
  38 + When I follow "submenu-people-trigger"
  39 + Then I should see "More recent"
  40 + And I should see "More active"
  41 + And I should see "More popular"
40 42 And I should see "Invite friends"
41 43 And I should see "My friends"
42 44  
43 45 Scenario: Browse people by query
44 46 Given I go to /search/people
45   - When I fill in "Silva" for "query"
  47 + When I fill in "Silva" for "search-input"
46 48 And I press "Search"
47 49 Then I should see "Joao Silva"
48 50 And I should see "Pedro Silva"
... ... @@ -54,31 +56,33 @@ Feature: browse
54 56 Scenario: Communities browse menu should add logged information
55 57 Given I am logged in as "joaosilva"
56 58 When I go to /joaosilva
57   - Then I should not see "More Recent"
58   - And I should not see "More Active"
59   - And I should not see "More Popular"
  59 + Then I should not see "More recent"
  60 + And I should not see "More active"
  61 + And I should not see "More popular"
60 62 And I should not see "My communities"
61 63 And I should not see "New community"
62   - When I click "#submenu-communities-trigger"
63   - Then I should see "More Recent"
64   - And I should see "More Active"
65   - And I should see "More Popular"
  64 + And display "#submenu-communities-trigger"
  65 + When I follow "submenu-communities-trigger"
  66 + Then I should see "More recent"
  67 + And I should see "More active"
  68 + And I should see "More popular"
66 69 And I should see "My communities"
67 70 And I should see "New community"
68 71  
69 72 @selenium
70 73 Scenario: Show communities browse menu
71   - Given I should not see "More Recent"
72   - And I should not see "More Active"
73   - And I should not see "More Popular"
74   - When I click "#submenu-communities-trigger"
75   - Then I should see "More Recent"
76   - And I should see "More Active"
77   - And I should see "More Popular"
  74 + Given I should not see "More recent"
  75 + And I should not see "More active"
  76 + And I should not see "More popular"
  77 + And display "#submenu-communities-trigger"
  78 + When I follow "submenu-communities-trigger"
  79 + Then I should see "More recent"
  80 + And I should see "More active"
  81 + And I should see "More popular"
78 82  
79 83 Scenario: Browse communities by query
80 84 When I go to /search/communities
81   - And I fill in "Neto" for "query"
  85 + And I fill in "Neto" for "search-input"
82 86 And I press "Search"
83 87 Then I should see "Community Neto"
84 88 And I should not see "Joao Silva"
... ... @@ -88,13 +92,14 @@ Feature: browse
88 92  
89 93 @selenium
90 94 Scenario: Show contents browse menu
91   - Given I should not see "More Comments"
92   - And I should not see "More Views"
93   - And I should not see "More Recent"
94   - When I click "#submenu-contents-trigger"
95   - Then I should see "More Comments"
96   - And I should see "More Views"
97   - And I should see "More Recent"
  95 + Given I should not see "Most commented"
  96 + And I should not see "More viewed"
  97 + And I should not see "More recent"
  98 + And display "#submenu-contents-trigger"
  99 + When I follow "submenu-contents-trigger"
  100 + Then I should see "Most commented"
  101 + And I should see "More viewed"
  102 + And I should see "More recent"
98 103  
99 104 Scenario: Browse contents by query
100 105 Given the following articles
... ... @@ -103,7 +108,7 @@ Feature: browse
103 108 | joaosilva | Bees and ants are insects | this is another article |
104 109 | joaosilva | Ants are small | this is another article |
105 110 When I go to /search/contents
106   - And I fill in "bees" for "query"
  111 + And I fill in "bees" for "search-input"
107 112 And I press "Search"
108 113 Then I should see "Bees can fly"
109 114 And I should see "Bees and ants are insects"
... ...
features/browse_catalogs.feature
... ... @@ -18,7 +18,7 @@ Feature: browse catalogs
18 18  
19 19 Scenario: display titles
20 20 Then I should see "Associação de Artesanato de Bonito"
21   - And I should see "Products/Services" within "#product-list"
  21 + And I should see "Products/Services"
22 22  
23 23 Scenario: display the simplest possible product
24 24 Given the following products
... ... @@ -132,7 +132,7 @@ Feature: browse catalogs
132 132 And I should not see "qualifiers"
133 133 And I should not see "price composition"
134 134  
135   - @selenium
  135 + @selenium-fixme
136 136 Scenario: display description button when needed (but not the description)
137 137 Given the following products
138 138 | owner | category | name | price | description |
... ... @@ -142,22 +142,22 @@ Feature: browse catalogs
142 142 Then I should see "Produto2" within "li.product-link"
143 143 And I should see "12.34" within "span.product-price"
144 144 And I should see "description" within "#product-description-button"
145   - And the "product-description-button" should be visible
  145 + And "description" should not be visible within "product-description-button"
146 146 And I should see "A small description" within "#product-description"
147   - And the "product-description" should not be visible
  147 + And "A small description for a product that doesn't exist" should not be visible within "product-description"
148 148  
149   - @selenium
  149 + @selenium-fixme
150 150 Scenario: display description when button is clicked
151 151 Given the following products
152 152 | owner | category | name | price | description |
153 153 | artebonito | categ1 | Produto3 | 12.34 | A small description for a product that doesn't exist. |
154 154 And I am on /catalog/artebonito
155 155 And I reload and wait for the page
156   - When I click "product-description-button"
  156 + When I follow "product-description-button"
157 157 Then I should see "A small description" within "#product-description"
158   - And the "product-description" should be visible
  158 + And "A small description for a product that doesn't exist" should not be visible within "product-description"
159 159  
160   - @selenium
  160 + @selenium-fixme
161 161 Scenario: hide description
162 162 Given the following products
163 163 | owner | category | name | price | description |
... ... @@ -198,7 +198,7 @@ Feature: browse catalogs
198 198 And I should see "Organic" within "span.search-product-qualifier"
199 199 And I should not see "price composition"
200 200  
201   - @selenium
  201 + @selenium-fixme
202 202 Scenario: not display price composition button if price is not described
203 203 Given the following product
204 204 | owner | category | name | price |
... ... @@ -212,7 +212,7 @@ Feature: browse catalogs
212 212 And I should see "10.00" within "span.product-price"
213 213 And the "#product-price-composition-button" should not be visible
214 214  
215   - @selenium
  215 + @selenium-fixme
216 216 Scenario: display price composition button (but not inputs)
217 217 Given the following product
218 218 | owner | category | name | price |
... ... @@ -229,7 +229,7 @@ Feature: browse catalogs
229 229 And I should see "food" within "#product-price-composition"
230 230 And I should see "10.00" within "#product-price-composition"
231 231  
232   - @selenium
  232 + @selenium-fixme
233 233 Scenario: display price composition when button is clicked
234 234 Given the following product
235 235 | owner | category | name | price |
... ... @@ -244,7 +244,7 @@ Feature: browse catalogs
244 244 And I should see "food" within "#product-price-composition"
245 245 And I should see "10.88" within "#product-price-composition"
246 246  
247   - @selenium
  247 + @selenium-fixme
248 248 Scenario: display inputs and raw materials button when not completely filled
249 249 Given the following product
250 250 | owner | category | name | price |
... ... @@ -260,7 +260,7 @@ Feature: browse catalogs
260 260 Then the "#inputs-button" should be visible
261 261 And I should see "inputs and raw materials" within "#inputs-button"
262 262  
263   - @selenium
  263 + @selenium-fixme
264 264 Scenario: display inputs and raw materials button
265 265 Given the following product
266 266 | owner | category | name | price |
... ... @@ -280,7 +280,7 @@ Feature: browse catalogs
280 280 And the "#inputs-description" should not be visible
281 281 And I should see "7.0 Liter of food" within "#inputs-description"
282 282  
283   - @selenium
  283 + @selenium-fixme
284 284 Scenario: display inputs and raw materials description
285 285 Given the following product
286 286 | owner | category | name | price |
... ... @@ -297,7 +297,7 @@ Feature: browse catalogs
297 297 Then the "#inputs-description" should be visible
298 298 And I should see "7.0 Liter of food" within "#inputs-description"
299 299  
300   - @selenium
  300 + @selenium-fixme
301 301 Scenario: hide inputs and raw materials
302 302 Given the following product
303 303 | owner | category | name | price |
... ...
features/browse_enterprises.feature
... ... @@ -24,7 +24,7 @@ Scenario: show profile links button
24 24 And I should not see "Members"
25 25 And I should not see "Agenda"
26 26  
27   -@selenium
  27 +@selenium-fixme
28 28 Scenario: show profile links when clicked
29 29 Given I am on /assets/enterprises
30 30 When I follow "Profile links"
... ... @@ -32,7 +32,7 @@ Scenario: show profile links when clicked
32 32 And I should see "Members" within "ul.menu-submenu-list"
33 33 And I should see "Agenda" within "ul.menu-submenu-list"
34 34  
35   -@selenium
  35 +@selenium-fixme
36 36 Scenario: go to catalog when click on products link
37 37 Given I am on /assets/enterprises
38 38 When I follow "Profile links"
... ...
features/categories_block.feature
... ... @@ -25,7 +25,7 @@ Feature: categories_block
25 25 | environment | CategoriesBlock |
26 26 And I am logged in as admin
27 27  
28   - @selenium
  28 + @selenium @ignore-hidden-elements
29 29 Scenario: List just product categories
30 30 Given I go to /admin/environment_design
31 31 And I follow "Edit" within ".categories-block"
... ... @@ -33,11 +33,11 @@ Feature: categories_block
33 33 When I press "Save"
34 34 Then I should see "Food"
35 35 And I should see "Book"
36   - And I should not see "Vegetarian"
37   - And I should not see "Steak"
38   - And I should not see "Fiction"
  36 + And "Vegetarian" should not be visible within "span#category-name"
  37 + And "Steak" should not be visible within "span#category-name"
  38 + And "Fiction" should not be visible within "span#category-name"
39 39  
40   - @selenium
  40 + @selenium @ignore-hidden-elements
41 41 Scenario: Show submenu if it exists
42 42 Given I go to /admin/environment_design
43 43 And I follow "Edit" within ".categories-block"
... ... @@ -45,40 +45,39 @@ Feature: categories_block
45 45 And I press "Save"
46 46 Then I should see "Food"
47 47 And I should see "Book"
48   - And I should not see "Vegetarian"
49   - And I should not see "Steak"
50   - And I should not see "Literature"
51   - When I click ".category-link-expand category-root"
  48 + And "Vegetarian" should not be visible within "span#category-name"
  49 + And "Steak" should not be visible within "span#category-name"
  50 + And "Literature" should not be visible within "span#category-name"
  51 + When I follow "block_2_category_2"
52 52 Then I should see "Literature"
53   - When I click ".category-link-expand category-root"
  53 + When I follow "block_2_category_1"
54 54 Then I should see "Vegetarian"
55 55 And I should see "Steak"
56 56 And I should not see "Fiction"
57 57  
58   - @selenium
  58 + @selenium @ignore-hidden-elements
59 59 Scenario: Show only one submenu per time
60 60 Given I go to /admin/environment_design
61 61 And I follow "Edit" within ".categories-block"
62 62 And I check "Product"
63 63 And I press "Save"
64 64 Then I should see "Book"
65   - And I should not see "Literature"
66   - When I click ".category-link-expand category-root"
  65 + And "Literature" should not be visible within "span#category-name"
  66 + When I follow "block_2_category_2"
67 67 Then I should see "Literature"
68 68  
69   - @selenium
  69 + @selenium @ignore-hidden-elements
70 70 Scenario: List just general categories
71 71 Given I go to /admin/environment_design
72 72 And I follow "Edit" within ".categories-block"
73   - And I check "Generic Category"
  73 + And I check "Generic category"
74 74 When I press "Save"
75 75 Then I should see "Wood"
76 76  
77   - @selenium
  77 + @selenium @ignore-hidden-elements
78 78 Scenario: List just regions
79 79 Given I go to /admin/environment_design
80 80 And I follow "Edit" within ".categories-block"
81 81 And I check "Region"
82 82 When I press "Save"
83 83 Then I should see "Bahia"
84   -
... ...
features/change_organization_name.feature
... ... @@ -12,12 +12,12 @@ Feature: change organization name
12 12 | joaosilva | Joao Silva |
13 13 And "Joao Silva" is admin of "Sample Community"
14 14 And I am logged in as "joaosilva"
15   - And I am on Sample Community's control panel
  15 + And I am on sample-community's control panel
16 16 And I follow "Community Info and settings"
17 17 And I fill in "Name" with "New Sample Community"
18 18 When I press "Save"
19   - Then I should be on New Sample Community's control panel
20   -
  19 + Then I should be on sample-community's control panel
  20 + And I should see "New Sample Community" within "title"
21 21  
22 22 Scenario: changing enterprise's name
23 23 Given the following enterprises
... ... @@ -28,8 +28,9 @@ Feature: change organization name
28 28 | joaosilva | Joao Silva |
29 29 And "Joao Silva" is admin of "Sample Enterprise"
30 30 And I am logged in as "joaosilva"
31   - And I am on Sample Enterprise's control panel
  31 + And I am on sample-enterprise's control panel
32 32 And I follow "Enterprise Info and settings"
33 33 And I fill in "Name" with "New Sample Enterprise"
34 34 When I press "Save"
35   - Then I should be on New Sample Enterprise's control panel
  35 + Then I should be on sample-enterprise's control panel
  36 + And I should see "New Sample Enterprise" within "title"
... ...
features/chat.feature
... ... @@ -17,7 +17,7 @@ Feature: chat
17 17 Scenario: provide link to open chat
18 18 Given feature "xmpp_chat" is enabled on environment
19 19 And I am logged in as "tame"
20   - Then I should see "Open chat" link
  20 + Then I should see "Open chat" within "#user"
21 21  
22 22 @selenium
23 23 Scenario: provide the chat online users content
... ... @@ -30,18 +30,18 @@ Feature: chat
30 30 Given the profile "tame" has no blocks
31 31 And feature "xmpp_chat" is enabled on environment
32 32 And I am logged in as "tame"
33   - And I go to Tame's profile
34   - When I click "#chat-online-users-title"
  33 + And I go to tame's profile
  34 + When I follow "chat-online-users-title"
35 35 Then I should see "Maria Silva"
36 36 And I should see "Jose Silva"
37 37  
38 38 Scenario: not provide link to chat when environment not support that
39 39 Given I am logged in as "tame"
40   - Then I should not see "Open chat" link
  40 + Then I should not see "Open chat" within "#user"
41 41  
42 42 Scenario: not provide link to chat when the user is logged out
43   - Given I am on Tame's homepage
44   - Then I should not see "Open chat" link
  43 + Given I am on tame's homepage
  44 + Then I should not see "Open chat" within "#user"
45 45  
46 46 @selenium
47 47 Scenario: not provide the chat online users list when environment not support that
... ... @@ -71,8 +71,8 @@ Feature: chat
71 71 Given the profile "tame" has no blocks
72 72 And feature "xmpp_chat" is enabled on environment
73 73 And I am logged in as "tame"
74   - And I go to Tame's profile
75   - When I click "#chat-online-users-title"
  74 + And I go to tame's profile
  75 + When I follow "chat-online-users-title"
76 76 And I follow "Maria Silva"
77 77 And I select window "noosfero_chat"
78 78 Then I should see "Chat - Colivre.net - Friends online (0)"
... ... @@ -83,7 +83,7 @@ Feature: chat
83 83 And I am logged in as "tame"
84 84 When I follow "Open chat"
85 85 And I select window "noosfero_chat"
86   - Then I should see "Offline" link
  86 + Then I should see "Offline" within "a"
87 87  
88 88 @selenium
89 89 Scenario: view options to change my chat status through menu
... ... @@ -91,13 +91,13 @@ Feature: chat
91 91 And I am logged in as "tame"
92 92 And I follow "Open chat"
93 93 When I select window "noosfero_chat"
94   - Then the "#chat-online" should not be visible
95   - And the "#chat-busy" should not be visible
96   - And the "#chat-disconnect" should not be visible
  94 + Then "Online" should not be visible within "#user-status"
  95 + And "Busy" should not be visible within "#user-status"
  96 + And "Sign out of chat" should not be visible within "#user-status"
97 97 When I follow "Offline"
98   - Then the "#chat-connect" should be visible
99   - And the "#chat-busy" should be visible
100   - And the "#chat-disconnect" should be visible
  98 + Then "Online" should be visible within "#user-status"
  99 + And "Busy" should be visible within "#user-status"
  100 + And "Sign out of chat" should be visible within "#user-status"
101 101  
102 102 @selenium
103 103 Scenario: link to open chatroom of a community
... ... @@ -107,8 +107,8 @@ Feature: chat
107 107 And "Tame" is a member of "Autoramas"
108 108 And feature "xmpp_chat" is enabled on environment
109 109 And I am logged in as "tame"
110   - When I go to Autoramas's profile
111   - Then I should see "Enter chat room" link
  110 + When I go to autoramas's profile
  111 + Then I should see "Enter chat room"
112 112  
113 113 @selenium
114 114 Scenario: not see link to open chatroom of a community if not a member
... ... @@ -117,8 +117,8 @@ Feature: chat
117 117 | autoramas | Autoramas |
118 118 And feature "xmpp_chat" is enabled on environment
119 119 And I am logged in as "tame"
120   - When I go to Autoramas's profile
121   - Then I should not see "Enter chat room" link
  120 + When I go to autoramas's profile
  121 + Then I should not see "Enter chat room" within "a"
122 122  
123 123 @selenium
124 124 Scenario: not see link to open chatroom of a community if xmpp_chat disabled
... ... @@ -127,8 +127,8 @@ Feature: chat
127 127 | autoramas | Autoramas |
128 128 And "Tame" is a member of "Autoramas"
129 129 And I am logged in as "tame"
130   - When I go to Autoramas's profile
131   - Then I should not see "Enter chat room" link
  130 + When I go to autoramas's profile
  131 + Then I should not see "Enter chat room" within "a"
132 132  
133 133 @selenium
134 134 Scenario: open chatroom of a community in a new window
... ... @@ -138,7 +138,7 @@ Feature: chat
138 138 | autoramas | Autoramas |
139 139 And "Tame" is a member of "Autoramas"
140 140 And I am logged in as "tame"
141   - When I go to Autoramas's profile
  141 + When I go to autoramas's profile
142 142 And I follow "Enter chat room"
143 143 And I select window "noosfero_chat"
144 144 Then I should see "Chat - Colivre.net - Friends online (0)"
... ...
features/clickable_images.feature
... ... @@ -22,7 +22,7 @@ Feature: clickable images
22 22 | owner | name | image | dimensions |
23 23 | booking | real | rails.png | 50x64 |
24 24 When I go to /booking/real
25   - Then I should not see "Zoom in"
  25 + Then "Zoom in" should not be visible within "a#zoomify-image"
26 26  
27 27 @selenium
28 28 Scenario: not show link if image does not have dimensions set
... ... @@ -30,9 +30,9 @@ Feature: clickable images
30 30 | owner | name | image |
31 31 | booking | not set | rails.png |
32 32 When I go to /booking/not-set
33   - Then I should not see "Zoom in"
  33 + Then "Zoom in" should not be visible within "a#zoomify-image"
34 34  
35   - @selenium
  35 + @selenium-fixme
36 36 Scenario: copy style from image
37 37 Given the following article with image
38 38 | owner | name | image | style | dimensions |
... ... @@ -40,11 +40,11 @@ Feature: clickable images
40 40 When I go to /booking/with-style
41 41 Then "zoomable-image" should be right aligned
42 42  
43   - @selenium
  43 + @selenium-fixme
44 44 Scenario: zoom image
45 45 Given the following article with image
46 46 | owner | name | image | dimensions |
47 47 | booking | zoom | rails.png | 25x32 |
48 48 When I go to /booking/zoom
49   - And I follow "Zoom in"
50   - Then the "#fancybox-wrap" should be visible
  49 + And I follow "Zoom in" within "a#zoomify-image"
  50 + Then I should see "fancybox-wrap"
... ...
features/comment.feature
... ... @@ -14,19 +14,23 @@ Feature: comment
14 14 | article | author | title | body |
15 15 | article with comment | booking | hi | how are you? |
16 16 | article with comment | booking | hello | i am fine |
  17 + And feature "captcha_for_logged_users" is disabled on environment
  18 + And I am logged in as "booking"
17 19  
18 20 Scenario: not post a comment without javascript
19 21 Given I am on /booking/article-to-comment
20   - And I fill in "Name" with "Joey Ramone"
21   - And I fill in "e-mail" with "joey@ramones.com"
  22 + And I follow "Post a comment"
22 23 And I fill in "Title" with "Hey ho, let's go!"
23 24 And I fill in "Enter your comment" with "Hey ho, let's go!"
24 25 When I press "Post comment"
25 26 Then I should not see "Hey ho, let's go"
26 27  
27   - @selenium
  28 + # This test requires some way to overcome the captcha with unauthenticated
  29 + # user.
  30 + @selenium-fixme
28 31 Scenario: post a comment while not authenticated
29 32 Given I am on /booking/article-to-comment
  33 + And I follow "Post a comment"
30 34 And I fill in "Name" with "Joey Ramone"
31 35 And I fill in "e-mail" with "joey@ramones.com"
32 36 And I fill in "Title" with "Hey ho, let's go!"
... ... @@ -36,8 +40,8 @@ Feature: comment
36 40  
37 41 @selenium
38 42 Scenario: post comment while authenticated
39   - Given I am logged in as "booking"
40   - And I am on /booking/article-to-comment
  43 + Given I am on /booking/article-to-comment
  44 + And I follow "Post a comment"
41 45 And I fill in "Title" with "Hey ho, let's go!"
42 46 And I fill in "Enter your comment" with "Hey ho, let's go!"
43 47 When I press "Post comment"
... ... @@ -48,8 +52,8 @@ Feature: comment
48 52 Given the following files
49 53 | owner | file | mime |
50 54 | booking | rails.png | image/png |
51   - Given I am logged in as "booking"
52 55 And I am on /booking/rails.png?view=true
  56 + And I follow "Post a comment"
53 57 And I fill in "Title" with "Hey ho, let's go!"
54 58 And I fill in "Enter your comment" with "Hey ho, let's go!"
55 59 When I press "Post comment"
... ... @@ -57,35 +61,34 @@ Feature: comment
57 61  
58 62 @selenium
59 63 Scenario: show error messages when make a blank comment
60   - Given I am logged in as "booking"
61   - And I am on /booking/article-to-comment
  64 + Given I am on /booking/article-to-comment
  65 + And I follow "Post a comment"
62 66 When I press "Post comment"
63   - Then I should see "Title can't be blank"
64   - And I should see "Body can't be blank"
  67 + Then I should see "Body can't be blank"
65 68  
66   - @selenium
  69 + @selenium-fixme
67 70 Scenario: disable post comment button
68 71 Given I am on /booking/article-to-comment
69   - And I fill in "Name" with "Joey Ramone"
70   - And I fill in "e-mail" with "joey@ramones.com"
  72 + And I follow "Post a comment"
71 73 And I fill in "Title" with "Hey ho, let's go!"
72 74 And I fill in "Enter your comment" with "Hey ho, let's go!"
73 75 When I press "Post comment"
74   - Then the "value.Post comment" button should not be enabled
75   - And I should see "Hey ho, let's go"
  76 +# Implement these steps...
  77 +# Then "Post comment" button should not be enabled
  78 +# And I should see "Hey ho, let's go"
76 79  
77 80 @selenium
78 81 Scenario: render comment form and go to bottom
79 82 Given I am on /booking/article-with-comment
80   - When I follow "Post a comment" within ".post-comment-button"
81   - Then I should see "Enter your comment" within "div#page-comment-form div.post_comment_box.opened"
82   - And I should be exactly on /booking/article-with-comment
83   - And I should be moved to anchor "comment_form"
  83 + When I follow "Post a comment"
  84 + Then I should see "Enter your comment"
  85 + And I should be on /booking/article-with-comment
84 86  
85 87 @selenium
86 88 Scenario: keep comments field filled while trying to do a comment
87 89 Given I am on /booking/article-with-comment
88   - And I fill in "Name" with "Joey Ramone"
  90 + And I follow "Post a comment"
  91 + And I fill in "Title" with "Joey Ramone"
89 92 When I press "Post comment"
90   - Then the "Name" field should contain "Joey Ramone"
91   - And I should see "errors prohibited"
  93 + Then the "Title" field should contain "Joey Ramone"
  94 + And I should see "Body can't be blank"
... ...
features/comment_reply.feature
... ... @@ -25,7 +25,7 @@ Feature: comment
25 25 Then I should not see "Enter your comment" within "div.comment-balloon"
26 26 And I should see "Reply" within "div.comment-balloon"
27 27  
28   - @selenium
  28 + @selenium-fixme
29 29 Scenario: show error messages when make a blank comment reply
30 30 Given I am logged in as "booking"
31 31 And I go to /booking/article-to-comment
... ... @@ -51,9 +51,9 @@ Feature: comment
51 51 Given I am on /booking/article-to-comment
52 52 When I follow "Reply" within ".comment-balloon"
53 53 And I follow "Cancel" within ".comment-balloon"
54   - Then I should see "Enter your comment" within "div.comment_reply.closed"
  54 + Then I should not see "Enter your comment" within "div.comment_reply.closed"
55 55  
56   - @selenium
  56 + @selenium-fixme
57 57 Scenario: not render same reply form twice
58 58 Given I am on /booking/article-to-comment
59 59 When I follow "Reply" within ".comment-balloon"
... ... @@ -62,7 +62,7 @@ Feature: comment
62 62 Then there should be 1 "comment_form" within "comment_reply"
63 63 And I should see "Enter your comment" within "div.comment_reply.opened"
64 64  
65   - @selenium
  65 + @selenium-fixme
66 66 Scenario: reply a comment
67 67 Given I go to /booking/another-article
68 68 And I follow "Reply" within ".comment-balloon"
... ... @@ -74,7 +74,7 @@ Feature: comment
74 74 Then I should see "Hey ho, let's go" within "ul.comment-replies"
75 75 And there should be 1 "comment-replies" within "article-comment"
76 76  
77   - @selenium
  77 + @selenium-fixme
78 78 Scenario: redirect to right place after reply a picture comment
79 79 Given the following files
80 80 | owner | file | mime |
... ...
features/contact.feature
... ... @@ -14,8 +14,8 @@ In order to ask questions and solve problems
14 14  
15 15 @selenium
16 16 Scenario: without states
17   - Given I am on Sample Community's homepage
18   - When I follow "Send an e-mail" and wait
  17 + Given I am on sample-community's homepage
  18 + When I follow "Send an e-mail"
19 19 Then I should not see "City and state"
20 20  
21 21 @selenium
... ... @@ -23,7 +23,6 @@ In order to ask questions and solve problems
23 23 Given the following states
24 24 | name |
25 25 | Bahia |
26   - And I am on Sample Community's homepage
27   - When I follow "Send an e-mail" and wait
  26 + And I am on sample-community's homepage
  27 + When I follow "Send an e-mail"
28 28 Then I should see "City and state"
29   -
... ...
features/create_community.feature
... ... @@ -11,7 +11,7 @@ Feature: create community
11 11 Scenario: a user creates a community
12 12 Given I am logged in as "joaosilva"
13 13 And feature "admin_must_approve_new_communities" is disabled on environment
14   - And I go to the Control panel
  14 + And I go to joaosilva's control panel
15 15 And I follow "Manage my groups"
16 16 When I follow "Create a new community"
17 17 And I fill in "Name" with "Fancy community"
... ... @@ -22,7 +22,7 @@ Feature: create community
22 22 Scenario: a user creates a community when environment moderates it
23 23 Given I am logged in as "joaosilva"
24 24 And feature "admin_must_approve_new_communities" is enabled on environment
25   - When I go to the Control panel
  25 + And I go to joaosilva's control panel
26 26 And I follow "Manage my groups"
27 27 And I follow "Create a new community"
28 28 And I fill in "Name" with "Community for moderation"
... ... @@ -32,7 +32,7 @@ Feature: create community
32 32 Scenario: a user tries to create a community without a name
33 33 Given I am logged in as "joaosilva"
34 34 And feature "admin_must_approve_new_communities" is disabled on environment
35   - And I go to the Control panel
  35 + And I go to joaosilva's control panel
36 36 And I follow "Manage my groups"
37 37 When I follow "Create a new community"
38 38 And I press "Create"
... ... @@ -42,20 +42,20 @@ Feature: create community
42 42 Given I am logged in as admin
43 43 And feature "admin_must_approve_new_communities" is enabled on environment
44 44 When I create community "Community for approval"
45   - And I go to the Control panel
  45 + And I go to admin_user's control panel
46 46 Then I should see "admin_user wants to create community Community for approval"
47 47  
48 48 Scenario: environment admin accepts new community task
49 49 Given I am logged in as admin
50 50 And feature "admin_must_approve_new_communities" is enabled on environment
51 51 When I create community "Community for approval"
52   - And I go to the Control panel
  52 + And I go to admin_user's control panel
53 53 And I follow "Process requests"
54 54 And I should see "admin_user wants to create community Community for approval"
55 55 And I choose "Accept"
56 56 When I press "Apply!"
57 57 Then I should not see "admin_user wants to create community Community for approval"
58   - When I go to the Control panel
  58 + And I go to admin_user's control panel
59 59 And I follow "Manage my groups"
60 60 Then I should see "Community for approval"
61 61  
... ... @@ -63,13 +63,13 @@ Feature: create community
63 63 Given I am logged in as admin
64 64 And feature "admin_must_approve_new_communities" is enabled on environment
65 65 When I create community "Community for approval"
66   - And I go to the Control panel
  66 + And I go to admin_user's control panel
67 67 And I follow "Process requests"
68 68 And I should see "admin_user wants to create community Community for approval"
69 69 And I choose "Reject"
70 70 When I press "Apply!"
71 71 Then I should not see "admin_user wants to create community Community for approval"
72   - When I go to the Control panel
  72 + And I go to admin_user's control panel
73 73 And I follow "Manage my groups"
74 74 Then I should not see "Community for approval"
75 75  
... ... @@ -78,7 +78,7 @@ Feature: create community
78 78 And feature "admin_must_approve_new_communities" is enabled on environment
79 79 When I create community "Community for approval"
80 80 And I approve community "Community for approval"
81   - When I go to the Control panel
  81 + And I go to admin_user's control panel
82 82 And I follow "Manage my groups"
83 83 Then I should see "Community for approval"
84 84  
... ... @@ -87,6 +87,6 @@ Feature: create community
87 87 And feature "admin_must_approve_new_communities" is enabled on environment
88 88 When I create community "Community for approval"
89 89 And I reject community "Community for approval"
90   - When I go to the Control panel
  90 + And I go to admin_user's control panel
91 91 And I follow "Manage my groups"
92 92 Then I should not see "Community for approval"
... ...
features/delete_profile.feature
... ... @@ -13,9 +13,10 @@ Feature: delete profile
13 13 | sample-community | Sample Community |
14 14 And "Maria Silva" is a member of "Sample Community"
15 15  
  16 + @selenium
16 17 Scenario: deleting profile
17 18 Given I am logged in as "joaosilva"
18   - And I am on Joao Silva's control panel
  19 + And I am on joaosilva's control panel
19 20 And I follow "Edit Profile"
20 21 And I follow "Delete profile"
21 22 Then I should see "Are you sure you want to delete this profile?"
... ... @@ -31,24 +32,25 @@ Feature: delete profile
31 32  
32 33 Scenario: giving up of deleting profile
33 34 Given I am logged in as "joaosilva"
34   - And I am on Joao Silva's control panel
  35 + And I am on joaosilva's control panel
35 36 And I follow "Edit Profile"
36 37 And I follow "Delete profile"
37 38 Then I should see "Are you sure you want to delete this profile?"
38 39 When I follow "No, I gave up"
39   - Then I should be on Joao Silva's profile
  40 + Then I should be on joaosilva's profile
40 41  
41 42 Scenario: community admin can see link to delete profile
42 43 Given "Joao Silva" is admin of "Sample Community"
43 44 And I am logged in as "joaosilva"
44   - And I am on Sample Community's control panel
  45 + And I am on sample-community's control panel
45 46 When I follow "Community Info and settings"
46 47 Then I should see "Delete profile"
47 48  
  49 + @selenium
48 50 Scenario: community admin deletes the community
49 51 Given "Joao Silva" is admin of "Sample Community"
50 52 And I am logged in as "joaosilva"
51   - And I am on Sample Community's control panel
  53 + And I am on sample-community's control panel
52 54 And I follow "Community Info and settings"
53 55 And I follow "Delete profile"
54 56 Then I should see "Are you sure you want to delete this profile?"
... ... @@ -69,17 +71,18 @@ Feature: delete profile
69 71 | sample-enterprise | Sample Enterprise |
70 72 And "Joao Silva" is admin of "Sample Enterprise"
71 73 And I am logged in as "joaosilva"
72   - And I am on Sample Enterprise's control panel
  74 + And I am on sample-enterprise's control panel
73 75 When I follow "Enterprise Info and settings"
74 76 Then I should see "Delete profile"
75 77  
  78 + @selenium
76 79 Scenario: enterprise admin deletes the enterprise
77 80 Given the following enterprise
78 81 | identifier | name |
79 82 | sample-enterprise | Sample Enterprise |
80 83 And "Joao Silva" is admin of "Sample Enterprise"
81 84 And I am logged in as "joaosilva"
82   - And I am on Sample Enterprise's control panel
  85 + And I am on sample-enterprise's control panel
83 86 When I follow "Enterprise Info and settings"
84 87 And I follow "Delete profile"
85 88 Then I should see "Are you sure you want to delete this profile?"
... ... @@ -98,9 +101,10 @@ Feature: delete profile
98 101 And I go to /myprofile/sample-enterprise/profile_editor/destroy_profile
99 102 Then I should see "Access denied"
100 103  
  104 + @selenium
101 105 Scenario: environment admin deletes profile
102 106 Given I am logged in as admin
103   - And I am on Joao Silva's control panel
  107 + And I am on joaosilva's control panel
104 108 And I follow "Edit Profile"
105 109 And I follow "Delete profile"
106 110 Then I should see "Are you sure you want to delete this profile?"
... ...
features/edit_article.feature
... ... @@ -13,17 +13,17 @@ Feature: edit article
13 13 And I am logged in as "joaosilva"
14 14  
15 15 Scenario: create a folder
16   - Given I am on Joao Silva's control panel
  16 + Given I am on joaosilva's control panel
17 17 And I follow "Manage Content"
18 18 And I follow "New content"
19 19 When I follow "Folder"
20 20 And I fill in "Title" with "My Folder"
21 21 And I press "Save"
22   - And I go to Joao Silva's control panel
  22 + And I go to joaosilva's control panel
23 23 Then I should see "My Folder"
24 24  
25 25 Scenario: redirect to the created folder
26   - Given I am on Joao Silva's control panel
  26 + Given I am on joaosilva's control panel
27 27 And I follow "Manage Content"
28 28 And I follow "New content"
29 29 When I follow "Folder"
... ... @@ -33,29 +33,29 @@ Feature: edit article
33 33 And I should be on /joaosilva/my-folder
34 34  
35 35 Scenario: cancel button back to cms
36   - Given I go to the Control panel
  36 + Given I am on joaosilva's control panel
37 37 And I follow "Manage Content"
38 38 And I follow "New content"
39 39 And I follow "Folder"
40 40 When I follow "Cancel" within ".main-block"
41   - Then I should be on Joao Silva's cms
  41 + Then I should be on joaosilva's cms
42 42  
43 43 Scenario: display tag list field when creating event
44   - Given I go to the Control panel
  44 + Given I am on joaosilva's control panel
45 45 And I follow "Manage Content"
46 46 And I follow "New content"
47 47 When I follow "Event"
48 48 Then I should see "Tag list"
49 49  
50 50 Scenario: display tag list field when creating folder
51   - Given I go to the Control panel
  51 + Given I am on joaosilva's control panel
52 52 And I follow "Manage Content"
53 53 And I follow "New content"
54 54 When I follow "Folder"
55 55 Then I should see "Tag list"
56 56  
57 57 Scenario: create new article with tags
58   - Given I go to the Control panel
  58 + Given I am on joaosilva's control panel
59 59 And I follow "Manage Content"
60 60 And I follow "New content"
61 61 When I follow "Text article with Textile markup language"
... ... @@ -68,7 +68,7 @@ Feature: edit article
68 68 And I should see "bug" within "#article-tags a:last"
69 69  
70 70 Scenario: redirect to the created article
71   - Given I am on Joao Silva's control panel
  71 + Given I am on joaosilva's control panel
72 72 And I follow "Manage Content"
73 73 When I follow "New content"
74 74 When I follow "Text article with visual editor"
... ... @@ -79,62 +79,62 @@ Feature: edit article
79 79  
80 80 @selenium
81 81 Scenario: edit an article
82   - Given I am on Joao Silva's sitemap
83   - When I follow "Save the whales" and wait
84   - And I follow "Edit" and wait
  82 + Given I am on joaosilva's sitemap
  83 + When I follow "Save the whales"
  84 + And I follow "Edit"
85 85 And I fill in "Title" with "My Article edited"
86   - And I press "Save" and wait
  86 + And I press "Save"
87 87 Then I should be on /joaosilva/my-article-edited
88 88  
89 89 @selenium
90 90 Scenario: cancel button back to article when edit
91   - Given I am on Joao Silva's sitemap
92   - When I follow "Save the whales" and wait
93   - And I follow "Edit" and wait
94   - And I follow "Cancel" and wait
  91 + Given I am on joaosilva's sitemap
  92 + When I follow "Save the whales"
  93 + And I follow "Edit" within "#article-actions"
  94 + And I follow "Cancel"
95 95 Then I should be on /joaosilva/save-the-whales
96 96  
97 97 @selenium
98 98 Scenario: create an article inside a folder
99   - Given I am on Joao Silva's control panel
  99 + Given I am on joaosilva's control panel
100 100 When I follow "Manage Content"
101 101 And I follow "New content"
102   - And I follow "Folder" and wait
  102 + And I follow "Folder"
103 103 And I fill in "Title" with "My Folder"
104   - And I press "Save" and wait
  104 + And I press "Save"
105 105 Then I should be on /joaosilva/my-folder
106 106 When I follow "New article"
107   - And I follow "Text article with visual editor" and wait
  107 + And I follow "Text article with visual editor"
108 108 And I fill in "Title" with "My Article"
109   - And I press "Save" and wait
  109 + And I press "Save"
110 110 Then I should see "My Article"
111 111 And I should be on /joaosilva/my-folder/my-article
112 112  
113 113 @selenium
114 114 Scenario: cancel button back to folder after giving up creating
115   - Given I am on Joao Silva's control panel
  115 + Given I am on joaosilva's control panel
116 116 When I follow "Manage Content"
117 117 And I follow "New content"
118   - And I follow "Folder" and wait
  118 + And I follow "Folder"
119 119 And I fill in "Title" with "My Folder"
120   - And I press "Save" and wait
  120 + And I press "Save"
121 121 Then I should be on /joaosilva/my-folder
122 122 When I follow "New article"
123   - And I follow "Text article with visual editor" and wait
124   - And I follow "Cancel" within ".no-boxes" and wait
  123 + And I follow "Text article with visual editor"
  124 + And I follow "Cancel" within ".no-boxes"
125 125 Then I should be on /joaosilva/my-folder
126 126  
127 127 @selenium
128 128 Scenario: save and continue
129 129 Given I am on /joaosilva/save-the-whales
130   - And I follow "Edit" and wait
  130 + And I follow "Edit"
131 131 When I fill in "Text" with "new text"
132 132 And I press "Save and continue"
133 133 Then the "Text" field should contain "new text"
134 134 And I should be on "Save the whales" edit page
135 135  
136 136 Scenario: save and continue when creating a new article
137   - Given I am on Joao Silva's control panel
  137 + Given I am on joaosilva's control panel
138 138 When I follow "Manage Content"
139 139 And I follow "New content"
140 140 And I follow "Text article with visual editor"
... ... @@ -147,16 +147,16 @@ Feature: edit article
147 147  
148 148 @selenium
149 149 Scenario: add a translation to an article
150   - Given I am on Joao Silva's sitemap
  150 + Given I am on joaosilva's sitemap
151 151 And I follow "Save the whales"
152 152 Then I should not see "Add translation"
153   - And I follow "Edit" and wait
  153 + And I follow "Edit"
154 154 And I select "English" from "Language"
155   - Then I press "Save" and wait
156   - And I follow "Add translation" and wait
  155 + Then I press "Save"
  156 + And I follow "Add translation"
157 157 And I fill in "Title" with "Mi neuvo artículo"
158 158 And I select "Español" from "Language"
159   - When I press "Save" and wait
  159 + When I press "Save"
160 160 Then I should be on /joaosilva/mi-neuvo-articulo
161 161 And I should see "Translations"
162 162  
... ... @@ -165,13 +165,13 @@ Feature: edit article
165 165 Given the following articles
166 166 | owner | name | language |
167 167 | joaosilva | Article in English | en |
168   - And I am on Joao Silva's sitemap
169   - When I follow "Article in English" and wait
170   - And I follow "Add translation" and wait
  168 + And I am on joaosilva's sitemap
  169 + When I follow "Article in English"
  170 + And I follow "Add translation"
171 171 And I fill in "Title" with "Article in Portuguese"
172   - And I press "Save" and wait
  172 + And I press "Save"
173 173 Then I should see "Language must be choosen"
174 174 When I select "Português" from "Language"
175   - And I press "Save" and wait
  175 + And I press "Save"
176 176 Then I should not see "Language must be choosen"
177 177 And I should be on /joaosilva/article-in-portuguese
... ...
features/edit_block_of_links.feature
... ... @@ -12,7 +12,7 @@ Feature: edit_block_of_links
12 12 | eddievedder | LinkListBlock |
13 13 And I am logged in as "eddievedder"
14 14  
15   - @selenium
  15 + @selenium-fixme
16 16 Scenario: show the icon selector
17 17 Given I follow "Edit sideboxes"
18 18 And I follow "Edit" within ".link-list-block"
... ...
features/edit_environment_templates.feature
... ... @@ -4,50 +4,46 @@ Feature: edit environment templates
4 4  
5 5 Background:
6 6 Given that the default environment have all profile templates
  7 + And I am logged in as admin
  8 + And I am on the environment control panel
7 9  
  10 + @selenium
8 11 Scenario: See links to edit all templates
9   - Given I am logged in as admin
10   - When I follow "Administration"
11   - And I follow "Profile templates"
12   - Then I should see "Person template" link
13   - And I should see "Community template" link
14   - And I should see "Enterprise template" link
15   - And I should see "Inactive Enterprise template" link
  12 + Given I follow "Profile templates"
  13 + Then I should see "Person template"
  14 + And I should see "Community template"
  15 + And I should see "Enterprise template"
  16 + And I should see "Inactive Enterprise template"
16 17  
  18 + @selenium
17 19 Scenario: Go to control panel of person template
18   - Given I am logged in as admin
19   - When I follow "Administration"
20   - And I follow "Profile templates"
  20 + Given I follow "Profile templates"
21 21 And I follow "Person template"
22   - Then I should be on Person template's control panel
  22 + Then I should be on colivre.net_person_template's control panel
23 23  
  24 + @selenium
24 25 Scenario: Go to control panel of enterprise template
25   - Given I am logged in as admin
26   - When I follow "Administration"
27   - And I follow "Profile templates"
  26 + Given I follow "Profile templates"
28 27 And I follow "Enterprise template"
29   - Then I should be on Enterprise template's control panel
  28 + Then I should be on colivre.net_enterprise_template's control panel
30 29  
  30 + @selenium
31 31 Scenario: Go to control panel of inactive enterprise template
32   - Given I am logged in as admin
33   - When I follow "Administration"
34   - And I follow "Profile templates"
35   - And I follow "Inactive enterprise template"
36   - Then I should be on Inactive Enterprise template's control panel
  32 + Given I follow "Profile templates"
  33 + And I follow "Inactive Enterprise template"
  34 + Then I should be on colivre.net_inactive_enterprise_template's control panel
37 35  
  36 + @selenium
38 37 Scenario: Go to control panel of community template
39   - Given I am logged in as admin
40   - When I follow "Administration"
41   - And I follow "Profile templates"
42   - And I follow "Community template"
43   - Then I should be on Community template's control panel
  38 + Given I follow "Profile templates"
  39 + When I follow "Community template"
  40 + Then I should be on colivre.net_community_template's control panel
44 41  
  42 + @selenium
45 43 Scenario: Not see link to edit an unexistent template
46   - Given that the default environment have no Inactive Enterprise template
47   - And I am logged in as admin
48   - When I follow "Administration"
49   - And I follow "Profile templates"
50   - Then I should see "Person template" link
51   - And I should see "Community template" link
52   - And I should see "Enterprise template" link
53   - And I should not see "Inactive enterprise template" link
  44 + Given I follow "Profile templates"
  45 + And that the default environment have no Inactive Enterprise template
  46 + Then I should see "Person template"
  47 + And I should see "Community template"
  48 + And I should see "Enterprise template"
  49 + And I should not see "Inactive enterprise template"
... ...
features/edit_language_block.feature
... ... @@ -15,25 +15,25 @@ Feature: edit language of block
15 15 Scenario: display in all languages
16 16 Given I go to edit ArticleBlock of joaosilva
17 17 And I fill in "Custom title for this block" with "Block displayed"
18   - And I select "all languages"
  18 + And I select "all languages" from "Show for"
19 19 And I press "Save"
20   - When I go to Jose Silva's homepage
  20 + When I go to joaosilva's homepage
21 21 Then I should see "Block displayed"
22 22  
23 23 Scenario: display in the selected language
24 24 Given I go to edit LinkListBlock of joaosilva
25 25 And I fill in "Custom title for this block" with "Block displayed"
26   - And I select "English"
  26 + And I select "English" from "Show for"
27 27 And I press "Save"
28 28 And my browser prefers English
29   - When I go to Jose Silva's homepage
  29 + When I go to joaosilva's homepage
30 30 Then I should see "Block displayed"
31 31  
32 32 Scenario: not display in a not selected language
33 33 Given I go to edit LinkListBlock of joaosilva
34 34 And I fill in "Custom title for this block" with "Block not displayed"
35   - And I select "English"
  35 + And I select "English" from "Show for"
36 36 And I press "Save"
37 37 And my browser prefers Portuguese
38   - When I go to Jose Silva's homepage
  38 + When I go to joaosilva's homepage
39 39 Then I should not see "Block displayed"
... ...
features/edit_profile.feature
... ... @@ -12,8 +12,8 @@ Feature: edit profile
12 12 | birth_date |
13 13 When I go to joao's control panel
14 14 And I follow "Edit Profile"
15   - And I select "November"
16   - And I select "15"
  15 + And I select "November" from "profile_data_birth_date_2i"
  16 + And I select "15" from "profile_data_birth_date_3i"
17 17 And I press "Save"
18 18 Then I should see "Birth date is invalid"
19 19 And I should not see "Birth date can't be blank"
... ... @@ -24,8 +24,8 @@ Feature: edit profile
24 24 | birth_date |
25 25 When I go to joao's control panel
26 26 And I follow "Edit Profile"
27   - And I select "November"
28   - And I select "15"
  27 + And I select "November" from "profile_data_birth_date_2i"
  28 + And I select "15" from "profile_data_birth_date_3i"
29 29 And I press "Save"
30 30 Then I should see "Birth date is invalid"
31 31 And I should not see "Birth date can't be blank"
... ... @@ -36,9 +36,9 @@ Feature: edit profile
36 36 | birth_date |
37 37 When I go to joao's control panel
38 38 And I follow "Edit Profile"
39   - And I select "November"
40   - And I select "15"
41   - And I select "1980"
  39 + And I select "November" from "profile_data_birth_date_2i"
  40 + And I select "15" from "profile_data_birth_date_3i"
  41 + And I select "1980" from "profile_data_birth_date_1i"
42 42 And I press "Save"
43 43 Then I should not see "Birth date is invalid"
44 44 And I should not see "Birth date is mandatory"
... ... @@ -49,9 +49,9 @@ Feature: edit profile
49 49 | birth_date |
50 50 When I go to joao's control panel
51 51 And I follow "Edit Profile"
52   - And I select "November"
53   - And I select "15"
54   - And I select "1980"
  52 + And I select "November" from "profile_data_birth_date_2i"
  53 + And I select "15" from "profile_data_birth_date_3i"
  54 + And I select "1980" from "profile_data_birth_date_1i"
55 55 And I press "Save"
56 56 Then I should not see "Birth date is invalid"
57 57 And I should not see "Birth date is mandatory"
... ... @@ -62,11 +62,11 @@ Feature: edit profile
62 62 | identifier | name | owner |
63 63 | o-rappa | O Rappa | joao |
64 64 And feature "enable_organization_url_change" is enabled on environment
65   - When I go to O Rappa's control panel
66   - And I follow "Community Info and settings" and wait
67   - Then the "#identifier-change-confirmation" should not be visible
  65 + When I go to o-rappa's control panel
  66 + And I follow "Community Info and settings"
  67 + And I should not see "identifier-change-confirmation"
68 68 When I fill in "Address" with "banda-o-rappa"
69   - Then the "#identifier-change-confirmation" should be visible
  69 + And I should see "identifier-change-confirmation"
70 70  
71 71 @selenium
72 72 Scenario: Confirm url change
... ... @@ -74,12 +74,12 @@ Feature: edit profile
74 74 | identifier | name | owner |
75 75 | o-rappa | O Rappa | joao |
76 76 And feature "enable_organization_url_change" is enabled on environment
77   - When I go to O Rappa's control panel
78   - And I follow "Community Info and settings" and wait
  77 + When I go to o-rappa's control panel
  78 + And I follow "Community Info and settings"
79 79 When I fill in "Address" with "banda-o-rappa"
80   - Then the "#identifier-change-confirmation" should be visible
  80 + Then I should see "identifier-change-confirmation"
81 81 When I follow "Yes"
82   - Then the "#identifier-change-confirmation" should not be visible
  82 + Then "identifier-change-confirmation" should not be visible within "profile-identifier-formitem"
83 83  
84 84 @selenium
85 85 Scenario: Cancel url change
... ... @@ -87,9 +87,9 @@ Feature: edit profile
87 87 | identifier | name | owner |
88 88 | o-rappa | O Rappa | joao |
89 89 And feature "enable_organization_url_change" is enabled on environment
90   - When I go to O Rappa's control panel
91   - And I follow "Community Info and settings" and wait
  90 + When I go to o-rappa's control panel
  91 + And I follow "Community Info and settings"
92 92 When I fill in "Address" with "banda-o-rappa"
93   - Then the "#identifier-change-confirmation" should be visible
  93 + Then I should see "identifier-change-confirmation"
94 94 When I follow "No"
95   - Then the "#identifier-change-confirmation" should not be visible
  95 + Then "identifier-change-confirmation" should not be visible within "profile-identifier-formitem"
... ...
features/environment_name.feature
... ... @@ -3,6 +3,7 @@ Feature: setting environment name
3 3 I want to change the name of the environment
4 4 So that it appears in the window's title bar
5 5  
  6 + @selenium-fixme
6 7 Scenario: setting environment name through administration panel
7 8 Given I am logged in as admin
8 9 When I follow "Administration"
... ...
features/events.feature
... ... @@ -184,7 +184,7 @@ Feature: events
184 184 And "josesilva" is a member of "Sample Community"
185 185 And I go to josesilva's control panel
186 186 And I follow "Manage Content"
187   - And I follow "Another Conference" and wait
  187 + And I follow "Another Conference"
188 188 And I follow "Spread"
189 189 And I check "Sample Community"
190 190 And I press "Spread this"
... ... @@ -213,15 +213,15 @@ Feature: events
213 213 And I am on josesilva's Event creation
214 214 Then I should see "Lead"
215 215  
216   - @selenium
  216 + @selenium-fixme
217 217 Scenario: events lead should be shown on blogs with short format
218 218 Given I am logged in as "josesilva"
219 219 And I am on josesilva's control panel
220   - And I follow "Configure blog" and wait
  220 + And I follow "Configure blog"
221 221 And I select "First paragraph" from "How to display posts:"
222 222 And I press "Save"
223 223 And I follow "New post"
224   - And I follow "A calendar event" and wait
  224 + And I follow "A calendar event"
225 225 And I fill in "Title" with "Leaded event"
226 226 And I type "This is the abstract." in TinyMCE field "article_abstract"
227 227 And I type "This is the real text." in TinyMCE field "article_body"
... ...
features/export_users.feature
... ... @@ -9,15 +9,13 @@ Feature: export users
9 9  
10 10 Scenario: Export users as XML
11 11 Given I am logged in as admin
12   - When I follow "Administration"
13   - And I follow "Users"
  12 + When I go to /admin/users
14 13 And I follow "[XML]"
15 14 Then I should see "ultraje"
16 15  
17 16 Scenario: Export users as CSV
18 17 Given I am logged in as admin
19   - When I follow "Administration"
20   - And I follow "Users"
  18 + When I go to /admin/users
21 19 And I follow "[CSV]"
22 20 Then I should see "name;email"
23 21 And I should see "ultraje"
... ...
features/featured_products_block.feature
... ... @@ -23,7 +23,7 @@ Feature: featured_products_block
23 23 | redemoinho | automobile | Moto | Very long description of and auto-mobile moto to be truncated | true |
24 24 And I am logged in as "eddievedder"
25 25  
26   - @selenium
  26 + @selenium-fixme
27 27 Scenario: select a product to be featured
28 28 And I follow "Manage my groups"
29 29 And I follow "Control panel of this group"
... ... @@ -35,7 +35,7 @@ Feature: featured_products_block
35 35 And I should not see "float_to_currency"
36 36 And I should not see "product_path"
37 37  
38   - @selenium
  38 + @selenium-fixme
39 39 Scenario: display block with long description
40 40 Given I follow "Manage my groups"
41 41 And I follow "Control panel of this group"
... ...
features/forum.feature
... ... @@ -10,18 +10,18 @@ Feature: forum
10 10 And "joaosilva" has no articles
11 11 And I am logged in as "joaosilva"
12 12  
13   - @selenium
  13 + @selenium @ignore-hidden-elements
14 14 Scenario: create a forum
15   - Given I am on Joao Silva's control panel
  15 + Given I am on joaosilva's control panel
16 16 And I follow "Manage Content"
17 17 And I follow "New content"
18   - When I follow "Forum" and wait
  18 + When I follow "Forum"
19 19 And I fill in "Title" with "My Forum"
20   - And I press "Save" and wait
  20 + And I press "Save"
21 21 Then I should see "Configure forum"
22 22  
23 23 Scenario: redirect to forum after create forum from cms
24   - Given I go to the Control panel
  24 + Given I go to joaosilva's control panel
25 25 And I follow "Manage Content"
26 26 And I follow "New content"
27 27 When I follow "Forum"
... ... @@ -30,13 +30,13 @@ Feature: forum
30 30 Then I should be on /joaosilva/forum-from-cms
31 31  
32 32 Scenario: create multiple forums
33   - Given I go to the Control panel
  33 + Given I go to joaosilva's control panel
34 34 And I follow "Manage Content"
35 35 And I follow "New content"
36 36 And I follow "Forum"
37 37 And I fill in "Title" with "Forum One"
38 38 And I press "Save"
39   - Then I go to the Control panel
  39 + Then I go to joaosilva's control panel
40 40 And I follow "Manage Content"
41 41 And I follow "New content"
42 42 And I follow "Forum"
... ... @@ -46,7 +46,7 @@ Feature: forum
46 46 And I should be on /joaosilva/forum-two
47 47  
48 48 Scenario: cancel button back to cms
49   - Given I go to the Control panel
  49 + Given I go to joaosilva's control panel
50 50 And I follow "Manage Content"
51 51 And I follow "New content"
52 52 And I follow "Forum"
... ... @@ -54,7 +54,7 @@ Feature: forum
54 54 Then I should be on /myprofile/joaosilva/cms
55 55  
56 56 Scenario: cancel button back to myprofile
57   - Given I go to the Control panel
  57 + Given I go to joaosilva's control panel
58 58 And I follow "Manage Content"
59 59 And I follow "New content"
60 60 And I follow "Forum"
... ... @@ -66,8 +66,8 @@ Feature: forum
66 66 Given the following forums
67 67 | owner | name |
68 68 | joaosilva | Forum One |
69   - And I visit "/joaosilva/forum-one" and wait
70   - When I follow "Configure forum" and wait
  69 + And I go to /joaosilva/forum-one
  70 + When I follow "Configure forum"
71 71 Then I should be on edit "Forum One" by joaosilva
72 72  
73 73 Scenario: last topic update by unautenticated user should not link
... ... @@ -94,4 +94,4 @@ Feature: forum
94 94 | article | author | title | body |
95 95 | Post one | joaosilva | Hi all | Hi all |
96 96 When I go to /joaosilva/forum
97   - Then I should see "Joao" linking to "http:///joaosilva"
  97 + Then I should see "Joao" linking to "http://localhost/joaosilva"
... ...
features/gallery_navigation.feature
... ... @@ -23,7 +23,7 @@ Feature: gallery_navigation
23 23 @selenium
24 24 Scenario: view next image when follow next link
25 25 Given I am on /marciopunk/my-gallery/other-pic.jpg?view=true
26   - When I follow "Next »" and wait
  26 + When I follow "Next »"
27 27 Then I should see "rails.png" within ".title"
28 28  
29 29 Scenario: not link to next when in last image
... ... @@ -38,7 +38,7 @@ Feature: gallery_navigation
38 38 @selenium
39 39 Scenario: view previous image when follow previous link
40 40 Given I am on /marciopunk/my-gallery/rails.png?view=true
41   - When I follow "« Previous" and wait
  41 + When I follow "« Previous"
42 42 Then I should see "other-pic.jpg" within ".title"
43 43  
44 44 Scenario: not link to previous when in first image
... ... @@ -68,11 +68,19 @@ Feature: gallery_navigation
68 68 When I follow "Go back to my-gallery"
69 69 Then I should be on /marciopunk/my-gallery
70 70  
  71 + # Looking for page title is problematic on selenium since it considers the
  72 + # title to be invibible. Checkout some information about this:
  73 + # * https://github.com/jnicklas/capybara/issues/863
  74 + # * https://github.com/jnicklas/capybara/pull/953
71 75 @selenium
72 76 Scenario: image title in window title
73 77 Given I am logged in as "marciopunk"
74   - When I visit "/marciopunk/other-gallery/rails.png?view=true" and wait
75   - And I follow "Edit" and wait
  78 + When I go to /marciopunk/other-gallery/rails.png?view=true
  79 + Then I should see "rails.png" within any "h1"
  80 +# And the page title should be "rails.png"
  81 + And I follow "Edit"
76 82 And I fill in "Title" with "Rails is cool"
77   - And I press "Save" and wait
78   - Then The page title should contain "Rails is cool"
  83 + And I press "Save"
  84 + When I go to /marciopunk/other-gallery/rails.png?view=true
  85 + Then I should see "Rails is cool" within any "h1"
  86 + #Then the page title should be "Rails is cool"
... ...
features/http_caching.feature
... ... @@ -35,13 +35,13 @@ Feature: HTTP caching
35 35 Then the response should be valid for 90 minutes
36 36  
37 37 Scenario: profile pages, default configuaration
38   - When I go to João Silva's homepage
  38 + When I go to joao's homepage
39 39 Then the response should be valid for 15 minutes
40 40  
41 41 Scenario: profile pages, custom configuration
42 42 Given the following environment configuration
43 43 | profile_cache_in_minutes | 90 |
44   - When I go to João Silva's homepage
  44 + When I go to joao's homepage
45 45 Then the response should be valid for 90 minutes
46 46  
47 47 Scenario: account controller should not be cached at all
... ... @@ -50,7 +50,7 @@ Feature: HTTP caching
50 50  
51 51 Scenario: profile administration
52 52 Given I am logged in as "joao"
53   - When I go to João Silva's control panel
  53 + When I go to joao's control panel
54 54 Then there must be no cache at all
55 55  
56 56 Scenario: environment administration
... ...
features/internationalization.feature
... ... @@ -28,6 +28,7 @@ Feature: internationalization
28 28 When I follow "Português"
29 29 Then the site should be in Portuguese
30 30  
  31 + @fixme
31 32 Scenario: language set by previous users
32 33 Given a user accessed in English before
33 34 And my browser prefers Portuguese
... ...
features/invitation.feature
... ... @@ -32,11 +32,13 @@ Feature: invitation
32 32 When I am on /profile/josesilva/invite/friends
33 33 Then I should see "Invite your friends"
34 34  
  35 + @selenium
35 36 Scenario: back to friends after invite friends
36 37 Given I am on /myprofile/josesilva/friends
37 38 And I follow "Invite people from my e-mail contacts"
38 39 And I press "Next"
39 40 And I fill in "manual_import_addresses" with "misfits@devil.doll"
  41 + And I follow "Personalize invitation mail"
40 42 And I fill in "mail_template" with "Follow this link <url>"
41 43 When I press "Invite my friends!"
42 44 Then I should be on /profile/josesilva/friends
... ... @@ -46,8 +48,7 @@ Feature: invitation
46 48 Then I should see "Invite your friends to join 26 Bsslines" link
47 49  
48 50 Scenario: not see link to invite members to community if has no rights
49   - Given I am not logged in
50   - And I am logged in as "josesantos"
  51 + Given I am logged in as "josesantos"
51 52 When I am on /profile/26-bsslines/members
52 53 Then I should not see "Invite your friends to join 26 Bsslines" link
53 54  
... ... @@ -65,8 +66,7 @@ Feature: invitation
65 66 Then I should not see "Invite your friends to join Beatles For Sale" link
66 67  
67 68 Scenario: deny access if user has no right to invite members
68   - Given I am not logged in
69   - And I am logged in as "josesantos"
  69 + Given I am logged in as "josesantos"
70 70 When I am on /profile/26-bsslines/invite/friends
71 71 Then I should see "Access denied"
72 72  
... ... @@ -74,93 +74,107 @@ Feature: invitation
74 74 Given I am on Beatles For Sale's members management
75 75 Then I should not see "Invite your friends to join Beatles For Sale" link
76 76  
  77 + @selenium
77 78 Scenario: back to members after invite friends to join a community
78 79 Given I am on 26 Bsslines's members management
79 80 And I follow "Invite your friends to join 26 Bsslines"
80 81 And I press "Next"
81 82 And I fill in "manual_import_addresses" with "misfits@devil.doll"
  83 + And I follow "Personalize invitation mail"
82 84 And I fill in "mail_template" with "Follow this link <url>"
83 85 When I press "Invite my friends!"
84 86 Then I should be on /profile/26-bsslines/members
85 87  
  88 + @selenium
86 89 Scenario: noosfero user receives a task when a user invites to join a community
87 90 Given I am on 26 Bsslines's members management
88 91 And I follow "Invite your friends to join 26 Bsslines"
89 92 And I press "Next"
90 93 And I fill in "manual_import_addresses" with "santos@invalid.br"
  94 + And I follow "Personalize invitation mail"
91 95 And I fill in "mail_template" with "Follow this link <url>"
92 96 And I press "Invite my friends!"
93 97 Given there are no pending jobs
94 98 When I am logged in as "josesantos"
95   - And I go to the Control panel
  99 + And I go to josesantos's control panel
96 100 And I should see "josesilva invited you to join 26 Bsslines."
97 101  
  102 + @selenium
98 103 Scenario: noosfero user accepts to join community
99 104 Given I invite email "santos@invalid.br" to join community "26 Bsslines"
100 105 And there are no pending jobs
101 106 When I am logged in as "josesantos"
102   - And I go to the Control panel
  107 + And I go to josesantos's control panel
103 108 And I follow "Process requests"
104 109 And I should see "josesilva invited you to join 26 Bsslines."
105 110 And I choose "Accept"
106 111 When I press "Apply!"
107 112 Then I should not see "josesilva invited you to join 26 Bsslines."
108   - When I go to the Control panel
  113 + When I go to josesantos's control panel
109 114 And I follow "Manage my groups"
110 115 Then I should see "26 Bsslines"
111 116  
  117 + @selenium
112 118 Scenario: noosfero user rejects to join community
113 119 Given I invite email "santos@invalid.br" to join community "26 Bsslines"
114 120 And there are no pending jobs
115 121 When I am logged in as "josesantos"
116   - And I go to the Control panel
  122 + And I go to josesantos's control panel
117 123 And I follow "Process requests"
118 124 And I should see "josesilva invited you to join 26 Bsslines."
119 125 And I choose "Reject"
120 126 When I press "Apply!"
121 127 Then I should not see "josesilva invited you to join 26 Bsslines."
122   - When I go to the Control panel
  128 + And I go to josesantos's control panel
123 129 And I follow "Manage my groups"
124 130 Then I should not see "26 Bsslines"
125 131  
  132 + @selenium
126 133 Scenario: noosfero user receives a task when a user invites to be friend
127 134 Given I am on josesilva's control panel
128   - And I follow "Manage Friends"
  135 + And I follow "Manage friends"
129 136 And I follow "Invite people from my e-mail contacts"
130 137 And I press "Next"
131 138 And I fill in "manual_import_addresses" with "santos@invalid.br"
  139 + And I follow "Personalize invitation mail"
132 140 And I fill in "mail_template" with "Follow this link <url>"
133 141 And I press "Invite my friends!"
134 142 Given there are no pending jobs
135 143 When I am logged in as "josesantos"
136   - And I go to the Control panel
  144 + And I go to josesantos's control panel
137 145 And I follow "Process requests"
138 146 Then I should see "josesilva wants to be your friend."
139 147  
  148 + @selenium
140 149 Scenario: noosfero user accepts to be friend
141   - Given I invite email "santos@invalid.br" to be my friend
  150 + Given I am logged in as "josesilva"
  151 + And I go to josesilva's control panel
  152 + And I invite email "santos@invalid.br" to be my friend
142 153 And there are no pending jobs
143 154 When I am logged in as "josesantos"
144   - And I go to the Control panel
  155 + And I go to josesantos's control panel
145 156 And I follow "Process requests"
146 157 And I should see "josesilva wants to be your friend."
147 158 And I choose "Accept"
148 159 When I press "Apply!"
149 160 And I should not see "josesilva wants to be your friend."
150   - When I go to the Control panel
  161 + When I go to josesantos's control panel
151 162 And I follow "Manage friends"
152 163 Then I should see "josesilva"
153 164  
  165 + @selenium
154 166 Scenario: noosfero user rejects to be friend
155   - Given I invite email "santos@invalid.br" to be my friend
  167 + Given I am logged in as "josesilva"
  168 + And I go to josesilva's control panel
  169 + And I invite email "santos@invalid.br" to be my friend
156 170 And there are no pending jobs
157 171 When I am logged in as "josesantos"
158   - And I go to the Control panel
  172 + And I go to josesantos's control panel
159 173 And I follow "Process requests"
160 174 And I should see "josesilva wants to be your friend."
161 175 And I choose "Reject"
162 176 When I press "Apply!"
163 177 And I should not see "josesilva wants to be your friend."
164   - When I go to the Control panel
  178 + When I go to josesantos's control panel
165 179 And I follow "Manage friends"
166 180 Then I should not see "josesilva"
... ...
features/language_redirection.feature
... ... @@ -7,7 +7,7 @@ Feature: language redirection
7 7 | login | name |
8 8 | manuel | Manuel Silva |
9 9 And the following articles
10   - | owner | name | body | lang | translation_of |
  10 + | owner | name | body | language | translation_of |
11 11 | manuel | Meu Artigo | isso é um teste | pt | nil |
12 12 | manuel | My Article | this is a test | en | Meu Artigo |
13 13  
... ... @@ -26,9 +26,9 @@ Feature: language redirection
26 26 # Testing the web UI
27 27 Given I am logged in as "manuel"
28 28 And my browser prefers English
29   - And I go to manuel's profile editor
  29 + And I go to /myprofile/manuel/profile_editor/edit
30 30 And I check "Automaticaly redirect the visitor to the article translated to his/her language"
31   - And I press "save"
  31 + And I press "Save"
32 32 When I go to /manuel/meu-artigo
33 33 Then the site should be in English
34 34  
... ...
features/location.feature
... ... @@ -16,13 +16,14 @@ Feature: Location
16 16 | state |
17 17 | city |
18 18 | zip_code |
19   - And I go to the Control panel
  19 + And I go to zezinho's control panel
20 20 And I follow "Location"
21 21 When I fill in "Address" with "Rua Marechal Floriano, 28"
22 22 And I select "Brazil" from "Country"
23 23 And I fill in "State" with "Bahia"
24 24 And I fill in "City" with "Salvador"
25   - And I fill in "ZIP Code" with "40110010"
  25 + And I fill in "ZIP code" with "40110010"
  26 + And I follow "Locate in the map"
26 27 And I press "Save"
27 28 Then "zezinho" should have the following data
28 29 | address | country | state | city | zip_code |
... ... @@ -38,14 +39,14 @@ Feature: Location
38 39 Given the following <plural>
39 40 | identifier | name | owner |
40 41 | mycollective | My Collective | zezinho |
41   - And I am on My Collective's control panel
  42 + And I am on mycollective's control panel
42 43 And I follow "Location"
43 44 And I select "Brazil" from "Country"
44 45 And I fill in the following:
45 46 | Address | Rua Marechal Floriano, 28 |
46 47 | State | Bahia |
47 48 | City | Salvador |
48   - | ZIP Code | 40110010 |
  49 + | ZIP code | 40110010 |
49 50 When I press "Save"
50 51 Then "mycollective" should have the following data
51 52 | address | country | state | city | zip_code |
... ...
features/login.feature
... ... @@ -8,17 +8,20 @@ Feature: login
8 8 | login | name |
9 9 | joaosilva | Joao Silva |
10 10  
  11 + @selenium
11 12 Scenario: login from portal homepage
12 13 Given feature "allow_change_of_redirection_after_login" is disabled on environment
13 14 And I am not logged in
14 15 And I go to the homepage
  16 + And I follow "Login"
15 17 And I fill in the following:
16   - | Username | joaosilva |
  18 + | Username / Email | joaosilva |
17 19 | Password | 123456 |
18 20 When I press "Log in"
19 21 Then I should be on the homepage
20 22 And I should be logged in as "joaosilva"
21 23  
  24 + @selenium
22 25 Scenario: login from some profile page
23 26 Given feature "allow_change_of_redirection_after_login" is disabled on environment
24 27 And I am not logged in
... ... @@ -28,30 +31,31 @@ Feature: login
28 31 And the following articles
29 32 | owner | name | homepage |
30 33 | mariasilva | my home page | true |
31   - And I go to Maria Silva's homepage
  34 + And I go to mariasilva's homepage
32 35 And I follow "Login"
33 36 And I fill in the following:
34   - | Username | joaosilva |
  37 + | Username / Email | joaosilva |
35 38 | Password | 123456 |
36 39 When I press "Log in"
37   - Then I should be on Maria Silva's homepage
  40 + Then I should be on mariasilva's homepage
38 41  
39 42 Scenario: view my control panel
40 43 Given feature "allow_change_of_redirection_after_login" is disabled on environment
41 44 And I am not logged in
42   - And I go to Joao Silva's control panel
  45 + And I go to joaosilva's control panel
43 46 And I should be on login page
44 47 And I fill in the following:
45   - | Username | joaosilva |
  48 + | Username / Email | joaosilva |
46 49 | Password | 123456 |
47 50 When I press "Log in"
48   - Then I should be on Joao Silva's control panel
  51 + Then I should be on joaosilva's control panel
49 52  
50 53 Scenario: be redirected if user goes to login page and is logged
51 54 Given I am logged in as "joaosilva"
52 55 And I go to login page
53   - Then I should be on Joao Silva's control panel
  56 + Then I should be on joaosilva's control panel
54 57  
  58 + @selenium
55 59 Scenario: stay on the same page after login if this is the environment default
56 60 Given feature "allow_change_of_redirection_after_login" is enabled on environment
57 61 And I am not logged in
... ... @@ -62,26 +66,28 @@ Feature: login
62 66 And the following articles
63 67 | owner | name | homepage |
64 68 | mariasilva | my home page | true |
65   - And I go to Maria Silva's homepage
  69 + And I go to mariasilva's homepage
66 70 And I follow "Login"
67 71 And I fill in the following:
68   - | Username | joaosilva |
  72 + | Username / Email | joaosilva |
69 73 | Password | 123456 |
70 74 When I press "Log in"
71   - Then I should be on Maria Silva's homepage
  75 + Then I should be on mariasilva's homepage
72 76  
  77 + @selenium
73 78 Scenario: go to site homepage if this is the environment default
74 79 Given feature "allow_change_of_redirection_after_login" is enabled on environment
75 80 And I am not logged in
76 81 And the environment is configured to redirect to site homepage after login
77   - And I go to Joao Silva's homepage
  82 + And I go to joaosilva's homepage
78 83 And I follow "Login"
79 84 And I fill in the following:
80   - | Username | joaosilva |
  85 + | Username / Email | joaosilva |
81 86 | Password | 123456 |
82 87 When I press "Log in"
83 88 Then I should be on the homepage
84 89  
  90 + @selenium
85 91 Scenario: go to user profile after login if this is the environment default
86 92 Given feature "allow_change_of_redirection_after_login" is enabled on environment
87 93 And I am not logged in
... ... @@ -89,11 +95,12 @@ Feature: login
89 95 And I go to the homepage
90 96 And I follow "Login"
91 97 And I fill in the following:
92   - | Username | joaosilva |
  98 + | Username / Email | joaosilva |
93 99 | Password | 123456 |
94 100 When I press "Log in"
95   - Then I should be on Joao Silva's profile
  101 + Then I should be on joaosilva's profile
96 102  
  103 + @selenium
97 104 Scenario: go to profile homepage after login if this is the environment default
98 105 Given the following articles
99 106 | owner | name | body | homepage |
... ... @@ -104,11 +111,12 @@ Feature: login
104 111 And I go to the homepage
105 112 And I follow "Login"
106 113 And I fill in the following:
107   - | Username | joaosilva |
  114 + | Username / Email | joaosilva |
108 115 | Password | 123456 |
109 116 When I press "Log in"
110   - Then I should be on Joao Silva's homepage
  117 + Then I should be on joaosilva's homepage
111 118  
  119 + @selenium
112 120 Scenario: go to profile control panel after login if this is the environment default
113 121 Given feature "allow_change_of_redirection_after_login" is enabled on environment
114 122 And I am not logged in
... ... @@ -116,11 +124,12 @@ Feature: login
116 124 And I go to the homepage
117 125 And I follow "Login"
118 126 And I fill in the following:
119   - | Username | joaosilva |
  127 + | Username / Email | joaosilva |
120 128 | Password | 123456 |
121 129 When I press "Log in"
122   - Then I should be on Joao Silva's control panel
  130 + Then I should be on joaosilva's control panel
123 131  
  132 + @selenium
124 133 Scenario: stay on the same page after login if this is the profile default
125 134 Given feature "allow_change_of_redirection_after_login" is enabled on environment
126 135 And I am not logged in
... ... @@ -132,27 +141,29 @@ Feature: login
132 141 And the following articles
133 142 | owner | name | homepage |
134 143 | mariasilva | my home page | true |
135   - And I go to Maria Silva's homepage
  144 + And I go to mariasilva's homepage
136 145 And I follow "Login"
137 146 And I fill in the following:
138   - | Username | joaosilva |
  147 + | Username / Email | joaosilva |
139 148 | Password | 123456 |
140 149 When I press "Log in"
141   - Then I should be on Maria Silva's homepage
  150 + Then I should be on mariasilva's homepage
142 151  
  152 + @selenium
143 153 Scenario: go to site homepage if this is the profile default
144 154 Given feature "allow_change_of_redirection_after_login" is enabled on environment
145 155 And I am not logged in
146 156 And the environment is configured to stay on the same page after login
147 157 And the profile joaosilva is configured to redirect to site homepage after login
148   - And I go to Joao Silva's homepage
  158 + And I go to joaosilva's homepage
149 159 And I follow "Login"
150 160 And I fill in the following:
151   - | Username | joaosilva |
  161 + | Username / Email | joaosilva |
152 162 | Password | 123456 |
153 163 When I press "Log in"
154 164 Then I should be on the homepage
155 165  
  166 + @selenium
156 167 Scenario: go to user profile after login if this is the profile default
157 168 Given feature "allow_change_of_redirection_after_login" is enabled on environment
158 169 And I am not logged in
... ... @@ -161,11 +172,12 @@ Feature: login
161 172 And I go to the homepage
162 173 And I follow "Login"
163 174 And I fill in the following:
164   - | Username | joaosilva |
  175 + | Username / Email | joaosilva |
165 176 | Password | 123456 |
166 177 When I press "Log in"
167   - Then I should be on Joao Silva's profile
  178 + Then I should be on joaosilva's profile
168 179  
  180 + @selenium
169 181 Scenario: go to profile homepage after login if this is the profile default
170 182 Given the following articles
171 183 | owner | name | body | homepage |
... ... @@ -177,11 +189,12 @@ Feature: login
177 189 And I go to the homepage
178 190 And I follow "Login"
179 191 And I fill in the following:
180   - | Username | joaosilva |
  192 + | Username / Email | joaosilva |
181 193 | Password | 123456 |
182 194 When I press "Log in"
183   - Then I should be on Joao Silva's homepage
  195 + Then I should be on joaosilva's homepage
184 196  
  197 + @selenium
185 198 Scenario: go to profile control panel after login if this is the profile default
186 199 Given feature "allow_change_of_redirection_after_login" is enabled on environment
187 200 And I am not logged in
... ... @@ -190,7 +203,7 @@ Feature: login
190 203 And I go to the homepage
191 204 And I follow "Login"
192 205 And I fill in the following:
193   - | Username | joaosilva |
  206 + | Username / Email | joaosilva |
194 207 | Password | 123456 |
195 208 When I press "Log in"
196   - Then I should be on Joao Silva's control panel
  209 + Then I should be on joaosilva's control panel
... ...
features/manage_categories.feature
... ... @@ -26,7 +26,6 @@ Feature: manage categories
26 26 Scenario: load subcategories only after following parent
27 27 Then I should not see "Beans"
28 28 And I should not see "Potatoes"
29   - When I follow "Show" and wait for jquery
30   - # Then show me the page
31   -
32   -
  29 + When I follow "Show"
  30 + Then I should see "Beans"
  31 + And I should see "Potatoes"
... ...
features/manage_enterprises.feature
... ... @@ -15,8 +15,10 @@ Feature: manage enterprises
15 15 Scenario: seeing my enterprises on menu
16 16 Given I am logged in as "joaosilva"
17 17 Then I should see "My enterprises" link
18   - When I follow "My enterprises" and wait
19   - Then I should see "Tangerine Dream" linking to "/myprofile/tangerine-dream"
  18 + When I follow "My enterprises"
  19 + And I follow "Tangerine Dream"
  20 + Then I should be on tangerine-dream's control panel
  21 +
20 22  
21 23 @selenium
22 24 Scenario: not show enterprises on menu to a user without enterprises
... ...