Commit c4df5f6afed03c176f5b24a750901f112a0201e5
Exists in
master
and in
29 other branches
[Mezuro] Merge branch 'master' into mezuro
Showing
309 changed files
with
76360 additions
and
69319 deletions
Show diff stats
Too many changes.
To preserve performance only 100 of 309 files displayed.
AUTHORS
... | ... | @@ -6,45 +6,144 @@ noosfero, that's not a problem). |
6 | 6 | Developers |
7 | 7 | ========== |
8 | 8 | |
9 | +Alan Freihof Tygel <alantygel@gmail.com> | |
10 | +Alessandro Palmeira <alessandro.palmeira@gmail.com> | |
11 | +Alessandro Palmeira + Caio C. Salgado <alessandro.palmeira@gmail.com> | |
12 | +Alessandro Palmeira + Caio Salgado <alessandro.palmeira@gmail.com> | |
13 | +Alessandro Palmeira + Caio Salgado <caio.csalgado@gmail.com> | |
14 | +Alessandro Palmeira + Caio Salgado + Diego Araújo + João M. M. da Silva <diegoamc90@gmail.com> | |
15 | +Alessandro Palmeira + Carlos Morais <alessandro.palmeira@gmail.com> | |
16 | +Alessandro Palmeira + Diego Araújo <alessandro.palmeira@gmail.com> | |
17 | +Alessandro Palmeira + Diego Araújo <diegoamc90@gmail.com> | |
18 | +Alessandro Palmeira + Diego Araújo + Pedro Leal <diegoamc90@gmail.com> | |
19 | +Alessandro Palmeira + Diego Araújo + Pedro Leal + João M. M. da Silva <diegoamc90@gmail.com> | |
20 | +Alessandro Palmeira + Diego Araujo + Rafael Manzo <alessandro.palmeira@gmail.com> | |
21 | +Alessandro Palmeira + Jefferson Fernandes <alessandro.palmeira@gmail.com> | |
22 | +Alessandro Palmeira + João M. M. da Silva <alessandro.palmeira@gmail.com> | |
23 | +Alessandro Palmeira + João M. M. da Silva + Renan Teruo <alessandro.palmeira@gmail.com> | |
24 | +Alessandro Palmeira + João M. M. Silva <alessandro.palmeira@gmail.com> | |
25 | +Alessandro Palmeira + Paulo Meirelles <alessandro.palmeira@gmail.com> | |
26 | +Alessandro Palmeira + Rafael Manzo <alessandro.palmeira@gmail.com> | |
9 | 27 | Antonio Terceiro + Carlos Morais <terceiro@colivre.coop.br> |
10 | 28 | Antonio Terceiro + Paulo Meirelles <terceiro@colivre.coop.br> |
11 | 29 | Antonio Terceiro <terceiro@colivre.coop.br> |
12 | 30 | Aurelio A. Heckert <aurelio@colivre.coop.br> |
13 | 31 | Braulio Bhavamitra <brauliobo@gmail.com> |
14 | 32 | Bráulio Bhavamitra <brauliobo@gmail.com> |
33 | +Caio <caio.csalgado@gmail.com> | |
34 | +Caio + Diego + Pedro + João <caio.csalgado@gmail.com> | |
35 | +Caio, Pedro <caio.csalgado@gmail.com> | |
36 | +Caio Salgado + Alessandro Palmeira <caio.csalgado@gmail.com> | |
37 | +Caio Salgado <caio.csalgado@gmail.com> | |
38 | +Caio Salgado + Carlos Morais + Diego Araújo + Pedro Leal <diegoamc90@gmail.com> | |
39 | +Caio Salgado + Diego Araujo <caio.csalgado@gmail.com> | |
40 | +Caio Salgado + Diego Araújo <caio.csalgado@gmail.com> | |
41 | +Caio Salgado + Diego Araújo <diegoamc90@gmail.com> | |
42 | +Caio Salgado + Diego Araújo + Jefferson Fernandes <caio.csalgado@gmail.com> | |
43 | +Caio Salgado + Diego Araújo + João M. M. da Silva <caio.csalgado@gmail.com> | |
44 | +Caio Salgado + Diego Araújo + Pedro Leal <caio.csalgado@gmail.com> | |
45 | +Caio Salgado + Diego Araújo + Pedro Leal <diegoamc90@gmail.com> | |
46 | +Caio Salgado + Diego Araújo + Rafael Manzo <diegoamc90@gmail.com> | |
47 | +Caio Salgado + Jefferson Fernandes <caio.csalgado@gmail.com> | |
48 | +Caio Salgado + Jefferson Fernandes <jeffs.fernandes@gmail.com> | |
49 | +Caio Salgado + Rafael Manzo <caio.csalgado@gmail.com> | |
50 | +Caio Salgado + Renan Teruo <caio.csalgado@gmail.com> | |
51 | +Caio Salgado + Renan Teruo <caio.salgado@gmail.com> | |
52 | +Caio Salgado + Renan Teruo + Jefferson Fernandes <jeffs.fernandes@gmail.com> | |
53 | +Caio Salgado + Renan Teruo <renanteruoc@gmail.com> | |
15 | 54 | Caio SBA <caio@colivre.coop.br> |
16 | 55 | Carlos Morais <carlos88morais@gmail.com> |
17 | 56 | Carlos Morais + Diego Araújo <diegoamc90@gmail.com> |
57 | +Carlos Morais + Eduardo Morais <carlos88morais@gmail.com> | |
18 | 58 | Carlos Morais + Paulo Meirelles <carlos88morais@gmail.com> |
59 | +Carlos Morais + Pedro Leal <carlos88morais@gmail.com> | |
19 | 60 | Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> |
20 | 61 | Daniel Cunha <daniel@colivre.coop.br> |
62 | +diegoamc <diegoamc90@gmail.com> | |
63 | +Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com> | |
64 | +Diego Araujo + Caio Salgado <diegoamc90@gmail.com> | |
21 | 65 | Diego Araújo <diegoamc90@gmail.com> |
66 | +Diego Araújo + Jefferson Fernandes <diegoamc90@gmail.com> | |
67 | +Diego Araujo + Jefferson Fernandes <jeffs.fernandes@gmail.com> | |
68 | +Diego Araújo + João Machini <diegoamc90@gmail.com> | |
69 | +Diego Araújo + João Machini <digoamc90@gmail.com> | |
22 | 70 | Diego Araújo + João M. M. da Silva <diegoamc90@gmail.com> |
71 | +Diego Araújo + João M. M. da Silva + João Machini <diegoamc90@gmail.com> | |
72 | +Diego Araújo + João M. M. da Silva + Pedro Leal <diegoamc90@gmail.com> | |
73 | +Diego Araújo + Paulo Meirelles <diegoamc90@gmail.com> | |
74 | +Diego Araújo + Pedro Leal <diegoamc90@gmail.com> | |
75 | +Diego Araújo + Rafael Manzo <diegoamc90@gmail.com> | |
76 | +Diego Araújo + Renan Teruo + Alessandro Palmeira <diegoamc90@gmail.com> | |
77 | +Diego Araújo + Renan Teruo <diegoamc90@gmail.com> | |
78 | +Diego + Jefferson <diegoamc90@gmail.com> | |
79 | +Diego Martinez <diegoamc90@gmail.com> | |
80 | +Diego + Renan <renanteruoc@gmail.com> | |
23 | 81 | Fernanda Lopes <nanda.listas+psl@gmail.com> |
24 | 82 | Grazieno Pellegrino <grazieno@gmail.com> |
25 | 83 | Isaac Canan <isaac@intelletto.com.br> |
26 | 84 | Italo Valcy <italo@dcc.ufba.br> |
85 | +Jefferson Fernandes + Diego Araujo + Rafael Manzo <jeffs.fernandes@gmail.com> | |
86 | +Jefferson Fernandes + Joao M. M. da Silva <jeffs.fernandes@gmail.com> | |
87 | +Jefferson Fernandes + Joao M. M. Silva <jeffs.fernandes@gmail.com> | |
27 | 88 | João da Silva <jaodsilv@linux.ime.usp.br> |
89 | +João Marco Maciel da Silva + Rafael Manzo + Renan Teruo <jaodsilv@linux.ime.usp.br> | |
90 | +João M. M. da Silva + Alessandro Palmeira + Diego Araújo + Caio Salgado <jaodsilv@linux.ime.usp.br> | |
91 | +João M. M. da Silva + Alessandro Palmeira + Diego Araújo <jaodsilv@linux.ime.usp.br> | |
92 | +João M. M. da Silva + Alessandro Palmeira <jaodsilv@linux.ime.usp.br> | |
93 | +João M. M. da Silva + Alessandro Palmeira + João Machini <jaodsilv@linux.ime.usp.br> | |
94 | +João M. M. da Silva + Caio Salgado + Alessandro Palmeira <jaodsilv@linux.ime.usp.br> | |
95 | +João M. M. da Silva + Caio Salgado <jaodsilv@linux.ime.usp.br> | |
28 | 96 | João M. M. da Silva + Carlos Morais <jaodsilv@linux.ime.usp.br> |
29 | 97 | João M. M. da Silva + Diego Araújo <diegoamc90@gmail.com> |
30 | 98 | João M. M. da Silva + Diego Araújo <jaodsilv@linux.ime.usp.br> |
99 | +João M. M. da Silva + Diego Araújo + Pedro Leal <jaodsilv@linux.ime.usp.br> | |
100 | +João M. M. da Silva <jaodsilv@linux.ime.usp.br> | |
101 | +Joao M. M. da Silva + Jefferson Fernandes <jaodsilv@linux.ime.usp.br> | |
102 | +João M. M. da Silva + Jefferson Fernandes <jaodsilv@linux.ime.usp.br> | |
103 | +João M. M. da Silva + João M. Miranda <jaodsilv@linux.ime.usp.br> | |
31 | 104 | João M. M. da Silva + Paulo Meirelles <jaodsilv@linux.ime.usp.br> |
105 | +João M. M. da Silva + Pedro Leal <jaodsilv@linux.ime.usp.br> | |
106 | +João M. M. da Silva + Rafael Manzo + Diego Araújo <jaodsilv@linux.ime.usp.br> | |
107 | +João M. M. da Silva + Rafael Manzo <jaodsilv@linux.ime.usp.br> | |
108 | +João M. M. da Silva + Renan Teruo <jaodsilv@linux.ime.usp.br> | |
109 | +João M. M. Silva + Caio Salgado <jaodsilv@linux.ime.usp.br> | |
110 | +João M. M. Silva + Diego Araújo <jaodsilv@linux.ime.usp.br> | |
111 | +Joao M. M. Silva + Jefferson Fernandes <jaodsilv@linux.ime.usp.br> | |
112 | +João M. M. Silva + Paulo Meirelles <jaodsilv@linux.ime.usp.br> | |
113 | +João M. M. Silva + Rafael Manzo <jaodsilv@linux.ime.usp.br> | |
114 | +João M. M. Silva + Renan Teruo <jaodsilv@linux.ime.usp.br> | |
32 | 115 | Joenio Costa <joenio@colivre.coop.br> |
33 | 116 | Josef Spillner <josef.spillner@tu-dresden.de> |
34 | 117 | Keilla Menezes <keilla@colivre.coop.br> |
35 | 118 | Larissa Reis <larissa@colivre.coop.br> |
36 | 119 | Larissa Reis <reiss.larissa@gmail.com> |
37 | 120 | Leandro Nunes dos Santos <leandronunes@gmail.com> |
121 | +Leandro Nunes dos Santos <leandro.santos@serpro.gov.br> | |
38 | 122 | LinguÁgil 2010 <linguagil.bahia@gmail.com> |
123 | +Luis David Aguilar Carlos <ludwig9003@gmail.com> | |
39 | 124 | Martín Olivera <molivera@solar.org.ar> |
40 | 125 | Moises Machado <moises@colivre.coop.br> |
41 | 126 | Nanda Lopes <nanda.listas+psl@gmail.com> |
127 | +Paulo Meirelles + Alessandro Palmeira <paulo@softwarelivre.org> | |
42 | 128 | Paulo Meirelles + Carlos Morais <paulo@softwarelivre.org> |
129 | +Paulo Meirelles + Diego Araújo <paulo@softwarelivre.org> | |
130 | +Paulo Meirelles + João M. M. da Silva <paulo@softwarelivre.org> | |
43 | 131 | Paulo Meirelles <paulo@softwarelivre.org> |
44 | 132 | Rafael Gomes <rafaelgomes@techfree.com.br> |
133 | +Rafael Manzo + João M. M. Silva <rr.manzo@gmail.com> | |
45 | 134 | Rafael Martins <rmmartins@gmail.com> |
135 | +Rafael Reggiani Manzo + Caio Salgado + Jefferson Fernandes <rr.manzo@gmail.com> | |
136 | +Rafael Reggiani Manzo + Diego Araujo <diegoamc90@gmail.com> | |
137 | +Rafael Reggiani Manzo + Diego Araujo <rr.manzo@gmail.com> | |
138 | +Rafael Reggiani Manzo <rr.manzo@gmail.com> | |
46 | 139 | Raphaël Rousseau <raph@r4f.org> |
47 | 140 | Raquel Lira <raquel.lira@gmail.com> |
141 | +Renan Teruo + Caio Salgado <renanteruoc@gmail.com> | |
142 | +Renan Teruoc + Diego Araujo <renanteruoc@gmail.com> | |
143 | +Renan Teruo + Diego Araujo <renanteruoc@gmail.com> | |
144 | +Renan Teruo + Diego Araújo <renanteruoc@gmail.com> | |
145 | +Renan Teruo + Paulo Meirelles <renanteruoc@gmail.com> | |
146 | +Renan Teruo + Rafael Manzo <renanteruoc@gmail.com> | |
48 | 147 | Rodrigo Souto <rodrigo@colivre.coop.br> |
49 | 148 | Ronny Kursawe <kursawe.ronny@googlemail.com> |
50 | 149 | Samuel R. C. Vale <srcvale@holoscopio.com> | ... | ... |
Gemfile
1 | 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' | |
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 | 2 | remote: http://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) | ... | ... |
HACKING
1 | 1 | = Noosfero instructions for developers |
2 | 2 | |
3 | -This document provides useful information to those who want to help with | |
4 | -Noosfero development. | |
3 | +== A work about your the development platform | |
5 | 4 | |
6 | -== Requirements for development | |
5 | +These instructions are tested and known to work on Debian stable, which is the | |
6 | +system that the Noosfero core developers use to work on Noosfero. | |
7 | 7 | |
8 | -First, install all requirements listed in INSTALL. Note that you do not need to | |
9 | -follow all the steps described there, you only need to install the packages | |
10 | -listed in the "Requirements" section. | |
8 | +If you want to use another OS, read "Instructions for other systems" below. | |
11 | 9 | |
12 | -After installing the requirements listed in INSTALL, you need to install some | |
13 | -packages be able to run Noosfero tests. On Debian GNU/Linux and Debian-based | |
14 | -systems, you install them with the following command: | |
10 | +== Instructions for Debian stable | |
15 | 11 | |
16 | - # apt-get install libtidy-ruby libhpricot-ruby libmocha-ruby imagemagick po4a xvfb libxml2-dev libxslt-dev | |
12 | +Download the source code: | |
17 | 13 | |
18 | -On other systems, they may or may not be available through your regular package | |
19 | -management system. Below are the links to their homepages. | |
14 | + $ git clone git://gitorious.org/noosfero/noosfero.git | |
15 | + $ cd noosfero | |
20 | 16 | |
21 | -* Mocha: http://mocha.rubyforge.org/ | |
22 | -* Tidy: http://tidy.sourceforge.net/ | |
23 | -* Hpricot: http://github.com/whymirror/hpricot | |
24 | -* Imagemagick: http://wwwimagemagick.org/ | |
25 | -* po4a: http://po4a.alioth.debian.org/ | |
26 | -* xvfb: http://packages.debian.org/lenny/xvfb | |
27 | -* Libxml2: http://xmlsoft.org/ | |
28 | -* Libxslt: http://xmlsoft.org/xslt | |
17 | +Run the quick start script: | |
29 | 18 | |
30 | -== Boostraping a development/test environment | |
19 | + $ ./script/quick-start | |
31 | 20 | |
32 | -You can copy and paste the commands below into a terminal (please review the | |
33 | -commands and make sure you understand what you are doing): | |
21 | +Now you can execute the development server with: | |
34 | 22 | |
35 | - # checkout the code from repository | |
36 | - git clone git://gitorious.org/noosfero/noosfero.git | |
37 | - # enter the directory | |
38 | - cd noosfero | |
39 | - # copy a sample config file | |
40 | - cp config/database.yml.sqlite3 config/database.yml | |
41 | - # create tmp directory if it doesn't exist | |
42 | - mkdir tmp | |
43 | - # start Solr | |
44 | - rake solr:start | |
45 | - # create the development database | |
46 | - rake db:schema:load | |
47 | - # run pending migrations | |
48 | - rake db:migrate | |
49 | - # compile translations: | |
50 | - rake makemo | |
51 | - # create some test data: | |
52 | - ./script/sample-data | |
53 | - # install latest requirements for running tests | |
54 | - RAILS_ENV=cucumber rake gems:install | |
55 | - RAILS_ENV=test rake gems:install | |
56 | - # run the automated test suite to make sure your environment is sane: | |
57 | - rake test | |
23 | + $ ./script/development | |
58 | 24 | |
59 | -You should now be ready to go. Issue the following command to start the Rails | |
60 | -development server: | |
25 | +You will be able to access Noosfero at http://localhost:3000/ | |
61 | 26 | |
62 | - ./script/server | |
27 | +If you want to use a different port than 3000, pass `-p <PORT>` to | |
28 | +./script/development | |
63 | 29 | |
64 | -The server will be available at http://localhost:3000/ . If you want to use | |
65 | -another port than 3000, you can use the -p option of ./script/server: | |
30 | +== Instructions for other systems | |
66 | 31 | |
67 | - ./script/server -p 9999 | |
32 | +On other OS, you have 2 options: | |
68 | 33 | |
69 | -The above command makes the server available at http://localhost:9999/ | |
34 | +1) using a chroot or a VM with Debian stable (easier) | |
70 | 35 | |
71 | -The sample-data data scripts creates two administrator users with login "ze" and | |
72 | -password "test" and login "adminuser" and password "admin". | |
36 | +Use a chroot (http://wiki.debian.org/Schroot) or a Virtual Machine (e.g. with | |
37 | +VirtualBox) with a Debian stable system and follow the instructions above for | |
38 | +Debian stable. | |
73 | 39 | |
74 | -Note that some operations, like generating image thumbnails, sending e-mails, | |
75 | -etc, are done in background in the context of a service independent from the | |
76 | -Rails application server. To have those tasks performed in a development | |
77 | -environment, you must run the delayed_job server like this: | |
40 | +2) Installing dependencies on other OS (harder) | |
78 | 41 | |
79 | - ./script/delayed_job run | |
42 | +If you want to setup a development environment in another OS, you can create a | |
43 | +file under script/install-dependencies/, called <OS>-<CODENAME>.sh, which | |
44 | +installed the dependencies for your system. With this script in place, | |
45 | +./script/quick-start will call it at the point of installing the required | |
46 | +packages for Noosfero development. | |
80 | 47 | |
81 | -This will block your terminal. To stop the delayed_job server, hit Control-C. | |
48 | +You can check script/install-dependencies/debian-squeeze.sh to have an idea of | |
49 | +what kind of stuff that script has to do. | |
82 | 50 | |
83 | -== Enabling exceptions notification | |
84 | - | |
85 | -By default, exception notifications are disabled in development environment. If | |
86 | -you want to enable it then you need to change some files: | |
87 | - | |
88 | -1) Add in config/environments/development.rb: | |
89 | - config.action_controller.consider_all_requests_local = false | |
90 | - | |
91 | -2) Add in app/controller/application.rb: | |
92 | - local_addresses.clear | |
93 | - | |
94 | -3) Add in config/noosfero.yml at development section: | |
95 | - exception_recipients: [admin@example.com] | |
96 | - | |
97 | -== Releasing and building Debian package | |
98 | - | |
99 | -See RELEASING file. | |
51 | +If you write such script for your own OS, *please* share it with us at the | |
52 | +development mailing list so that we can include it in the official repository. | |
53 | +This way other people using the same OS will have to put less effort to develop | |
54 | +Noosfero. | ... | ... |
INSTALL
1 | -= Noosfero installation instructions | |
1 | += Noosfero installation instructions from source for production environments | |
2 | 2 | |
3 | -Noosfero is written in Ruby with the "Rails framework":http://www.rubyonrails.org, | |
4 | -so the process of setting it up is pretty similar to other Rails applications. | |
3 | +The instructions below can be used for setting up a Noosfero production | |
4 | +environment from the Noosfero sources. | |
5 | 5 | |
6 | -Below we have the instructions for installing Noosfero dependencies and setting | |
7 | -up a production environment. If you have problems with the setup, please feel | |
8 | -free to ask questions in the development mailing list. | |
6 | +Before you start installing Noosfero manually, see the information about the | |
7 | +Noosfero Debian package at http://noosfero.org/Development/DebianPackage. Using | |
8 | +the Debian packages on a Debian stable system is the recommended method for | |
9 | +installing production environments. | |
10 | + | |
11 | +If you want to setup a development environment instead of a production one, | |
12 | +stop reading this file right now and read the file HACKING instead. | |
13 | + | |
14 | +For a complete installation guide, please see the following web page: | |
15 | +http://noosfero.org/Development/HowToInstall | |
16 | + | |
17 | +If you have problems with the setup, please feel free to ask questions in the | |
18 | +development mailing list. | |
9 | 19 | |
10 | 20 | == Requirements |
11 | 21 | |
22 | +DISCLAIMER: this installation procedure is tested with Debian stable, which is | |
23 | +currently the only recommended operating system for production usage. It is | |
24 | +possible that you can install it on other systems, and if you do so, please | |
25 | +report it on one of the Noosfero mailing lists, and please send a patch | |
26 | +updating these instructions. | |
27 | + | |
28 | +Noosfero is written in Ruby with the "Rails | |
29 | +framework":http://www.rubyonrails.org, so the process of setting it up is | |
30 | +pretty similar to other Rails applications. | |
31 | + | |
12 | 32 | You need to install some packages Noosfero depends on. On Debian GNU/Linux or |
13 | 33 | Debian-based systems, all of these packages are available through the Debian |
14 | 34 | archive. You can install them with the following command: |
... | ... | @@ -38,21 +58,9 @@ If you manage to install Noosfero successfully on other systems than Debian, |
38 | 58 | please feel free to contact the Noosfero development mailing with the |
39 | 59 | instructions for doing so, and we'll include it here. |
40 | 60 | |
41 | -=== Setting up a production environment | |
42 | - | |
43 | -DISCLAIMER: this installation procedure is tested with Debian stable, which is | |
44 | -currently the only recommended operating system for production usage. It is | |
45 | -possible that you can install it on other systems, and if you do so, please | |
46 | -report it on one of the Noosfero mailing lists, and please send a patch | |
47 | -updating these instructions. | |
48 | - | |
49 | 61 | As root user |
50 | 62 | ============ |
51 | 63 | |
52 | -NOTE: these instructions are for seting up a *production* environment. If you | |
53 | -are going to do Noosfero development, you don't need to do these steps. Stop | |
54 | -here and see the HACKING file instead. | |
55 | - | |
56 | 64 | Install memcached. On Debian: |
57 | 65 | |
58 | 66 | # apt-get install memcached |
... | ... | @@ -96,11 +104,11 @@ $ git checkout -b stable origin/stable |
96 | 104 | downloading tarball |
97 | 105 | ------------------- |
98 | 106 | |
99 | -Note: replace 0.35.0 below from the latest stable version. | |
107 | +Note: replace 0.39.0 below from the latest stable version. | |
100 | 108 | |
101 | -$ wget http://noosfero.org/pub/Development/NoosferoVersion00x35x00/noosfero-0.35.0.tar.gz | |
102 | -$ tar -zxvf noosfero-0.35.0.tar.gz | |
103 | -$ ln -s noosfero-0.35.0 current | |
109 | +$ wget http://noosfero.org/pub/Development/NoosferoVersion00x39x00/noosfero-0.39.0.tar.gz | |
110 | +$ tar -zxvf noosfero-0.39.0.tar.gz | |
111 | +$ ln -s noosfero-0.39.0 current | |
104 | 112 | $ cd current |
105 | 113 | |
106 | 114 | Copy config/solr.yml.dist to config/solr.yml. You will |
... | ... | @@ -108,7 +116,7 @@ probably not need to customize this configuration, but have a look at it. |
108 | 116 | |
109 | 117 | Create the thin configuration file: |
110 | 118 | |
111 | -$ thin -C config/thin.yml config | |
119 | +$ thin -C config/thin.yml -e production config | |
112 | 120 | |
113 | 121 | Edit config/thin.yml to suit your needs. Make sure your apache |
114 | 122 | configuration matches the thin cluster configuration, specially in respect |
... | ... | @@ -147,48 +155,7 @@ Restart postgresql: |
147 | 155 | |
148 | 156 | Noosfero needs a functional e-mail setup to work: the local mail system should |
149 | 157 | be able to deliver e-mail to the internet, either directly or through an |
150 | -external SMTP server. | |
151 | - | |
152 | -If you know mail systems well, you just need to make sure thet the local MTA, | |
153 | -listening on localhost:25, is able to deliver e-mails to the internet. Any mail | |
154 | -server will do it. | |
155 | - | |
156 | -If you are not a mail specialist, we suggest that you use the Postfix mail | |
157 | -server, since it is easy to configure and very reliable. Just follow the | |
158 | -instructions below. | |
159 | - | |
160 | -To install Postfix: | |
161 | - | |
162 | -# apt-get install postfix | |
163 | - | |
164 | -During the installation process, you will be asked a few questions. Your answer | |
165 | -to them will vary in 2 cases: | |
166 | - | |
167 | -Case 1: you can send e-mails directly to the internet. This will be the case | |
168 | -for most commercial private servers. Your answers should be: | |
169 | - | |
170 | - General type of mail configuration: Internet site | |
171 | - System mail name: the name of your domain, e.g. "mysocialnetwork.com" | |
172 | - | |
173 | -Case 2: you cannot, or don't want to, send e-mail directly to the internet. | |
174 | -This happens for example if your server is not allowed to make outbound | |
175 | -connections on port 25, or if you want to concentrate all your outbound mail | |
176 | -through a single SMTP server. Your answers in this case should be: | |
177 | - | |
178 | - General type of mail configuration: Internet with smarthost | |
179 | - System mail name: the name of your domain, e.g. "mysocialnetwork.com" | |
180 | - SMTP relay host: smtp.yourprovider.com | |
181 | - | |
182 | -Note that smtp.yourprovider.com must allow your server to deliver e-mails | |
183 | -through it. You should probably ask your servive provider about this. | |
184 | - | |
185 | -There is another possibility: if you are installing on a shared server, and | |
186 | -don't have permission to configure the local MTA, you can instruct Noosfero to | |
187 | -send e-mails directly through an external server. Please note that this should | |
188 | -be your last option, since contacting an external SMTP server directly may slow | |
189 | -down your Noosfero application server. To configure Noosfero to send e-mails | |
190 | -through an external SMTP server, follow the instructions on | |
191 | -http://noosfero.org/Development/SMTPMailSending | |
158 | +external SMTP server. Please check the documentation at the INSTALL.email file. | |
192 | 159 | |
193 | 160 | As noosfero user |
194 | 161 | ================ |
... | ... | @@ -220,19 +187,6 @@ $ ./script/dbconsole production |
220 | 187 | If it connects to your database, then everything is fine. If you got an error |
221 | 188 | message, then you have to check your database configuration. |
222 | 189 | |
223 | -Installing gem rack | |
224 | -=================== | |
225 | - | |
226 | -This gem is required if you want to run Mezuro plugin. | |
227 | - | |
228 | -Install RubyGem Rack 1.0.1. | |
229 | -Others versions may not be compatible with Noosfero: | |
230 | - | |
231 | -# gem install rack -v 1.0.1 | |
232 | - | |
233 | -As noosfero user | |
234 | -================ | |
235 | - | |
236 | 190 | Create the database structure: |
237 | 191 | |
238 | 192 | $ RAILS_ENV=production rake db:schema:load |
... | ... | @@ -245,7 +199,7 @@ Run Solr: |
245 | 199 | |
246 | 200 | $ rake solr:start |
247 | 201 | |
248 | -Now we have to create some initial data. To create your default environment | |
202 | +Now we must create some initial data. To create your default environment | |
249 | 203 | (the first one), run the command below: |
250 | 204 | |
251 | 205 | $ RAILS_ENV=production ./script/runner 'Environment.create!(:name => "My environment", :is_default => true)' |
... | ... | @@ -261,10 +215,10 @@ $ RAILS_ENV=production ./script/runner "Environment.default.domains << Domain.ne |
261 | 215 | |
262 | 216 | Add at least one user as admin of environment: |
263 | 217 | |
264 | -$ RAILS_ENV=production ./script/runner "User.create(:login => 'adminuser', :email => 'admin@example.com', :password => 'admin', :password_confirmation => 'admin', :environment => Environment.default)" | |
218 | +$ RAILS_ENV=production ./script/runner "User.create(:login => 'adminuser', :email => 'admin@example.com', :password => 'admin', :password_confirmation => 'admin', :environment => Environment.default, :activated_at => Time.new)" | |
265 | 219 | |
266 | 220 | (replace "adminuser", "admin@example.com", "admin" with the login, email |
267 | -and password of your environment admin) | |
221 | +and password of your environment administrator) | |
268 | 222 | |
269 | 223 | To start the Noosfero application servers: |
270 | 224 | |
... | ... | @@ -274,23 +228,6 @@ At this point you have a functional Noosfero installation running, the only |
274 | 228 | thing left is to configure your webserver as a reverse proxy to pass requests |
275 | 229 | to them. |
276 | 230 | |
277 | -Enabling exception notifications | |
278 | -================================ | |
279 | - | |
280 | -This is an optional step. You will need it only if you want to receive e-mail | |
281 | -notifications when some exception occurs on Noosfero. | |
282 | - | |
283 | -First, install this version of the gem. | |
284 | -Others versions may not be compatible with Noosfero: | |
285 | - | |
286 | -# gem install exception_notification -v 1.0.20090728 | |
287 | - | |
288 | -You can configure the e-mails that will receive the notifications. | |
289 | -Change the file config/noosfero.yml as the following example, replacing the | |
290 | -e-mails by real ones: | |
291 | - | |
292 | - production: | |
293 | - exception_recipients: [admin@example.com, you@example.com] | |
294 | 231 | |
295 | 232 | ================== |
296 | 233 | Apache instalation |
... | ... | @@ -384,6 +321,26 @@ Now restart your apache server (as root): |
384 | 321 | |
385 | 322 | # invoke-rc.d apache2 restart |
386 | 323 | |
324 | + | |
325 | +Enabling exception notifications | |
326 | +================================ | |
327 | + | |
328 | +This is an optional step. You will need it only if you want to receive e-mail | |
329 | +notifications when some exception occurs on Noosfero. | |
330 | + | |
331 | +First, install this version of the gem. | |
332 | +Others versions may not be compatible with Noosfero: | |
333 | + | |
334 | +# gem install exception_notification -v 1.0.20090728 | |
335 | + | |
336 | +You can configure the e-mails that will receive the notifications. | |
337 | +Change the file config/noosfero.yml as the following example, replacing the | |
338 | +e-mails by real ones: | |
339 | + | |
340 | + production: | |
341 | + exception_recipients: [admin@example.com, you@example.com] | |
342 | + | |
343 | + | |
387 | 344 | ============ |
388 | 345 | Maintainance |
389 | 346 | ============ | ... | ... |
... | ... | @@ -0,0 +1,43 @@ |
1 | += Noosfero email setup | |
2 | + | |
3 | +If you know mail systems well, you just need to make sure that the local MTA, | |
4 | +listening on localhost:25, is able to deliver e-mails to the internet. Any mail | |
5 | +server will do it. You can stop reading now. | |
6 | + | |
7 | +If you are not an email specialist, then follow the instructions below. We | |
8 | +suggest that you use the Postfix mail server, since it is easy to configure and | |
9 | +very reliable. Just follow the instructions below. | |
10 | + | |
11 | +To install Postfix: | |
12 | + | |
13 | +# apt-get install postfix | |
14 | + | |
15 | +During the installation process, you will be asked a few questions. Your answer | |
16 | +to them will vary in 2 cases: | |
17 | + | |
18 | +Case 1: you can send e-mails directly to the internet. This will be the case | |
19 | +for most commercial private servers. Your answers should be: | |
20 | + | |
21 | + General type of mail configuration: Internet site | |
22 | + System mail name: the name of your domain, e.g. "mysocialnetwork.com" | |
23 | + | |
24 | +Case 2: you cannot, or don't want to, send e-mail directly to the internet. | |
25 | +This happens for example if your server is not allowed to make outbound | |
26 | +connections on port 25, or if you want to concentrate all your outbound mail | |
27 | +through a single SMTP server. Your answers in this case should be: | |
28 | + | |
29 | + General type of mail configuration: Internet with smarthost | |
30 | + System mail name: the name of your domain, e.g. "mysocialnetwork.com" | |
31 | + SMTP relay host: smtp.yourprovider.com | |
32 | + | |
33 | +Note that smtp.yourprovider.com must allow your server to deliver e-mails | |
34 | +through it. You should probably ask your servive provider about this. | |
35 | + | |
36 | +There is another possibility: if you are installing on a shared server, and | |
37 | +don't have permission to configure the local MTA, you can instruct Noosfero to | |
38 | +send e-mails directly through an external server. Please note that this should | |
39 | +be your last option, since contacting an external SMTP server directly may slow | |
40 | +down your Noosfero application server. To configure Noosfero to send e-mails | |
41 | +through an external SMTP server, follow the instructions on | |
42 | +http://noosfero.org/Development/SMTPMailSending | |
43 | + | ... | ... |
INSTALL.varnish
... | ... | @@ -5,75 +5,67 @@ recommended. See http://www.varnish-cache.org/ for more information on Varnish. |
5 | 5 | |
6 | 6 | Varnish can be set up to use with Noosfero with the following steps: |
7 | 7 | |
8 | -1) setup Noosfero with apache according to the INSTALL file. | |
8 | +1) setup Noosfero with apache according to the INSTALL file. If you used the | |
9 | +Debian package to install noosfero, you don't need to do anything about this. | |
9 | 10 | |
10 | 11 | 2) install Varnish |
11 | 12 | |
12 | 13 | # apt-get install varnish |
13 | 14 | |
14 | -Noosfero was tested with Varnish 2.x. If you are using a Debian Lenny (and you | |
15 | -should, unless Debian already released Squeeze by now), make sure you install | |
16 | -varnish from the lenny-backports suite. | |
17 | - | |
18 | 15 | Install the RPAF apache module (or skip this step if not using apache): |
19 | 16 | |
20 | 17 | # apt-get install libapache2-mod-rpaf |
21 | 18 | |
22 | -3) Enable varnish logging: | |
19 | +3) Change Apache to listen on port 8080 instead of 80 | |
23 | 20 | |
24 | -3a) Edit /etc/default/varnishncsa and uncomment the line that contains: | |
21 | +3a) Edit /etc/apache2/ports.conf, and: | |
25 | 22 | |
26 | -VARNISHNCSA_ENABLED=1 | |
23 | + * change 'NameVirtualHost *:80' to 'NameVirtualHost *:8080' | |
24 | + * change 'Listen 80' to 'Listen 127.0.0.1:8080' | |
27 | 25 | |
28 | -The varnish log will be written to /var/log/varnish/varnishncsa.log in an | |
29 | -apache-compatible format. You should change your statistics generation software | |
30 | -(e.g. awstats) to use that instead of apache logs. | |
26 | +3b) Edit /etc/apache2/sites-enabled/*, and change '<VirtualHost *:80>' to | |
27 | +'<VirtualHost *:8080>' | |
31 | 28 | |
32 | -3b) Restart Varnish Logging service | |
29 | +3c) Restart apache | |
33 | 30 | |
34 | - # invoke-rc.d varnishncsa start | |
31 | + # invoke-rc.d apache2 restart | |
35 | 32 | |
36 | -4) Change Apache to listen on port 8080 instead of 80 | |
33 | +4) Varnish configuration | |
37 | 34 | |
38 | -4a) Edit /etc/apache2/ports.conf, and: | |
35 | +4a) Edit /etc/default/varnish | |
39 | 36 | |
40 | - * change 'Listen 80' to 'Listen 127.0.0.1:8080' | |
41 | - * change 'NameVirtualHost *:80' to 'NameVirtualHost *:8080' | |
37 | + * change the line that says "START=no" to say "START=yes" | |
38 | + * change '-a :6081' to '-a :80' | |
42 | 39 | |
43 | -4b) Edit /etc/apache2/sites-enabled/*, and change '<VirtualHost *:80>' to '<VirtualHost *:8080>' | |
40 | +4b) Edit /etc/varnish/default.vcl and add the following lines at the end: | |
44 | 41 | |
45 | -4c) Restart apache | |
42 | + include "/etc/noosfero/varnish-noosfero.vcl"; | |
43 | + include "/etc/noosfero/varnish-accept-language.vcl"; | |
46 | 44 | |
47 | - # invoke-rc.d apache2 restart | |
45 | +On manual installations, change "/etc/noosfero/*" to | |
46 | +"{Rails.root}/etc/noosfero/*" | |
48 | 47 | |
49 | -5) Change Varnish to listen on port 80 | |
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". | |
50 | 51 | |
51 | -5a) Edit /etc/default/varnish and change '-a :6081' to '-a :80' | |
52 | - | |
53 | -5b) Restart Varnish | |
52 | +4c) Restart Varnish | |
54 | 53 | |
55 | 54 | # invoke-rc.d varnish restart |
56 | 55 | |
57 | -6) Configure varnish to fit noosfero | |
58 | -(assuming Noosfero is installed in /var/lib/noosfero) | |
59 | - | |
60 | -6a) Configure noosfero to do specific routines to varnish | |
61 | - | |
62 | -Add the following line to your /etc/varnish/default.vcl file: | |
56 | +5) Enable varnish logging: | |
63 | 57 | |
64 | - include "/var/lib/noosfero/etc/noosfero/varnish-noosfero.vcl"; | |
58 | +5a) Edit /etc/default/varnishncsa and uncomment the line that contains: | |
65 | 59 | |
66 | -6b) Configure varnish to store separate caches for each language | |
67 | - | |
68 | -Add the following line to your /etc/varnish/default.vcl file: | |
60 | +VARNISHNCSA_ENABLED=1 | |
69 | 61 | |
70 | - include "/var/lib/noosfero/etc/noosfero/varnish-accept-language.vcl"; | |
62 | +The varnish log will be written to /var/log/varnish/varnishncsa.log in an | |
63 | +apache-compatible format. You should change your statistics generation software | |
64 | +(e.g. awstats) to use that instead of apache logs. | |
71 | 65 | |
72 | -7) Restart Varnish | |
66 | +5b) Restart Varnish Logging service | |
73 | 67 | |
74 | - # invoke-rc.d varnish restart | |
68 | + # invoke-rc.d varnishncsa restart | |
75 | 69 | |
76 | 70 | Thanks to Cosimo Streppone for varnish-accept-language. See |
77 | 71 | http://github.com/cosimo/varnish-accept-language for more information. |
78 | - | |
79 | - -- Antonio Terceiro <terceiro@colivre.coop.br> Sat, 04 Sep 2010 17:29:27 -0300 | ... | ... |
app/controllers/admin/environment_design_controller.rb
... | ... | @@ -3,7 +3,7 @@ class EnvironmentDesignController < 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 | end |
8 | 8 | |
9 | 9 | end | ... | ... |
app/controllers/my_profile/cms_controller.rb
... | ... | @@ -16,7 +16,13 @@ class CmsController < MyProfileController |
16 | 16 | |
17 | 17 | before_filter :login_required, :except => [:suggest_an_article] |
18 | 18 | |
19 | - protect_if :except => [:suggest_an_article, :set_home_page, :edit, :destroy, :publish] do |c, user, profile| | |
19 | + protect_if :only => :upload_files do |c, user, profile| | |
20 | + article_id = c.params[:parent_id] | |
21 | + (!article_id.blank? && profile.articles.find(article_id).allow_create?(user)) || | |
22 | + (user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile))) | |
23 | + end | |
24 | + | |
25 | + protect_if :except => [:suggest_an_article, :set_home_page, :edit, :destroy, :publish, :upload_files] do |c, user, profile| | |
20 | 26 | user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile)) |
21 | 27 | end |
22 | 28 | |
... | ... | @@ -92,7 +98,7 @@ class CmsController < MyProfileController |
92 | 98 | @article_types = [] |
93 | 99 | available_article_types.each do |type| |
94 | 100 | @article_types.push({ |
95 | - :name => type.name, | |
101 | + :class => type, | |
96 | 102 | :short_description => type.short_description, |
97 | 103 | :description => type.description |
98 | 104 | }) |
... | ... | @@ -154,7 +160,7 @@ class CmsController < MyProfileController |
154 | 160 | end |
155 | 161 | if request.post? && params[:uploaded_files] |
156 | 162 | params[:uploaded_files].each do |file| |
157 | - @uploaded_files << UploadedFile.create(:uploaded_data => file, :profile => profile, :parent => @parent) unless file == '' | |
163 | + @uploaded_files << UploadedFile.create(:uploaded_data => file, :profile => profile, :parent => @parent, :last_changed_by => user) unless file == '' | |
158 | 164 | end |
159 | 165 | @errors = @uploaded_files.select { |f| f.errors.any? } |
160 | 166 | if @errors.any? | ... | ... |
app/controllers/my_profile/tasks_controller.rb
... | ... | @@ -9,7 +9,7 @@ class TasksController < MyProfileController |
9 | 9 | end |
10 | 10 | |
11 | 11 | def processed |
12 | - @tasks = Task.to(profile).finished.sort_by(&:created_at) | |
12 | + @tasks = Task.to(profile).closed.sort_by(&:created_at) | |
13 | 13 | end |
14 | 14 | |
15 | 15 | VALID_DECISIONS = [ 'finish', 'cancel', 'skip' ] | ... | ... |
app/controllers/public/account_controller.rb
... | ... | @@ -4,6 +4,7 @@ class AccountController < 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 < 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 < 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 < 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 < 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 < 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
1 | 1 | class CatalogController < PublicController |
2 | 2 | needs_profile |
3 | + no_design_blocks | |
3 | 4 | |
4 | 5 | before_filter :check_enterprise_and_environment |
5 | 6 | |
6 | 7 | def index |
7 | - @products = @profile.products.paginate(:order => 'name asc', :per_page => 9, :page => params[:page]) | |
8 | + @category = params[:level] ? ProductCategory.find(params[:level]) : nil | |
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]).order(:name) | |
8 | 11 | end |
9 | 12 | |
10 | 13 | protected | ... | ... |
app/controllers/public/content_viewer_controller.rb
... | ... | @@ -25,24 +25,26 @@ class ContentViewerController < ApplicationController |
25 | 25 | return |
26 | 26 | end |
27 | 27 | end |
28 | - | |
29 | - # page not found, give error | |
30 | - if @page.nil? | |
31 | - render_not_found(@path) | |
32 | - return | |
33 | - end | |
34 | 28 | end |
35 | 29 | |
36 | - if !@page.display_to?(user) | |
37 | - if profile.display_info_to?(user) || !profile.visible? | |
38 | - message = _('You are not allowed to view this content. You can contact the owner of this profile to request access then.') | |
30 | + if !@page.nil? && !@page.display_to?(user) | |
31 | + if !profile.public? | |
32 | + private_profile_partial_parameters | |
33 | + render :template => 'profile/_private_profile.rhtml', :status => 403 | |
34 | + else #if !profile.visible? | |
35 | + message = _('You are not allowed to view this content.') | |
36 | + message += ' ' + _('You can contact the owner of this profile to request access then.') | |
39 | 37 | render_access_denied(message) |
40 | - elsif !profile.public? | |
41 | - redirect_to :controller => 'profile', :action => 'index', :profile => profile.identifier | |
42 | 38 | end |
43 | 39 | return |
44 | 40 | end |
45 | 41 | |
42 | + # page not found, give error | |
43 | + if @page.nil? | |
44 | + render_not_found(@path) | |
45 | + return | |
46 | + end | |
47 | + | |
46 | 48 | if request.xhr? && params[:toolbar] |
47 | 49 | render :partial => 'article_toolbar' |
48 | 50 | return | ... | ... |
app/controllers/public/profile_controller.rb
... | ... | @@ -368,18 +368,13 @@ class ProfileController < PublicController |
368 | 368 | end |
369 | 369 | |
370 | 370 | def private_profile |
371 | - if profile.person? | |
372 | - @action = :add_friend | |
373 | - @message = _("The content here is available to %s's friends only.") % profile.short_name | |
374 | - else | |
375 | - @action = :join | |
376 | - @message = _('The contents in this community is available to members only.') | |
377 | - end | |
378 | - @no_design_blocks = true | |
371 | + private_profile_partial_parameters | |
379 | 372 | end |
380 | 373 | |
381 | 374 | def invisible_profile |
382 | - render_access_denied(_("This profile is inaccessible. You don't have the permission to view the content here."), _("Oops ... you cannot go ahead here")) | |
375 | + unless profile.is_template? | |
376 | + render_access_denied(_("This profile is inaccessible. You don't have the permission to view the content here."), _("Oops ... you cannot go ahead here")) | |
377 | + end | |
383 | 378 | end |
384 | 379 | |
385 | 380 | def per_page | ... | ... |
app/helpers/application_helper.rb
... | ... | @@ -1284,7 +1284,7 @@ module ApplicationHelper |
1284 | 1284 | (user.already_reported?(profile) ? |
1285 | 1285 | content_tag('a', text, :class => klass + ' disabled comment-footer comment-footer-link', :title => already_reported_message) : |
1286 | 1286 | link_to(text, url, :class => klass + ' comment-footer comment-footer-link', :title => report_profile_message) |
1287 | - ) + content_tag('span', ' | ', :class => 'comment-footer comment-footer-hide') | |
1287 | + ) + content_tag('span', ' ', :class => 'comment-footer comment-footer-hide') | |
1288 | 1288 | end |
1289 | 1289 | end |
1290 | 1290 | |
... | ... | @@ -1337,11 +1337,12 @@ module ApplicationHelper |
1337 | 1337 | counter = 0 |
1338 | 1338 | radios = klass.templates.map do |template| |
1339 | 1339 | counter += 1 |
1340 | - content_tag('li', labelled_radio_button(template.name, "#{field_name}[template_id]", template.id, counter==1)) | |
1340 | + content_tag('li', labelled_radio_button(link_to(template.name, template.url, :target => '_blank'), "#{field_name}[template_id]", template.id, counter==1)) | |
1341 | 1341 | end.join("\n") |
1342 | 1342 | |
1343 | - content_tag('div', content_tag('span', _('Template:')) + | |
1344 | - content_tag('ul', radios, :style => 'list-style: none; padding-left: 0; margin-top: 0.5em;'), | |
1343 | + content_tag('div', content_tag('label', _('Profile organization'), :for => 'template-options', :class => 'formlabel') + | |
1344 | + content_tag('p', _('Your profile will be created according to the selected template. Click on the options to view them.'), :style => 'margin: 5px 15px;padding: 0px 10px;') + | |
1345 | + content_tag('ul', radios, :style => 'list-style: none; padding-left: 20px; margin-top: 0.5em;'), | |
1345 | 1346 | :id => 'template-options', |
1346 | 1347 | :style => 'margin-top: 1em' |
1347 | 1348 | ) |
... | ... | @@ -1410,4 +1411,16 @@ module ApplicationHelper |
1410 | 1411 | options[:class] = "comment-footer comment-footer-link comment-footer-hide" |
1411 | 1412 | expirable_content_reference content, action, text, url, options |
1412 | 1413 | end |
1414 | + | |
1415 | + def private_profile_partial_parameters | |
1416 | + if profile.person? | |
1417 | + @action = :add_friend | |
1418 | + @message = _("The content here is available to %s's friends only.") % profile.short_name | |
1419 | + else | |
1420 | + @action = :join | |
1421 | + @message = _('The contents in this community is available to members only.') | |
1422 | + end | |
1423 | + @no_design_blocks = true | |
1424 | + end | |
1425 | + | |
1413 | 1426 | end | ... | ... |
app/helpers/catalog_helper.rb
... | ... | @@ -3,4 +3,28 @@ module CatalogHelper |
3 | 3 | include DisplayHelper |
4 | 4 | include ManageProductsHelper |
5 | 5 | |
6 | + def breadcrumb(category) | |
7 | + start = link_to(_('Start'), {:action => 'index'}) | |
8 | + ancestors = category.ancestors.map { |c| link_to(c.name, {:action => 'index', :level => c.id}) }.reverse | |
9 | + current_level = content_tag('strong', category.name) | |
10 | + all_items = [start] + ancestors + [current_level] | |
11 | + content_tag('div', all_items.join(' → '), :id => 'breadcrumb') | |
12 | + end | |
13 | + | |
14 | + def category_link(category, sub = false) | |
15 | + count = profile.products.from_category(category).count | |
16 | + name = truncate(category.name, :length => 22 - count.to_s.size) | |
17 | + link_name = sub ? name : content_tag('strong', name) | |
18 | + link = link_to(link_name, {:action => 'index', :level => category.id}, :title => category.name) | |
19 | + content_tag('li', "#{link} (#{count})") if count > 0 | |
20 | + end | |
21 | + | |
22 | + def category_sub_links(category) | |
23 | + sub_categories = [] | |
24 | + category.children.order(:name).each do |sub_category| | |
25 | + sub_categories << category_link(sub_category, true) | |
26 | + end | |
27 | + content_tag('ul', sub_categories) if sub_categories.size > 1 | |
28 | + end | |
29 | + | |
6 | 30 | end | ... | ... |
app/helpers/content_viewer_helper.rb
... | ... | @@ -26,7 +26,7 @@ module ContentViewerHelper |
26 | 26 | end |
27 | 27 | title << content_tag('span', |
28 | 28 | content_tag('span', show_date(article.published_at), :class => 'date') + |
29 | - content_tag('span', [_(", by %s") % link_to(article.author_name, article.author.url)], :class => 'author') + | |
29 | + content_tag('span', [_(", by %s") % link_to(article.author_name, article.author_url)], :class => 'author') + | |
30 | 30 | content_tag('span', comments, :class => 'comments'), |
31 | 31 | :class => 'created-at' |
32 | 32 | ) | ... | ... |
app/helpers/display_helper.rb
... | ... | @@ -8,6 +8,14 @@ module DisplayHelper |
8 | 8 | opts |
9 | 9 | end |
10 | 10 | |
11 | + def themed_path(file) | |
12 | + if File.exists?(File.join(Rails.root, 'public', theme_path, file)) | |
13 | + File.join(theme_path, file) | |
14 | + else | |
15 | + file | |
16 | + end | |
17 | + end | |
18 | + | |
11 | 19 | def image_link_to_product(product, opts={}) |
12 | 20 | return _('No product') unless product |
13 | 21 | target = product_path(product) | ... | ... |
app/helpers/folder_helper.rb
... | ... | @@ -52,8 +52,8 @@ module FolderHelper |
52 | 52 | end |
53 | 53 | end |
54 | 54 | |
55 | - def icon_for_new_article(type) | |
56 | - "icon-new icon-new%s" % type.constantize.icon_name | |
55 | + def icon_for_new_article(klass) | |
56 | + "icon-new icon-new%s" % klass.icon_name | |
57 | 57 | end |
58 | 58 | |
59 | 59 | def custom_options_for_article(article) | ... | ... |
app/helpers/forms_helper.rb
... | ... | @@ -142,6 +142,38 @@ 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 | + | |
145 | 177 | def date_field(name, value, format = '%Y-%m-%d', datepicker_options = {}, html_options = {}) |
146 | 178 | datepicker_options[:disabled] ||= false |
147 | 179 | datepicker_options[:alt_field] ||= '' | ... | ... |
app/helpers/language_helper.rb
... | ... | @@ -13,19 +13,20 @@ module LanguageHelper |
13 | 13 | |
14 | 14 | alias :calendar_date_select_language :tinymce_language |
15 | 15 | |
16 | - def language_chooser(environment, options = {}) | |
17 | - return if environment.locales.size < 2 | |
16 | + def language_chooser(environment=nil, options = {}) | |
17 | + locales = environment.nil? ? Noosfero.locales : environment.locales | |
18 | + return if locales.size < 2 | |
18 | 19 | current = language |
19 | 20 | separator = options[:separator] || ' — ' |
20 | 21 | |
21 | 22 | if options[:element] == 'dropdown' |
22 | 23 | select_tag('lang', |
23 | - options_for_select(environment.locales.map{|code,name| [name, code]}, current), | |
24 | + options_for_select(locales.map{|code,name| [name, code]}, current), | |
24 | 25 | :onchange => "document.location.href= #{url_for(params.merge(:lang => 'LANGUAGE')).inspect}.replace(/LANGUAGE/, this.value) ;", |
25 | 26 | :help => _('The language you choose here is the language used for options, buttons, etc. It does not affect the language of the content created by other users.') |
26 | 27 | ) |
27 | 28 | else |
28 | - languages = environment.locales.map do |code,name| | |
29 | + languages = locales.map do |code,name| | |
29 | 30 | if code == current |
30 | 31 | content_tag('strong', name) |
31 | 32 | else | ... | ... |
app/models/approve_article.rb
... | ... | @@ -48,7 +48,7 @@ class ApproveArticle < Task |
48 | 48 | end |
49 | 49 | |
50 | 50 | def perform |
51 | - article.copy!(:name => name, :abstract => abstract, :body => body, :profile => target, :reference_article => article, :parent => article_parent, :highlighted => highlighted, :source => article.source) | |
51 | + article.copy!(:name => name, :abstract => abstract, :body => body, :profile => target, :reference_article => article, :parent => article_parent, :highlighted => highlighted, :source => article.source, :last_changed_by_id => article.author_id) | |
52 | 52 | end |
53 | 53 | |
54 | 54 | def title | ... | ... |
app/models/article.rb
... | ... | @@ -13,10 +13,18 @@ class Article < ActiveRecord::Base |
13 | 13 | # xss_terminate plugin can't sanitize array fields |
14 | 14 | before_save :sanitize_tag_list |
15 | 15 | |
16 | + before_create do |article| | |
17 | + if article.last_changed_by_id | |
18 | + article.author_name = Person.find(article.last_changed_by_id).name | |
19 | + end | |
20 | + end | |
21 | + | |
16 | 22 | belongs_to :profile |
17 | 23 | validates_presence_of :profile_id, :name |
18 | 24 | validates_presence_of :slug, :path, :if => lambda { |article| !article.name.blank? } |
19 | 25 | |
26 | + validates_length_of :name, :maximum => 150 | |
27 | + | |
20 | 28 | validates_uniqueness_of :slug, :scope => ['profile_id', 'parent_id'], :message => N_('The title (article name) is already being used by another article, please use another title.'), :if => lambda { |article| !article.slug.blank? } |
21 | 29 | |
22 | 30 | belongs_to :last_changed_by, :class_name => 'Person', :foreign_key => 'last_changed_by_id' |
... | ... | @@ -289,7 +297,7 @@ class Article < ActiveRecord::Base |
289 | 297 | if last_comment |
290 | 298 | {:date => last_comment.created_at, :author_name => last_comment.author_name, :author_url => last_comment.author_url} |
291 | 299 | else |
292 | - {:date => updated_at, :author_name => author.name, :author_url => author.url} | |
300 | + {:date => updated_at, :author_name => author_name, :author_url => author_url} | |
293 | 301 | end |
294 | 302 | end |
295 | 303 | |
... | ... | @@ -441,7 +449,7 @@ class Article < ActiveRecord::Base |
441 | 449 | end |
442 | 450 | |
443 | 451 | def allow_post_content?(user = nil) |
444 | - user && (user.has_permission?('post_content', profile) || allow_publish_content?(user) && (user == self.creator)) | |
452 | + user && (user.has_permission?('post_content', profile) || allow_publish_content?(user) && (user == author)) | |
445 | 453 | end |
446 | 454 | |
447 | 455 | def allow_publish_content?(user = nil) |
... | ... | @@ -496,7 +504,6 @@ class Article < ActiveRecord::Base |
496 | 504 | :slug, |
497 | 505 | :updated_at, |
498 | 506 | :created_at, |
499 | - :last_changed_by_id, | |
500 | 507 | :version, |
501 | 508 | :lock_version, |
502 | 509 | :type, |
... | ... | @@ -539,15 +546,24 @@ class Article < ActiveRecord::Base |
539 | 546 | end |
540 | 547 | |
541 | 548 | def author |
542 | - if reference_article | |
543 | - reference_article.author | |
549 | + if versions.empty? | |
550 | + last_changed_by | |
544 | 551 | else |
545 | - last_changed_by || profile | |
552 | + author_id = versions.first.last_changed_by_id | |
553 | + Person.exists?(author_id) ? Person.find(author_id) : nil | |
546 | 554 | end |
547 | 555 | end |
548 | 556 | |
549 | 557 | def author_name |
550 | - setting[:author_name].blank? ? author.name : setting[:author_name] | |
558 | + author ? author.name : (setting[:author_name] || _('Unknown')) | |
559 | + end | |
560 | + | |
561 | + def author_url | |
562 | + author ? author.url : nil | |
563 | + end | |
564 | + | |
565 | + def author_id | |
566 | + author ? author.id : nil | |
551 | 567 | end |
552 | 568 | |
553 | 569 | alias :active_record_cache_key :cache_key |
... | ... | @@ -572,11 +588,6 @@ class Article < ActiveRecord::Base |
572 | 588 | truncate sanitize_html(self.lead), :length => 170, :omission => '...' |
573 | 589 | end |
574 | 590 | |
575 | - def creator | |
576 | - creator_id = versions[0][:last_changed_by_id] | |
577 | - creator_id && Profile.find(creator_id) | |
578 | - end | |
579 | - | |
580 | 591 | def notifiable? |
581 | 592 | false |
582 | 593 | end | ... | ... |
app/models/category.rb
... | ... | @@ -13,6 +13,16 @@ class Category < ActiveRecord::Base |
13 | 13 | {:conditions => ['parent_id is null and environment_id = ?', environment.id ]} |
14 | 14 | } |
15 | 15 | |
16 | + named_scope :on_level, lambda { |parent| {:conditions => {:parent_id => parent}} } | |
17 | + | |
18 | + named_scope :sub_categories, lambda { |category| | |
19 | + {:conditions => ['categories.path LIKE ? AND categories.id != ?', "%#{category.slug}%", category.id]} | |
20 | + } | |
21 | + | |
22 | + named_scope :sub_tree, lambda { |category| | |
23 | + {:conditions => ['categories.path LIKE ?', "%#{category.slug}%"]} | |
24 | + } | |
25 | + | |
16 | 26 | acts_as_filesystem |
17 | 27 | |
18 | 28 | has_many :article_categorizations, :dependent => :destroy | ... | ... |
app/models/comment.rb
... | ... | @@ -74,6 +74,10 @@ class Comment < ActiveRecord::Base |
74 | 74 | self.find(:all, :order => 'created_at desc, id desc', :limit => limit) |
75 | 75 | end |
76 | 76 | |
77 | + def notification_emails | |
78 | + self.article.profile.notification_emails - [self.author_email || self.email] | |
79 | + end | |
80 | + | |
77 | 81 | after_save :notify_article |
78 | 82 | after_destroy :notify_article |
79 | 83 | def notify_article |
... | ... | @@ -114,7 +118,7 @@ class Comment < ActiveRecord::Base |
114 | 118 | |
115 | 119 | def notify_by_mail |
116 | 120 | if source.kind_of?(Article) && article.notify_comments? |
117 | - if !article.profile.notification_emails.empty? | |
121 | + if !notification_emails.empty? | |
118 | 122 | Comment::Notifier.deliver_mail(self) |
119 | 123 | end |
120 | 124 | emails = article.followers - [author_email] |
... | ... | @@ -174,7 +178,7 @@ class Comment < ActiveRecord::Base |
174 | 178 | class Notifier < ActionMailer::Base |
175 | 179 | def mail(comment) |
176 | 180 | profile = comment.article.profile |
177 | - recipients profile.notification_emails | |
181 | + recipients comment.notification_emails | |
178 | 182 | from "#{profile.environment.name} <#{profile.environment.contact_email}>" |
179 | 183 | subject _("[%s] you got a new comment!") % [profile.environment.name] |
180 | 184 | body :recipient => profile.nickname || profile.name, |
... | ... | @@ -224,6 +228,7 @@ class Comment < ActiveRecord::Base |
224 | 228 | def spam! |
225 | 229 | self.spam = true |
226 | 230 | self.save! |
231 | + SpammerLogger.log(ip_address, self) | |
227 | 232 | Delayed::Job.enqueue(CommentHandler.new(self.id, :marked_as_spam)) |
228 | 233 | self |
229 | 234 | end | ... | ... |
app/models/enterprise_homepage.rb
app/models/environment.rb
... | ... | @@ -233,8 +233,10 @@ class Environment < 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 | - settings_items :message_for_disabled_enterprise, :type => String | |
238 | + settings_items :message_for_disabled_enterprise, :type => String, | |
239 | + :default => _('This enterprise needs to be enabled.') | |
238 | 240 | settings_items :location, :type => String |
239 | 241 | settings_items :layout_template, :type => String, :default => 'default' |
240 | 242 | settings_items :homepage, :type => String |
... | ... | @@ -616,12 +618,10 @@ class Environment < ActiveRecord::Base |
616 | 618 | end |
617 | 619 | |
618 | 620 | def top_url |
619 | - protocol = 'http' | |
620 | - result = "#{protocol}://#{default_hostname}" | |
621 | - if Noosfero.url_options.has_key?(:port) | |
622 | - result << ':' << Noosfero.url_options[:port].to_s | |
623 | - end | |
624 | - 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 | |
625 | 625 | end |
626 | 626 | |
627 | 627 | def to_s | ... | ... |
app/models/event.rb
... | ... | @@ -38,7 +38,7 @@ class Event < Article |
38 | 38 | filter_iframes :body, :link, :address, :whitelist => lambda { profile && profile.environment && profile.environment.trusted_sites_for_iframe } |
39 | 39 | |
40 | 40 | def self.description |
41 | - _('A calendar event') | |
41 | + _('A calendar event.') | |
42 | 42 | end |
43 | 43 | |
44 | 44 | def self.short_description | ... | ... |
app/models/organization.rb
... | ... | @@ -78,6 +78,8 @@ class Organization < Profile |
78 | 78 | country |
79 | 79 | tag_list |
80 | 80 | template_id |
81 | + district | |
82 | + address_reference | |
81 | 83 | ] |
82 | 84 | |
83 | 85 | def self.fields |
... | ... | @@ -96,8 +98,8 @@ class Organization < Profile |
96 | 98 | [] |
97 | 99 | end |
98 | 100 | |
99 | - N_('Display name'); N_('Description'); N_('Contact person'); N_('Contact email'); N_('Acronym'); N_('Foundation year'); N_('Legal form'); N_('Economic activity'); N_('Management information'); N_('Tag list') | |
100 | - settings_items :display_name, :description, :contact_person, :contact_email, :acronym, :foundation_year, :legal_form, :economic_activity, :management_information | |
101 | + N_('Display name'); N_('Description'); N_('Contact person'); N_('Contact email'); N_('Acronym'); N_('Foundation year'); N_('Legal form'); N_('Economic activity'); N_('Management information'); N_('Tag list'); N_('District'); N_('Address reference') | |
102 | + settings_items :display_name, :description, :contact_person, :contact_email, :acronym, :foundation_year, :legal_form, :economic_activity, :management_information, :district, :address_reference | |
101 | 103 | |
102 | 104 | validates_format_of :foundation_year, :with => Noosfero::Constants::INTEGER_FORMAT |
103 | 105 | validates_format_of :contact_email, :with => Noosfero::Constants::EMAIL_FORMAT, :if => (lambda { |org| !org.contact_email.blank? }) | ... | ... |
app/models/person.rb
... | ... | @@ -67,6 +67,9 @@ class Person < Profile |
67 | 67 | :order => 'total DESC', |
68 | 68 | :conditions => ['action_tracker.created_at >= ? OR action_tracker.id IS NULL', ActionTracker::Record::RECENT_DELAY.days.ago] |
69 | 69 | |
70 | + named_scope :abusers, :joins => :abuse_complaints, :conditions => ['tasks.status = 3'], :select => 'DISTINCT profiles.*' | |
71 | + named_scope :non_abusers, :joins => "LEFT JOIN tasks ON profiles.id = tasks.requestor_id AND tasks.type='AbuseComplaint'", :conditions => ["tasks.status != 3 OR tasks.id is NULL"], :select => "DISTINCT profiles.*" | |
72 | + | |
70 | 73 | after_destroy do |person| |
71 | 74 | Friendship.find(:all, :conditions => { :friend_id => person.id}).each { |friendship| friendship.destroy } |
72 | 75 | end |
... | ... | @@ -144,6 +147,9 @@ class Person < Profile |
144 | 147 | contact_phone |
145 | 148 | contact_information |
146 | 149 | description |
150 | + image | |
151 | + district | |
152 | + address_reference | |
147 | 153 | ] |
148 | 154 | |
149 | 155 | validates_multiparameter_assignments |
... | ... | @@ -198,8 +204,8 @@ class Person < Profile |
198 | 204 | N_('Education'); N_('Custom education'); N_('Custom area of study'); |
199 | 205 | settings_items :formation, :custom_formation, :custom_area_of_study |
200 | 206 | |
201 | - N_('Contact information'); N_('City'); N_('State'); N_('Country'); N_('Sex'); N_('Zip code') | |
202 | - settings_items :photo, :contact_information, :sex, :city, :state, :country, :zip_code | |
207 | + N_('Contact information'); N_('City'); N_('State'); N_('Country'); N_('Sex'); N_('Zip code'); N_('District'); N_('Address reference') | |
208 | + settings_items :photo, :contact_information, :sex, :city, :state, :country, :zip_code, :district, :address_reference | |
203 | 209 | |
204 | 210 | extend SetProfileRegionFromCityState::ClassMethods |
205 | 211 | set_profile_region_from_city_state |
... | ... | @@ -440,6 +446,10 @@ class Person < Profile |
440 | 446 | abuse_report.save! |
441 | 447 | end |
442 | 448 | |
449 | + def abuser? | |
450 | + AbuseComplaint.finished.where(:requestor_id => self).count > 0 | |
451 | + end | |
452 | + | |
443 | 453 | def control_panel_settings_button |
444 | 454 | {:title => _('Edit Profile'), :icon => 'edit-profile'} |
445 | 455 | end | ... | ... |
app/models/product.rb
... | ... | @@ -23,6 +23,10 @@ class Product < ActiveRecord::Base |
23 | 23 | |
24 | 24 | named_scope :more_recent, :order => "created_at DESC" |
25 | 25 | |
26 | + named_scope :from_category, lambda { |category| | |
27 | + {:joins => :product_category, :conditions => ['categories.path LIKE ?', "%#{category.slug}%"]} if category | |
28 | + } | |
29 | + | |
26 | 30 | after_update :save_image |
27 | 31 | |
28 | 32 | def lat | ... | ... |
app/models/profile.rb
... | ... | @@ -141,6 +141,10 @@ class Profile < ActiveRecord::Base |
141 | 141 | |
142 | 142 | acts_as_having_settings :field => :data |
143 | 143 | |
144 | + def settings | |
145 | + data | |
146 | + end | |
147 | + | |
144 | 148 | settings_items :redirect_l10n, :type => :boolean, :default => false |
145 | 149 | settings_items :public_content, :type => :boolean, :default => true |
146 | 150 | settings_items :description |
... | ... | @@ -229,7 +233,7 @@ class Profile < ActiveRecord::Base |
229 | 233 | if myregion |
230 | 234 | myregion.hierarchy.reverse.first(2).map(&:name).join(separator) |
231 | 235 | else |
232 | - %w[address city state country_name zip_code ].map {|item| (self.respond_to?(item) && !self.send(item).blank?) ? self.send(item) : nil }.compact.join(separator) | |
236 | + %w[address district city state country_name zip_code ].map {|item| (self.respond_to?(item) && !self.send(item).blank?) ? self.send(item) : nil }.compact.join(separator) | |
233 | 237 | end |
234 | 238 | end |
235 | 239 | |
... | ... | @@ -463,6 +467,10 @@ class Profile < ActiveRecord::Base |
463 | 467 | { :profile => identifier, :controller => 'profile_editor', :action => 'index' } |
464 | 468 | end |
465 | 469 | |
470 | + def tasks_url | |
471 | + { :profile => identifier, :controller => 'tasks', :action => 'index', :host => default_hostname } | |
472 | + end | |
473 | + | |
466 | 474 | def leave_url(reload = false) |
467 | 475 | { :profile => identifier, :controller => 'profile', :action => 'leave', :reload => reload } |
468 | 476 | end |
... | ... | @@ -694,7 +702,7 @@ private :generate_url, :url_options |
694 | 702 | def custom_footer_expanded |
695 | 703 | footer = custom_footer |
696 | 704 | if footer |
697 | - %w[contact_person contact_email contact_phone location address economic_activity city state country zip_code].each do |att| | |
705 | + %w[contact_person contact_email contact_phone location address district address_reference economic_activity city state country zip_code].each do |att| | |
698 | 706 | if self.respond_to?(att) && footer.match(/\{[^{]*#{att}\}/) |
699 | 707 | if !self.send(att).nil? && !self.send(att).blank? |
700 | 708 | footer = footer.gsub(/\{([^{]*)#{att}\}/, '\1' + self.send(att)) | ... | ... |
app/models/raw_html_article.rb
... | ... | @@ -5,11 +5,11 @@ class RawHTMLArticle < TextArticle |
5 | 5 | end |
6 | 6 | |
7 | 7 | def self.short_description |
8 | - _('Raw HTML text article.') | |
8 | + _('Raw HTML text article') | |
9 | 9 | end |
10 | 10 | |
11 | 11 | def self.description |
12 | - _('Allows HTML without filter (only for admins)') | |
12 | + _('Allows HTML without filter (only for admins).') | |
13 | 13 | end |
14 | 14 | |
15 | 15 | xss_terminate :only => [ ] | ... | ... |
... | ... | @@ -0,0 +1,24 @@ |
1 | +class SpammerLogger < Logger | |
2 | + @logpath = File.join(Rails.root, 'log', "#{ENV['RAILS_ENV']}_spammers.log") | |
3 | + @logger = new(@logpath) | |
4 | + | |
5 | + def self.log(spammer_ip, object=nil) | |
6 | + if object | |
7 | + if object.kind_of?(Comment) | |
8 | + @logger << "[#{Time.now.strftime('%F %T %z')}] Comment-id: #{object.id} IP: #{spammer_ip}\n" | |
9 | + end | |
10 | + else | |
11 | + @logger << "[#{Time.now.strftime('%F %T %z')}] IP: #{spammer_ip}\n" | |
12 | + end | |
13 | + end | |
14 | + | |
15 | + def self.clean_log | |
16 | + File.delete(@logpath) if File.exists?(@logpath) | |
17 | + end | |
18 | + | |
19 | + def self.reload_log | |
20 | + clean_log | |
21 | + @logger = new(@logpath) | |
22 | + end | |
23 | + | |
24 | +end | ... | ... |
app/models/tags_block.rb
... | ... | @@ -20,7 +20,8 @@ class TagsBlock < 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 < 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 | 38 | "\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 ) + | |
39 | + tag_cloud( tags, tagname_option, url, :max_size => 16, :min_size => 9 ) + | |
37 | 40 | "\n</div><!-- end class='tag_cloud' -->\n"; |
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/task.rb
... | ... | @@ -267,7 +267,10 @@ class Task < ActiveRecord::Base |
267 | 267 | end |
268 | 268 | |
269 | 269 | named_scope :pending, :conditions => { :status => Task::Status::ACTIVE } |
270 | - named_scope :finished, :conditions => { :status => [Task::Status::CANCELLED, Task::Status::FINISHED] } | |
270 | + named_scope :hidden, :conditions => { :status => Task::Status::HIDDEN } | |
271 | + named_scope :finished, :conditions => { :status => Task::Status::FINISHED } | |
272 | + named_scope :canceled, :conditions => { :status => Task::Status::CANCELLED } | |
273 | + named_scope :closed, :conditions => { :status => [Task::Status::CANCELLED, Task::Status::FINISHED] } | |
271 | 274 | named_scope :opened, :conditions => { :status => [Task::Status::ACTIVE, Task::Status::HIDDEN] } |
272 | 275 | named_scope :of, lambda { |type| conditions = type ? "type LIKE '#{type}'" : "1=1"; {:conditions => [conditions]} } |
273 | 276 | named_scope :order_by, lambda { |attribute, ord| {:order => "#{attribute} #{ord}"} } | ... | ... |
app/models/task_mailer.rb
... | ... | @@ -14,7 +14,7 @@ class TaskMailer < ActionMailer::Base |
14 | 14 | |
15 | 15 | recipients task.target.notification_emails |
16 | 16 | |
17 | - url_for_tasks_list = task.target.kind_of?(Environment) ? '' : url_for(task.target.url.merge(:controller => 'tasks', :action => 'index')) | |
17 | + url_for_tasks_list = task.target.kind_of?(Environment) ? '' : url_for(task.target.tasks_url) | |
18 | 18 | |
19 | 19 | from self.class.generate_from(task) |
20 | 20 | subject '[%s] %s' % [task.environment.name, task.target_notification_description] | ... | ... |
app/models/tiny_mce_article.rb
app/models/user.rb
... | ... | @@ -15,7 +15,7 @@ class User < 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 |
... | ... | @@ -31,7 +31,7 @@ class User < ActiveRecord::Base |
31 | 31 | after_create do |user| |
32 | 32 | user.person ||= Person.new |
33 | 33 | user.person.attributes = user.person_data.merge(:identifier => user.login, :user => user, :environment_id => user.environment_id) |
34 | - user.person.name ||= user.login | |
34 | + user.person.name ||= user.name | |
35 | 35 | user.person.visible = false unless user.activated? |
36 | 36 | user.person.save! |
37 | 37 | if user.environment.enabled?('skip_new_user_email_confirmation') |
... | ... | @@ -116,10 +116,11 @@ class User < 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 | -<%= error_messages_for :user, :person %> | |
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 | + | |
8 | +<% @profile_data = @person %> | |
9 | + | |
10 | +<%= error_messages_for :user, :person, :header_message => _('The account could not be created') %> | |
11 | + | |
12 | +<% labelled_form_for :user, @user, :html => { :multipart => true, :id => 'signup-form', :honeypot => true } do |f| %> | |
2 | 13 | |
3 | -<% labelled_form_for :user, @user, :html => { :multipart => true, :id => 'signup-form' } do |f| %> | |
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> | |
4 | 25 | |
5 | 26 | <%= hidden_field_tag :invitation_code, @invitation_code %> |
6 | 27 | |
7 | 28 | <div id='signup-form-header'> |
8 | 29 | |
9 | - <span id="signup-domain"><%= environment.default_hostname %>/</span> | |
10 | - <div id='signup-login'> | |
11 | - <div id='signup-login-field'> | |
12 | - <%= required f.text_field(:login, :onchange => 'this.value = convToValidLogin(this.value);', :rel => s_('signup|Login')) %> | |
13 | - <div id='url-check'><p> </p></div> | |
30 | + <div id='signup-formfield-group'> | |
31 | + <%= label(:user, :login, _('Username'), {:class => 'formlabel'}) %> | |
32 | + <span id="signup-domain"><%= environment.default_hostname %>/</span> | |
33 | + <div id='signup-login'> | |
34 | + <div id='signup-login-field' class='formfield'> | |
35 | + <%= required text_field(:user, :login, :id => 'user_login', | |
36 | + :onchange => 'this.value = convToValidUsername(this.value);') %> | |
37 | + <div id='url-check'><p> </p></div> | |
38 | + </div> | |
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') %> | |
40 | + <br style="clear: both;" /> | |
14 | 41 | </div> |
15 | - <%= 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') %> | |
16 | - <br style="clear: both;" /> | |
17 | 42 | </div> |
18 | 43 | <%= observe_field 'user_login', |
19 | 44 | :url => { :action => 'check_url' }, |
... | ... | @@ -26,20 +51,19 @@ |
26 | 51 | |
27 | 52 | <div id='signup-password'> |
28 | 53 | <%= required f.password_field(:password, :id => 'user_pw') %> |
29 | - <%= f.text_field(:password_clear, :value => _('password')) %> | |
30 | 54 | <%= content_tag(:small,_('Choose a password that you can remember easily. It must have at least 4 characters.'), :id => 'password-balloon') %> |
31 | 55 | <div id='fake-check'><p> </p></div> |
32 | 56 | </div> |
33 | 57 | |
34 | 58 | <div id='signup-password-confirmation'> |
35 | 59 | <%= required f.password_field(:password_confirmation) %> |
36 | - <%= f.text_field(:password_confirmation_clear, :value => _('password confirmation')) %> | |
60 | + <%= content_tag(:small,_('We need to be sure that you filled in your password correctly. Confirm you password.'), :id => 'password-confirmation-balloon') %> | |
37 | 61 | <div id='password-check'><p> </p></div> |
38 | 62 | </div> |
39 | 63 | |
40 | 64 | <div id='signup-email'> |
41 | - <%= required f.text_field(:email, :rel => _('e-Mail')) %> | |
42 | - <%= content_tag(:small,_('This e-mail address will be used to contact you.')) %> | |
65 | + <%= required f.text_field(:email) %> | |
66 | + <%= content_tag(:small,_('This e-mail address will be used to contact you.'), :id => 'email-balloon') %> | |
43 | 67 | <div id='email-check'><p> </p></div> |
44 | 68 | </div> |
45 | 69 | <%= observe_field "user_email", |
... | ... | @@ -62,21 +86,23 @@ |
62 | 86 | }" |
63 | 87 | %> |
64 | 88 | |
65 | - <%= label :profile_data, :name %> | |
66 | - <%= required text_field(:profile_data, :name, :rel => _('Full name')) %> | |
89 | + <div id='signup-name'> | |
90 | + <%= labelled_form_field(_('Full name'), text_field(:profile_data, :name)) %> | |
91 | + <%= content_tag(:small,_('Tell us your name, it will be used to identify yourself.'), :id => 'name-balloon') %> | |
92 | + </div> | |
67 | 93 | |
68 | 94 | </div> |
69 | 95 | |
70 | 96 | <div id="signup-form-profile"> |
71 | 97 | |
72 | - <%= template_options(Person, 'profile_data') %> | |
73 | - | |
74 | 98 | <% labelled_fields_for :profile_data, @person do |f| %> |
75 | 99 | <%= render :partial => 'profile_editor/person_form', :locals => {:f => f} %> |
76 | 100 | <% end %> |
77 | 101 | |
78 | 102 | <%= @plugins.dispatch(:signup_extra_contents).collect { |content| instance_eval(&content) }.join("") %> |
79 | 103 | |
104 | + <%= template_options(Person, 'profile_data') %> | |
105 | + | |
80 | 106 | <% unless @terms_of_use.blank? %> |
81 | 107 | <div id='terms-of-use-box' class='formfieldline'> |
82 | 108 | <%= labelled_check_box(_('I accept the %s') % link_to(_('terms of use'), {:controller => 'home', :action => 'terms'}, :target => '_blank'), 'user[terms_accepted]') %> |
... | ... | @@ -91,6 +117,8 @@ |
91 | 117 | <% end %> |
92 | 118 | </div> |
93 | 119 | |
120 | +<%= recaptcha_tags :ajax => true, :display => {:theme => 'clean'} if @block_bot %> | |
121 | + | |
94 | 122 | <p style="text-align: center"> |
95 | 123 | <%= submit_button('save', _('Create my account')) %> |
96 | 124 | </p> |
... | ... | @@ -99,70 +127,59 @@ |
99 | 127 | |
100 | 128 | <script type="text/javascript"> |
101 | 129 | jQuery(function($) { |
130 | + | |
131 | + $('#signup-form #user_login').css('width', 335 - $('#signup-domain').outerWidth()); | |
132 | + | |
102 | 133 | $('#signup-form input[type=text], #signup-form textarea').each(function() { |
103 | - if ($(this).attr('rel')) var default_value = $(this).attr('rel').toLowerCase(); | |
104 | - if ($(this).val() == '') $(this).val(default_value); | |
105 | - $(this).bind('focus', function() { | |
106 | - if ($(this).val() == default_value) $(this).val(''); | |
107 | - }); | |
108 | 134 | $(this).bind('blur', function() { |
109 | 135 | if ($(this).val() == '') { |
110 | - $(this).val(default_value); | |
111 | 136 | $(this).removeClass('filled-in'); |
112 | 137 | } |
113 | 138 | else $(this).addClass('filled-in'); |
114 | 139 | }); |
115 | 140 | }); |
116 | 141 | |
117 | - $('#signup-form').bind('submit', function() { | |
118 | - $('#signup-form input[type=text], #signup-form textarea').each(function() { | |
119 | - if ($(this).attr('rel')) var default_value = $(this).attr('rel').toLowerCase(); | |
120 | - if ($(this).val() == default_value) $(this).val(''); | |
121 | - }); | |
122 | - return true; | |
123 | - }); | |
124 | - | |
125 | - $('#user_password_clear, #user_password_confirmation_clear').show(); | |
126 | - $('#user_password_clear, #user_password_confirmation_clear').unbind(); | |
127 | - $('#user_pw, #user_password_confirmation').hide(); | |
128 | - $('#user_password_clear').focus(function() { | |
129 | - $(this).hide(); | |
130 | - $('#user_pw').show(); | |
131 | - $('#user_pw').focus(); | |
132 | - }); | |
133 | 142 | $('#user_pw').focus(function() { |
134 | 143 | $('#password-balloon').fadeIn('slow'); |
135 | 144 | }); |
136 | - $('#user_pw').blur(function() { | |
137 | - if ($(this).val() == '') { | |
138 | - $('#user_password_clear').show(); | |
139 | - $(this).hide(); | |
140 | - } | |
141 | - }); | |
142 | - $('#user_password_confirmation_clear').focus(function() { | |
143 | - $(this).hide(); | |
144 | - $('#user_password_confirmation').show(); | |
145 | - $('#user_password_confirmation').focus(); | |
145 | + $('#user_password_confirmation').focus(function() { | |
146 | + $('#password-confirmation-balloon').fadeIn('slow'); | |
146 | 147 | }); |
147 | 148 | $('#user_password_confirmation, #user_pw').blur(function() { |
148 | - if ($('#user_password_confirmation').val() == '') { | |
149 | - $('#user_password_confirmation_clear').show(); | |
150 | - $('#user_password_confirmation').hide(); | |
151 | - } else if ($('#user_password_confirmation').val() == $('#user_pw').val()) { | |
152 | - $('#user_password_confirmation').addClass('validated').removeClass('invalid'); | |
153 | - $('#user_pw').removeClass('invalid_input').addClass('valid_input'); | |
154 | - $('#password-check').html("<p> </p>"); | |
155 | - } else if ($('#user_password_confirmation').val() != $('#user_pw').val()) { | |
156 | - $('#user_password_confirmation').removeClass('validated').addClass('invalid'); | |
157 | - $('#user_pw').addClass('invalid_input').removeClass('valid_input'); | |
158 | - $('#password-check').html("<p><span class='invalid'><%= _('Passwords don\'t match') %></span></p>"); | |
149 | + if ($('#user_password_confirmation').val() != '') { | |
150 | + if ($('#user_password_confirmation').val() == $('#user_pw').val()) { | |
151 | + $('#user_password_confirmation').addClass('validated').removeClass('invalid'); | |
152 | + $('#user_pw').removeClass('invalid_input').addClass('valid_input'); | |
153 | + $('#password-check').html("<p> </p>"); | |
154 | + } else if ($('#user_password_confirmation').val() != $('#user_pw').val()) { | |
155 | + $('#user_password_confirmation').removeClass('validated').addClass('invalid'); | |
156 | + $('#user_pw').addClass('invalid_input').removeClass('valid_input'); | |
157 | + $('#password-check').html("<p><span class='invalid'><%= _('Passwords don\'t match') %></span></p>"); | |
158 | + } | |
159 | 159 | } |
160 | 160 | $('#password-balloon').fadeOut('slow'); |
161 | + $('#password-confirmation-balloon').fadeOut('slow'); | |
161 | 162 | }); |
162 | 163 | $('#user_login').focus(function() { |
163 | 164 | $('#signup-balloon').fadeIn('slow'); |
164 | 165 | }); |
165 | 166 | $('#user_login').blur(function() { $('#signup-balloon').fadeOut('slow'); }); |
166 | 167 | $('#signup-form').validate({ rules: { 'user[email]': { email: true } }, messages: { 'user[email]' : '' } }); |
168 | + $('#user_email').focus(function() { | |
169 | + $('#email-balloon').fadeIn('slow'); | |
170 | + }); | |
171 | + $('#user_email').blur(function() { | |
172 | + $('#email-balloon').fadeOut('slow'); | |
173 | + }); | |
174 | + $('#profile_data_name').focus(function() { | |
175 | + $('#name-balloon').fadeIn('slow'); | |
176 | + }); | |
177 | + $('#profile_data_name').blur(function() { | |
178 | + $('#name-balloon').fadeOut('slow'); | |
179 | + if ($(this).val() == '') { | |
180 | + $(this).removeClass('validated'); | |
181 | + } | |
182 | + else $(this).addClass('validated'); | |
183 | + }); | |
167 | 184 | }); |
168 | 185 | </script> | ... | ... |
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/catalog/index.rhtml
1 | 1 | <% extra_content = [] %> |
2 | 2 | <% extra_content_list = [] %> |
3 | 3 | |
4 | -<ul id="product-list"> | |
5 | - <li><h1><%= _('Products/Services') %></h1></li> | |
4 | +<h1><%= _('Products/Services') %></h1> | |
6 | 5 | |
6 | +<%= breadcrumb(@category) if params[:level] %> | |
7 | + | |
8 | +<div class='l-sidebar-left-bar'> | |
9 | + <ul> | |
10 | + <%= content_tag('li', link_to(_('Enterprise homepage'), profile.public_profile_url), :id => 'catalog-categories-homepage-link') %> | |
11 | + <% if @categories.present? %> | |
12 | + <% @categories.each do |category| %> | |
13 | + <%= category_link(category) %> | |
14 | + <%= category_sub_links(category) %> | |
15 | + <% end %> | |
16 | + <% elsif @category.present? %> | |
17 | + <%= content_tag('li', _('There are no sub-categories for %s') % @category.name, :id => 'catalog-categories-notice') %> | |
18 | + <% else %> | |
19 | + <%= content_tag('li', _('There are no categories available.'), :id => 'catalog-categories-notice') %> | |
20 | + <% end %> | |
21 | + </ul> | |
22 | +</div> | |
23 | + | |
24 | +<ul id="product-list" class="l-sidebar-left-content"> | |
7 | 25 | <% @products.each do |product| %> |
8 | 26 | <% extra_content = @plugins.dispatch(:catalog_item_extras, product).collect { |content| instance_eval(&content) } %> |
9 | 27 | <% extra_content_list = @plugins.dispatch(:catalog_list_item_extras, product).collect { |content| instance_eval(&content) } %> |
10 | 28 | |
11 | - <li class="product <%= "not-available" unless product.available %>"> | |
29 | + <% status = [] %> | |
30 | + <% status << 'not-available' if !product.available %> | |
31 | + <% status << 'highlighted' if product.highlighted %> | |
32 | + | |
33 | + <li id="product-<%= product.id %>" class="product <%= status.join(' ') %>"> | |
12 | 34 | <ul> |
13 | 35 | <li class="product-image-link"> |
36 | + <% if product.highlighted? %> | |
37 | + <%= link_to image_tag(themed_path('/images/star.png'), :class => 'star', :alt => _('Highlighted product')), product_path(product) %> | |
38 | + <% end %> | |
14 | 39 | <% if product.image %> |
15 | 40 | <div class="zoomable-image"> |
16 | 41 | <%= link_to_product product, :class => 'product-big', :style => "background-image: url(#{product.default_image(:big)})" %> | ... | ... |
app/views/cms/_blog.rhtml
... | ... | @@ -4,7 +4,7 @@ |
4 | 4 | |
5 | 5 | <%= render :file => 'shared/tiny_mce' %> |
6 | 6 | |
7 | -<%= required f.text_field(:name, :size => '64', :onchange => "updateUrlField(this, 'article_slug')") %> | |
7 | +<%= required f.text_field(:name, :size => '64', :maxlength => 150, :onchange => "updateUrlField(this, 'article_slug')") %> | |
8 | 8 | |
9 | 9 | <%= render :partial => 'general_fields' %> |
10 | 10 | ... | ... |
app/views/cms/_event.rhtml
... | ... | @@ -3,7 +3,7 @@ |
3 | 3 | <%# TODO add Textile help here %> |
4 | 4 | <%= render :file => 'shared/tiny_mce' %> |
5 | 5 | |
6 | -<%= required f.text_field('name', :size => '64') %> | |
6 | +<%= required f.text_field('name', :size => '64', :maxlength => 150) %> | |
7 | 7 | |
8 | 8 | <%= render :partial => 'general_fields' %> |
9 | 9 | <%= render :partial => 'translatable' %> | ... | ... |
app/views/cms/_folder.rhtml
1 | 1 | <%= required_fields_message %> |
2 | 2 | |
3 | -<%= required f.text_field('name', :size => '64') %> | |
3 | +<%= required f.text_field('name', :size => '64', :maxlength => 150) %> | |
4 | 4 | <%= render :partial => 'general_fields' %> |
5 | 5 | |
6 | 6 | <%= labelled_form_field(_('Description:'), text_area(:article, :body, :rows => 3, :cols => 64)) %> | ... | ... |
app/views/cms/_forum.rhtml
... | ... | @@ -4,7 +4,7 @@ |
4 | 4 | |
5 | 5 | <%= render :file => 'shared/tiny_mce' %> |
6 | 6 | |
7 | -<%= required f.text_field(:name, :size => '64', :onchange => "updateUrlField(this, 'article_slug')") %> | |
7 | +<%= required f.text_field(:name, :size => '64', :maxlength => 150, :onchange => "updateUrlField(this, 'article_slug')") %> | |
8 | 8 | |
9 | 9 | <%= render :partial => 'general_fields' %> |
10 | 10 | ... | ... |
app/views/cms/_gallery.rhtml
app/views/cms/_published_article.rhtml
1 | -<%= f.text_field 'name', :size => '64' %> | |
1 | +<%= f.text_field 'name', :size => '64', :maxlength => 150 %> | |
2 | 2 | <%= render :partial => 'general_fields' %> |
3 | 3 | |
4 | 4 | <p><%= _('This is a republication of "%s", by %s.') % [link_to(h(@article.reference_article.name), @article.reference_article.url), @article.reference_article.profile.name] %></p> | ... | ... |
app/views/cms/_raw_html_article.rhtml
1 | 1 | <%= required_fields_message %> |
2 | 2 | |
3 | -<%= required labelled_form_field(_('Title'), text_field(:article, 'name', :size => '64')) %> | |
3 | +<%= required labelled_form_field(_('Title'), text_field(:article, 'name', :size => '64', :maxlength => 150)) %> | |
4 | 4 | |
5 | 5 | <%= render :partial => 'general_fields' %> |
6 | 6 | <%= render :partial => 'translatable' %> | ... | ... |
app/views/cms/_textile_article.rhtml
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | |
3 | 3 | <%# TODO add Textile help here %> |
4 | 4 | |
5 | -<%= required labelled_form_field(_('Title'), text_field(:article, 'name', :size => '72')) %> | |
5 | +<%= required labelled_form_field(_('Title'), text_field(:article, 'name', :size => '72', :maxlength => 150)) %> | |
6 | 6 | |
7 | 7 | <%= render :partial => 'general_fields' %> |
8 | 8 | <%= render :partial => 'translatable' %> | ... | ... |
app/views/cms/_tiny_mce_article.rhtml
... | ... | @@ -3,7 +3,7 @@ |
3 | 3 | <%= render :file => 'shared/tiny_mce' %> |
4 | 4 | |
5 | 5 | <div> |
6 | - <%= required labelled_form_field(_('Title'), text_field(:article, 'name', :size => '64')) %> | |
6 | + <%= required labelled_form_field(_('Title'), text_field(:article, 'name', :size => '64', :maxlength => 150)) %> | |
7 | 7 | |
8 | 8 | <%= render :partial => 'general_fields' %> |
9 | 9 | <%= render :partial => 'translatable' %> | ... | ... |
app/views/cms/select_article_type.rhtml
... | ... | @@ -2,9 +2,9 @@ |
2 | 2 | |
3 | 3 | <ul id="article_types"> |
4 | 4 | <% for type in @article_types %> |
5 | - <% action = type[:name] == 'UploadedFile' ? {:action => 'upload_files'} : {:action => 'new', :type => type[:name]} %> | |
5 | + <% action = type[:class].name == 'UploadedFile' ? {:action => 'upload_files'} : {:action => 'new', :type => type[:class].name} %> | |
6 | 6 | <% content_tag('a', :href => url_for(action.merge(:parent_id => @parent_id, :back_to => @back_to))) do %> |
7 | - <li class="<%= icon_for_new_article(type[:name]) %>" onmouseover="javascript: jQuery(this).addClass('mouseover')" onmouseout="jQuery(this).removeClass('mouseover')"> | |
7 | + <li class="<%= icon_for_new_article(type[:class]) %>" onmouseover="javascript: jQuery(this).addClass('mouseover')" onmouseout="jQuery(this).removeClass('mouseover')"> | |
8 | 8 | <strong><%= type[:short_description] %></strong> |
9 | 9 | <div class='description'><%= type[:description] %></div> |
10 | 10 | </li> | ... | ... |
app/views/content_viewer/_article_toolbar.rhtml
... | ... | @@ -34,11 +34,11 @@ |
34 | 34 | <%= expirable_button @page, :locale, content, url %> |
35 | 35 | <% end %> |
36 | 36 | |
37 | - <%= colorbox_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)))) %> | |
37 | + <%= colorbox_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)))) unless remove_content_button(:new) %> | |
38 | 38 | <% end %> |
39 | 39 | |
40 | 40 | <% if @page.accept_uploads? && @page.allow_create?(user) %> |
41 | - <%= button('upload-file', _('Upload files'), profile.admin_url.merge(:controller => 'cms', :action => 'upload_files', :parent_id => (@page.folder? ? @page : @page.parent))) %> | |
41 | + <%= button('upload-file', _('Upload files'), profile.admin_url.merge(:controller => 'cms', :action => 'upload_files', :parent_id => (@page.folder? ? @page : @page.parent))) unless remove_content_button(:upload)%> | |
42 | 42 | <% end %> |
43 | 43 | |
44 | 44 | <% if !@page.allow_create?(user) && profile.community? && (@page.blog? || @page.parent && @page.parent.blog?) && !remove_content_button(:suggest) %> | ... | ... |
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/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') %> | |
94 | 94 | <% end %> |
95 | 95 | |
96 | 96 | <ul class="article-comments-list"> | ... | ... |
app/views/layouts/application-ng.rhtml
... | ... | @@ -69,7 +69,7 @@ |
69 | 69 | <% end %> |
70 | 70 | |
71 | 71 | </span> |
72 | - <form action="/search" class="search_form" method="get" class="clean"> | |
72 | + <form action="/search" class="search_form clean" method="get" id="top-search"> | |
73 | 73 | <input name="query" size="15" title="<%=_('Search...')%>" onfocus="this.form.className='focused';" onblur="this.form.className=''" /> |
74 | 74 | <div><%=_('Press <strong>Enter</strong> to send the search query.')%></div> |
75 | 75 | <%= javascript_tag 'jQuery("#user form input").hint();' %> | ... | ... |
app/views/profile/_create_article.rhtml
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | <div class='profile-activity-lead'> |
10 | 10 | <div class='article-name'><%= link_to(activity.params['name'], activity.params['url']) %></div> |
11 | 11 | <span title='<%= activity.target.class.short_description %>' class='profile-activity-icon icon-new icon-new<%= activity.target.class.icon_name %>'></span> |
12 | - <%= image_tag(activity.params['first_image']) unless activity.params['first_image'].blank? %><%= strip_tags(truncate(activity.params['lead'], :length => 1000, :ommision => '...')).gsub(/(\xA0|\xC2|\s)+/, ' ').gsub(/^\s+/, '') %> <small><%= link_to(_('See more'), activity.params['url']) unless activity.get_lead.blank? %></small> | |
12 | + <%= image_tag(activity.params['first_image']) unless activity.params['first_image'].blank? %><%= strip_tags(truncate(activity.params['lead'], :length => 1000, :ommision => '...')).gsub(/(\xC2\xA0|\s)+/, ' ').gsub(/^\s+/, '') %> <small><%= link_to(_('See more'), activity.params['url']) unless activity.get_lead.blank? %></small> | |
13 | 13 | </div> |
14 | 14 | <%= content_tag(:p, link_to(_('See complete forum'), activity.get_url), :class => 'see-forum') if activity.target.is_a?(Forum) %> |
15 | 15 | <p class='profile-activity-time'><%= time_ago_as_sentence(activity.created_at) %></p> | ... | ... |
app/views/profile/communities.rhtml
app/views/profile_editor/_person_form.rhtml
... | ... | @@ -21,6 +21,8 @@ |
21 | 21 | <%= optional_field(@person, 'city', f.text_field(:city, :rel => _('City'))) %> |
22 | 22 | <%= optional_field(@person, 'zip_code', labelled_form_field(_('ZIP code'), text_field(:profile_data, :zip_code, :rel => _('ZIP code')))) %> |
23 | 23 | <%= optional_field(@person, 'address', labelled_form_field(_('Address (street and number)'), text_field(:profile_data, :address, :rel => _('Address')))) %> |
24 | +<%= optional_field(@person, 'address_reference', labelled_form_field(_('Address reference'), text_field(:profile_data, :address_reference, :rel => _('Address reference')))) %> | |
25 | +<%= optional_field(@person, 'district', labelled_form_field(_('District'), text_field(:profile_data, :district, :rel => _('District')))) %> | |
24 | 26 | |
25 | 27 | <% optional_field(@person, 'schooling') do %> |
26 | 28 | <div class="formfieldline"> | ... | ... |
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/search/_product.rhtml
1 | -<% extra_content = @plugins.dispatch(:asset_product_extras, product, product.enterprise).collect { |content| instance_eval(&content) } %> | |
1 | +<% extra_content = @plugins.dispatch(:asset_product_extras, product).collect { |content| instance_eval(&content) } %> | |
2 | 2 | <% extra_properties = @plugins.dispatch(:asset_product_properties, product)%> |
3 | 3 | |
4 | -<li class="search-product-item"> | |
4 | +<li class="search-product-item <%= 'highlighted' if product.highlighted? %>"> | |
5 | 5 | |
6 | 6 | <div class="search-product-item-first-column"> |
7 | 7 | <%= render :partial => 'search/image', :object => product %> | ... | ... |
app/views/shared/_organization_custom_fields.rhtml
... | ... | @@ -10,6 +10,8 @@ |
10 | 10 | <%= optional_field(profile, 'economic_activity', f.text_field(:economic_activity)) %> |
11 | 11 | <%= optional_field(profile, 'management_information', f.text_area(:management_information, :rows => 5)) %> |
12 | 12 | <%= optional_field(profile, 'address', labelled_form_field(_('Address (street and number)'), text_field(object_name, :address))) %> |
13 | +<%= optional_field(profile, 'address_reference', labelled_form_field(_('Address reference'), text_field(object_name, :address_reference))) %> | |
14 | +<%= optional_field(profile, 'district', labelled_form_field(_('District'), text_field(object_name, :district))) %> | |
13 | 15 | <%= optional_field(profile, 'zip_code', labelled_form_field(_('ZIP code'), text_field(object_name, :zip_code))) %> |
14 | 16 | <%= optional_field(profile, 'city', f.text_field(:city)) %> |
15 | 17 | <%= optional_field(profile, 'state', f.text_field(:state)) %> | ... | ... |
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/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 | +default: --color --format progress --strict --tags ~@selenium --tags ~@selenium-fixme --tags ~@fixme --exclude features/support/selenium.rb -r features/support -r features/step_definitions | |
2 | +selenium: --strict --tags @selenium -r features/support -r features/step_definitions | ... | ... |
config/database.yml.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 | + | ... | ... |
config/initializers/plugins.rb
db/migrate/20130111232201_aggressive_indexing_strategy3.rb
0 → 100644
... | ... | @@ -0,0 +1,39 @@ |
1 | +class AggressiveIndexingStrategy3 < ActiveRecord::Migration | |
2 | + def self.up | |
3 | + add_index :articles, :slug | |
4 | + add_index :articles, :parent_id | |
5 | + add_index :articles, :profile_id | |
6 | + add_index :articles, :name | |
7 | + | |
8 | + add_index :article_versions, :article_id | |
9 | + | |
10 | + add_index :comments, [:source_id, :spam] | |
11 | + | |
12 | + add_index :profiles, :identifier | |
13 | + | |
14 | + add_index :friendships, :person_id | |
15 | + add_index :friendships, :friend_id | |
16 | + add_index :friendships, [:person_id, :friend_id], :uniq => true | |
17 | + | |
18 | + add_index :external_feeds, :blog_id | |
19 | + end | |
20 | + | |
21 | + def self.down | |
22 | + remove_index :articles, :slug | |
23 | + remove_index :articles, :parent_id | |
24 | + remove_index :articles, :profile_id | |
25 | + remove_index :articles, :name | |
26 | + | |
27 | + remove_index :article_versions, :article_id | |
28 | + | |
29 | + remove_index :comments, [:source_id, :spam] | |
30 | + | |
31 | + remove_index :profiles, :identifier | |
32 | + | |
33 | + remove_index :friendships, :person_id | |
34 | + remove_index :friendships, :friend_id | |
35 | + remove_index :friendships, [:person_id, :friend_id] | |
36 | + | |
37 | + remove_index :external_feeds, :blog_id | |
38 | + end | |
39 | +end | ... | ... |
db/migrate/20130117132943_remove_index_articles_on_name.rb
0 → 100644
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 => 20121008185303) 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" |
... | ... | @@ -88,6 +88,8 @@ ActiveRecord::Schema.define(:version => 20121008185303) do |
88 | 88 | t.integer "license_id" |
89 | 89 | end |
90 | 90 | |
91 | + add_index "article_versions", ["article_id"], :name => "index_article_versions_on_article_id" | |
92 | + | |
91 | 93 | create_table "articles", :force => true do |t| |
92 | 94 | t.string "name" |
93 | 95 | t.string "slug" |
... | ... | @@ -129,6 +131,10 @@ ActiveRecord::Schema.define(:version => 20121008185303) do |
129 | 131 | t.integer "license_id" |
130 | 132 | end |
131 | 133 | |
134 | + add_index "articles", ["name"], :name => "index_articles_on_name" | |
135 | + add_index "articles", ["parent_id"], :name => "index_articles_on_parent_id" | |
136 | + add_index "articles", ["profile_id"], :name => "index_articles_on_profile_id" | |
137 | + add_index "articles", ["slug"], :name => "index_articles_on_slug" | |
132 | 138 | add_index "articles", ["translation_of_id"], :name => "index_articles_on_translation_of_id" |
133 | 139 | |
134 | 140 | create_table "articles_categories", :id => false, :force => true do |t| |
... | ... | @@ -217,6 +223,8 @@ ActiveRecord::Schema.define(:version => 20121008185303) do |
217 | 223 | t.string "referrer" |
218 | 224 | end |
219 | 225 | |
226 | + add_index "comments", ["source_id", "spam"], :name => "index_comments_on_source_id_and_spam" | |
227 | + | |
220 | 228 | create_table "contact_lists", :force => true do |t| |
221 | 229 | t.text "list" |
222 | 230 | t.string "error_fetching" |
... | ... | @@ -280,6 +288,7 @@ ActiveRecord::Schema.define(:version => 20121008185303) do |
280 | 288 | t.integer "update_errors", :default => 0 |
281 | 289 | end |
282 | 290 | |
291 | + add_index "external_feeds", ["blog_id"], :name => "index_external_feeds_on_blog_id" | |
283 | 292 | add_index "external_feeds", ["enabled"], :name => "index_external_feeds_on_enabled" |
284 | 293 | add_index "external_feeds", ["fetched_at"], :name => "index_external_feeds_on_fetched_at" |
285 | 294 | |
... | ... | @@ -295,6 +304,10 @@ ActiveRecord::Schema.define(:version => 20121008185303) do |
295 | 304 | t.string "group" |
296 | 305 | end |
297 | 306 | |
307 | + add_index "friendships", ["friend_id"], :name => "index_friendships_on_friend_id" | |
308 | + add_index "friendships", ["person_id", "friend_id"], :name => "index_friendships_on_person_id_and_friend_id" | |
309 | + add_index "friendships", ["person_id"], :name => "index_friendships_on_person_id" | |
310 | + | |
298 | 311 | create_table "images", :force => true do |t| |
299 | 312 | t.integer "parent_id" |
300 | 313 | t.string "content_type" |
... | ... | @@ -402,7 +415,7 @@ ActiveRecord::Schema.define(:version => 20121008185303) do |
402 | 415 | t.datetime "updated_at" |
403 | 416 | t.decimal "discount" |
404 | 417 | t.boolean "available", :default => true |
405 | - t.boolean "highlighted" | |
418 | + t.boolean "highlighted", :default => false | |
406 | 419 | t.integer "unit_id" |
407 | 420 | t.integer "image_id" |
408 | 421 | end |
... | ... | @@ -446,6 +459,7 @@ ActiveRecord::Schema.define(:version => 20121008185303) do |
446 | 459 | end |
447 | 460 | |
448 | 461 | add_index "profiles", ["environment_id"], :name => "index_profiles_on_environment_id" |
462 | + add_index "profiles", ["identifier"], :name => "index_profiles_on_identifier" | |
449 | 463 | add_index "profiles", ["region_id"], :name => "index_profiles_on_region_id" |
450 | 464 | |
451 | 465 | create_table "qualifier_certifiers", :force => true do |t| | ... | ... |
debian/changelog
1 | +noosfero (0.41.1) unstable; urgency=low | |
2 | + | |
3 | + * Bugfixes release | |
4 | + | |
5 | + -- Rodrigo Souto <rodrigo@colivre.coop.br> Fri, 08 Mar 2013 11:33:11 -0300 | |
6 | + | |
7 | +noosfero (0.41.0) unstable; urgency=low | |
8 | + | |
9 | + * Features version with anti spam-bot measures | |
10 | + | |
11 | + -- Rodrigo Souto <rodrigo@colivre.coop.br> Mon, 28 Jan 2013 10:20:21 +0000 | |
12 | + | |
13 | +noosfero (0.40.0) unstable; urgency=low | |
14 | + | |
15 | + * Features version release | |
16 | + | |
17 | + -- Rodrigo Souto <rodrigo@colivre.coop.br> Sat, 19 Jan 2013 21:58:06 +0000 | |
18 | + | |
19 | +noosfero (0.39.3) unstable; urgency=low | |
20 | + | |
21 | + * Bugfixes release | |
22 | + | |
23 | + -- Rodrigo Souto <rodrigo@colivre.coop.br> Sat, 19 Jan 2013 19:27:04 +0000 | |
24 | + | |
25 | +noosfero (0.39.2) unstable; urgency=low | |
26 | + | |
27 | + * Bugfixes release | |
28 | + | |
29 | + -- Rodrigo Souto <rodrigo@colivre.coop.br> Sat, 12 Jan 2013 10:13:46 +0000 | |
30 | + | |
31 | +noosfero (0.39.1) unstable; urgency=low | |
32 | + | |
33 | + * Bugfixes release | |
34 | + | |
35 | + -- Daniela Soares Feitosa <daniela@colivre.coop.br> Thu, 20 Dec 2012 15:47:55 -0200 | |
36 | + | |
37 | +noosfero (0.39.0) unstable; urgency=low | |
38 | + | |
39 | + * Features version release | |
40 | + | |
41 | + -- Daniela Soares Feitosa <daniela@colivre.coop.br> Fri, 07 Dec 2012 09:53:42 -0200 | |
42 | + | |
1 | 43 | noosfero (0.39.0~1) UNRELEASED; urgency=low |
2 | 44 | |
3 | 45 | * Pre-release to test the antispam mechanism. |
4 | 46 | |
5 | 47 | -- Antonio Terceiro <terceiro@debian.org> Thu, 30 Aug 2012 14:55:10 -0300 |
6 | 48 | |
49 | +noosfero (0.38.3) unstable; urgency=low | |
50 | + | |
51 | + * Bugfixes release | |
52 | + | |
53 | + -- Daniela Soares Feitosa <daniela@colivre.coop.br> Wed, 07 Nov 2012 20:25:51 -0200 | |
54 | + | |
7 | 55 | noosfero (0.38.2) unstable; urgency=low |
8 | 56 | |
9 | 57 | * Bugfixes release | ... | ... |
debian/noosfero.install
... | ... | @@ -32,6 +32,8 @@ debian/solr.yml etc/noosfero |
32 | 32 | debian/thin.yml etc/noosfero |
33 | 33 | etc/logrotate.d/noosfero etc/logrotate.d |
34 | 34 | debian/noosfero.yml etc/noosfero |
35 | +etc/noosfero/varnish-accept-language.vcl etc/noosfero | |
36 | +etc/noosfero/varnish-noosfero.vcl etc/noosfero | |
35 | 37 | |
36 | 38 | locale usr/share/noosfero |
37 | 39 | doc/noosfero usr/share/noosfero/doc | ... | ... |
etc/noosfero/varnish-noosfero.vcl
1 | 1 | sub vcl_recv { |
2 | 2 | if (req.request == "GET" || req.request == "HEAD") { |
3 | 3 | if (req.http.Cookie) { |
4 | - # We only care about the "_noosfero_session.*" cookie, used for | |
5 | - # authentication. | |
6 | - if (req.http.Cookie !~ "_noosfero_session.*" ) { | |
4 | + # We only care about the "_noosfero_.*" cookies, used by Noosfero | |
5 | + if (req.http.Cookie !~ "_noosfero_.*" ) { | |
7 | 6 | # strip all cookies |
8 | 7 | unset req.http.Cookie; |
9 | 8 | } | ... | ... |
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" | ... | ... |