voluntary 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/app/helpers/product_helper.rb +5 -3
  2. data/config/initializers/vendor_extensions.rb +1 -0
  3. data/lib/generators/voluntary/install/install_generator.rb +0 -17
  4. data/lib/generators/voluntary/product_dummy/product_dummy_generator.rb +105 -0
  5. data/lib/generators/voluntary/product_dummy/templates/app/controllers/application_controller.rb +3 -0
  6. data/lib/generators/voluntary/product_dummy/templates/app/controllers/home_controller.rb +4 -0
  7. data/lib/generators/voluntary/product_dummy/templates/app/models/ability.rb +49 -0
  8. data/lib/generators/voluntary/product_dummy/templates/app/models/app_config.rb +32 -0
  9. data/lib/generators/voluntary/product_dummy/templates/app/views/home/index.html.erb +0 -0
  10. data/lib/generators/voluntary/product_dummy/templates/app/views/layouts/application.html.erb +50 -0
  11. data/lib/generators/voluntary/product_dummy/templates/config/application.yml +147 -0
  12. data/lib/generators/voluntary/product_dummy/templates/config/cucumber.yml +8 -0
  13. data/lib/generators/voluntary/product_dummy/templates/config/database.example.yml +28 -0
  14. data/lib/generators/voluntary/product_dummy/templates/config/email.example.yml +9 -0
  15. data/lib/generators/voluntary/product_dummy/templates/config/locale_settings.yml +121 -0
  16. data/lib/generators/voluntary/product_dummy/templates/config/main_navigation.rb +262 -0
  17. data/lib/generators/voluntary/product_dummy/templates/config/mongoid.yml +78 -0
  18. data/lib/generators/voluntary/product_dummy/templates/config/routes.rb +3 -0
  19. data/lib/generators/voluntary/product_dummy/templates/features/step_definitions/area_behaviour_steps.rb +17 -0
  20. data/lib/generators/voluntary/product_dummy/templates/features/step_definitions/area_steps.rb +11 -0
  21. data/lib/generators/voluntary/product_dummy/templates/features/step_definitions/candidature_steps.rb +34 -0
  22. data/lib/generators/voluntary/product_dummy/templates/features/step_definitions/comment_behaviour_steps.rb +23 -0
  23. data/lib/generators/voluntary/product_dummy/templates/features/step_definitions/comment_steps.rb +25 -0
  24. data/lib/generators/voluntary/product_dummy/templates/features/step_definitions/email_steps.rb +89 -0
  25. data/lib/generators/voluntary/product_dummy/templates/features/step_definitions/factory_steps.rb +120 -0
  26. data/lib/generators/voluntary/product_dummy/templates/features/step_definitions/javascript_steps.rb +15 -0
  27. data/lib/generators/voluntary/product_dummy/templates/features/step_definitions/navigation_steps.rb +3 -0
  28. data/lib/generators/voluntary/product_dummy/templates/features/step_definitions/product_steps.rb +15 -0
  29. data/lib/generators/voluntary/product_dummy/templates/features/step_definitions/project_steps.rb +23 -0
  30. data/lib/generators/voluntary/product_dummy/templates/features/step_definitions/resources_steps.rb +8 -0
  31. data/lib/generators/voluntary/product_dummy/templates/features/step_definitions/session_steps.rb +35 -0
  32. data/lib/generators/voluntary/product_dummy/templates/features/step_definitions/state_machines/vacancy_steps.rb +7 -0
  33. data/lib/generators/voluntary/product_dummy/templates/features/step_definitions/story_steps.rb +33 -0
  34. data/lib/generators/voluntary/product_dummy/templates/features/step_definitions/task_steps.rb +29 -0
  35. data/lib/generators/voluntary/product_dummy/templates/features/step_definitions/user_steps.rb +4 -0
  36. data/lib/generators/voluntary/product_dummy/templates/features/step_definitions/vacancy_steps.rb +32 -0
  37. data/lib/generators/voluntary/product_dummy/templates/features/step_definitions/web_steps.rb +271 -0
  38. data/lib/generators/voluntary/product_dummy/templates/features/step_definitions/wizards/story_steps.rb +15 -0
  39. data/lib/generators/voluntary/product_dummy/templates/features/support/database_cleaner_patches.rb +24 -0
  40. data/lib/generators/voluntary/product_dummy/templates/features/support/env.rb +86 -0
  41. data/lib/generators/voluntary/product_dummy/templates/features/support/integration_sessions_controller.rb +32 -0
  42. data/lib/generators/voluntary/product_dummy/templates/features/support/integration_sessions_form.html.erb +1 -0
  43. data/lib/generators/voluntary/product_dummy/templates/features/support/paths.rb +98 -0
  44. data/lib/generators/voluntary/product_dummy/templates/features/support/selectors.rb +44 -0
  45. data/lib/generators/voluntary/product_dummy/templates/features/support/spork_env +72 -0
  46. data/lib/generators/voluntary/product_dummy/templates/features/support/user_cuke_helpers.rb +78 -0
  47. data/lib/generators/voluntary/product_dummy/templates/spec/support/deferred_garbage_collector.rb +45 -0
  48. data/lib/generators/voluntary/product_dummy/templates/spec/support/devise.rb +3 -0
  49. data/lib/generators/voluntary/product_dummy/templates/spec/support/mongo_database_cleaner.rb +25 -0
  50. data/lib/voluntary/version.rb +1 -1
  51. metadata +212 -168
  52. data/app/views/products/types/text_creation/stories/_form.html.erb +0 -19
  53. data/app/views/products/types/text_creation/stories/_task_fields.html.erb +0 -7
  54. data/lib/vendors/active_model/naming.rb +0 -14
@@ -0,0 +1,262 @@
1
+ SimpleNavigation::Configuration.run do |navigation|
2
+ navigation.items do |primary|
3
+ primary.dom_class = 'nav'
4
+ primary.item :root, t('general.index.title'), root_path
5
+
6
+ primary.item :areas, t('areas.index.title'), areas_path do |areas|
7
+ areas.item :new, t('general.new'), new_area_path
8
+
9
+ unless (@area.new_record? rescue true)
10
+ areas.item :show, @area.name, area_path(@area) do |area|
11
+ if can? :destroy, @area
12
+ area.item :destroy, t('general.destroy'), area_path(@area), method: :delete, confirm: t('general.questions.are_you_sure')
13
+ end
14
+
15
+ area.item :show, t('general.details'), "#{area_path(@area)}#top"
16
+ area.item :edit, t('general.edit'), edit_area_path(@area) if can? :edit, @area
17
+ area.item :users, t('users.index.title'), area_users_path(@area)
18
+ area.item :projects, t('projects.index.title'), area_projects_path(@area)
19
+ end
20
+ end
21
+ end
22
+
23
+ primary.item :products, t('products.index.title'), products_path do |products|
24
+ products.item :new, t('general.new'), new_product_path
25
+
26
+ unless (@product.new_record? rescue true)
27
+ products.item :show, @product.name, product_path(@product) do |product|
28
+ if can? :edit, @product
29
+ product.item :destroy, t('general.destroy'), product_path(@product), method: :delete, confirm: t('general.questions.are_you_sure')
30
+ end
31
+
32
+ product.item :show, t('general.details'), "#{product_path(@product)}#top"
33
+ product.item :edit, t('general.edit'), edit_product_path(@product) if can? :edit, @product
34
+
35
+ product.item :projects, t('projects.index.title'), product_projects_path(@product)
36
+ end
37
+ end
38
+ end
39
+
40
+ primary.item :projects, t('projects.index.title'), projects_path do |projects|
41
+ projects.item :new, t('general.new'), new_project_path
42
+
43
+ unless (@project.new_record? rescue true)
44
+ projects.item :show, @project.name, project_path(@project) do |project|
45
+ if can? :destroy, @project
46
+ project.item :destroy, t('general.destroy'), project_path(@project), method: :delete, confirm: t('general.questions.are_you_sure')
47
+ end
48
+
49
+ project.item :show, t('general.details'), "#{project_path(@project)}#top"
50
+ project.item :edit, t('general.edit'), edit_project_path(@project) if can? :edit, @project
51
+
52
+ project.item :users, t('users.index.title'), project_users_path(@project)
53
+
54
+ project.item :vacancies, t('vacancies.index.title'), project_vacancies_path(@project) do |vacancy|
55
+ vacancy.item :new, t('general.new'), new_project_vacancy_path(@project)
56
+ end
57
+
58
+ project.item :stories, t('stories.index.title'), project_stories_path(@project) do |stories|
59
+ stories.item :new, t('general.new'), new_project_story_path(@project)
60
+
61
+ unless (@story.new_record? rescue true)
62
+ stories.item(:show, @story.name, story_path(@story)) do |story|
63
+ if can? :destroy, @story
64
+ story.item :destroy, t('general.destroy'), story_path(@story), method: :delete, confirm: t('general.questions.are_you_sure')
65
+ end
66
+
67
+ story.item :show, t('general.details'), "#{story_path(@story)}#top"
68
+ story.item :edit, t('general.edit'), edit_story_path(@story) if can? :edit, @story
69
+
70
+ story.item :steps, t('general.steps'), setup_tasks_story_path(@story) do |steps|
71
+ steps.item :setup_tasks, t('stories.steps.setup_tasks.title'), setup_tasks_story_path(@story)
72
+ steps.item :activate, t('general.events.activate'), activate_story_path(@story)
73
+ end
74
+
75
+ story.item :tasks, t('tasks.index.title'), story_tasks_path(@story) do |tasks|
76
+ tasks.item :new, t('general.new'), new_story_task_path(@story)
77
+
78
+ unless (@task.new_record? rescue true)
79
+ tasks.item(:show, @task.name, task_path(@task)) do |task|
80
+ if can? :destroy, @task
81
+ task.item :destroy, t('general.destroy'), task_path(@task), method: :delete, confirm: t('general.questions.are_you_sure')
82
+ end
83
+
84
+ task.item :show, t('general.details'), "#{task_path(@task)}#top"
85
+ task.item :edit, t('general.edit'), edit_task_path(@task) if can? :edit, @task
86
+
87
+ task.item :results, t('results.index.title'), task_results_path(@task) do |results|
88
+ results.item :new, t('general.new'), new_task_result_path(@task)
89
+
90
+ unless (@result.new_record? rescue true)
91
+ results.item(:show, @result.name, result_path(@result)) do |result|
92
+ if can? :destroy, @result
93
+ result.item :destroy, t('general.destroy'), result_path(@result), method: :delete, confirm: t('general.questions.are_you_sure')
94
+ end
95
+
96
+ result.item :show, t('general.details'), "#{result_path(@result)}#top"
97
+ result.item :edit, t('general.edit'), edit_result_path(@result) if can? :edit, @result
98
+
99
+ result.item :comments, t('comments.index.title'), "#{story_path(@story)}#comments" do |comments|
100
+ comments.item(:new, t('general.new'), new_story_comment_path(@story)) if @comment
101
+
102
+ if can? :edit, @comment
103
+ comments.item(:edit, t('general.edit'), edit_comment_path(@comment)) if @comment.try(:id)
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+
110
+ task.item :comments, t('comments.index.title'), "#{story_path(@story)}#comments" do |comments|
111
+ comments.item(:new, t('general.new'), new_story_comment_path(@story)) if @comment
112
+
113
+ if @comment.try(:id) && can?(:edit, @comment)
114
+ comments.item(:edit, t('general.edit'), edit_comment_path(@comment))
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
120
+
121
+ story.item :comments, t('comments.index.title'), "#{story_path(@story)}#comments" do |comments|
122
+ comments.item(:new, t('general.new'), new_story_comment_path(@story)) if @comment
123
+
124
+ if @comment.try(:id) && can?(:edit, @comment)
125
+ comments.item(:edit, t('general.edit'), edit_comment_path(@comment))
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ project.item :comments, t('comments.index.title'), "#{project_path(@project)}#comments" do |comments|
133
+ comments.item(:new, t('general.new'), new_project_comment_path(@project)) if @comment
134
+
135
+ if @comment.try(:id) && can?(:edit, @comment)
136
+ comments.item(:edit, t('general.edit'), edit_comment_path(@comment))
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
142
+
143
+ primary.item :vacancies, t('vacancies.index.title'), vacancies_path do |vacancies|
144
+ vacancies.item :new, t('general.new'), new_vacancy_path
145
+
146
+ unless (@vacancy.new_record? rescue true)
147
+ vacancies.item :show, "#{@vacancy.name} @ #{@vacancy.project.name}", vacancy_path(@vacancy) do |vacancy|
148
+
149
+ if can? :destroy, @vacancy
150
+ vacancy.item :destroy, t('general.destroy'), vacancy_path(@vacancy), method: :delete, confirm: t('general.questions.are_you_sure')
151
+ end
152
+
153
+ vacancy.item :show, t('general.details'), "#{vacancy_path(@vacancy)}#top"
154
+ vacancy.item :edit, t('general.edit'), edit_vacancy_path(@vacancy) if can? :edit, @vacancy
155
+
156
+ vacancy.item :candidatures, t('candidatures.index.title'), vacancy_candidatures_path(@vacancy) do |candidatures|
157
+ candidatures.item :new, t('general.new'), new_vacancy_candidature_path(@vacancy)
158
+
159
+ unless (@candidature.new_record? rescue true)
160
+ candidatures.item(
161
+ :show, t('activerecord.models.candidature') + " of #{@candidature.user.name} @ #{@candidature.vacancy.project.name}",
162
+ candidature_path(@candidature)
163
+ ) do |candidature|
164
+ if can? :destroy, @candidature
165
+ candidature.item :destroy, t('general.destroy'), candidature_path(@candidature), method: :delete, confirm: t('general.questions.are_you_sure')
166
+ end
167
+
168
+ candidature.item :show, t('general.details'), "#{candidature_path(@candidature)}#top"
169
+ candidature.item :edit, t('general.edit'), edit_candidature_path(@candidature) if can? :edit, @candidature
170
+
171
+ candidature.item :comments, t('comments.index.title'), "#{candidature_path(@candidature)}#comments" do |comments|
172
+ comments.item(:new, t('general.new'), new_candidature_comment_path(@candidature)) if @comment
173
+
174
+ if @comment.try(:id) && can?(:edit, @comment)
175
+ comments.item(:edit, t('general.edit'), edit_comment_path(@comment))
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end
181
+
182
+ vacancy.item :comments, t('comments.index.title'), "#{vacancy_path(@vacancy)}#comments" do |comments|
183
+ comments.item(:new, t('general.new'), new_vacancy_comment_path(@vacancy)) if @comment && !@candidature
184
+
185
+ if @comment.try(:id) && can?(:edit, @comment)
186
+ comments.item(:edit, t('general.edit'), edit_comment_path(@comment))
187
+ end
188
+ end
189
+ end
190
+ end
191
+ end
192
+
193
+ primary.item :users, t('users.index.title'), users_path do |users|
194
+ unless (@user.new_record? rescue true) || current_user.try(:id) == @user.id
195
+ users.item :show, t('general.details'), "#{user_path(@user)}#top"
196
+
197
+ users.item :projects, t('projects.index.title'), user_projects_path(@user)
198
+ users.item :candidatures, t('candidatures.index.title'), user_candidatures_path(@user)
199
+ end
200
+ end
201
+
202
+ if user_signed_in?
203
+ primary.item :workflow, t('workflow.index.title'), workflow_path do |workflow|
204
+ workflow.item :project_owner, t('workflow.project_owner.index.title'), workflow_project_owner_index_path do |project_owner|
205
+ project_owner.item :vacancies, t('vacancies.index.title'), open_workflow_vacancies_path do |vacancies|
206
+ Vacancy::STATES.each do |state|
207
+ vacancies.item state, t("vacancies.show.states.#{state}"), eval("#{state}_workflow_vacancies_path")
208
+ end
209
+ end
210
+
211
+ project_owner.item :candidatures, t('candidatures.index.title'), new_workflow_candidatures_path do |candidatures|
212
+ Candidature::STATES.each do |state|
213
+ candidatures.item state, t("candidatures.show.states.#{state}"), eval("#{state}_workflow_candidatures_path")
214
+ end
215
+ end
216
+ end
217
+
218
+ workflow.item :user, t('workflow.user.index.title'), workflow_user_index_path do |user|
219
+ {
220
+ 'no-name' => t('workflow.user.products.no_name.title')
221
+ }.each do |slug, text|
222
+ user.item slug.gsub('-', '_').to_sym, text, product_workflow_user_index_path(slug) do |product|
223
+ product_slug = @story ? (@story.product.try(:to_param) || 'no-name') : 'no-name'
224
+
225
+ unless (@story.new_record? rescue true) || product_slug != slug
226
+ product.item(:show, @story.name, story_path(@story)) do |story|
227
+ story.item :show, t('general.details'), "#{story_path(@story)}#top"
228
+
229
+ story.item :tasks, t('tasks.index.title'), tasks_workflow_user_index_path(@story) do |tasks|
230
+ unless (@task.new_record? rescue true)
231
+ tasks.item(:edit, @task.name, edit_task_workflow_user_index_path(@task))
232
+ end
233
+ end
234
+ end
235
+ end
236
+
237
+ product.item :next_task, t('workflow.user.tasks.next.title'), next_task_workflow_user_index_path('text-creation')
238
+ end
239
+ end
240
+ end
241
+ end
242
+
243
+ primary.item :profile, t('users.show.title'), user_path(current_user) do |profile|
244
+ profile.item :show, t('users.show.title'), user_path(current_user) do |user|
245
+ user.item :show, t('users.show.title'), "#{user_path(current_user)}#top"
246
+ user.item :settings, t('users.edit.title'), edit_user_path(current_user)
247
+ user.item :preferences, t('users.preferences.title'), preferences_user_path(current_user)
248
+ user.item :projects, t('projects.index.title'), user_projects_path(current_user)
249
+ user.item :candidatures, t('candidatures.index.title'), user_candidatures_path(current_user)
250
+ end
251
+ end
252
+
253
+ primary.item :sign_out, t('authentication.sign_out'), destroy_user_session_path, method: :delete
254
+ else
255
+ primary.item :authentication, t('authentication.title'), new_user_session_path do |authentication|
256
+ authentication.item :sign_in, t('authentication.sign_in'), new_user_session_path
257
+ #authentication.item :rpx_sign_in, t('authentication.rpx_sign_in'), 'a' # link_to_rpx
258
+ authentication.item :sign_up, t('authentication.sign_up'), new_user_registration_path
259
+ end
260
+ end
261
+ end
262
+ end
@@ -0,0 +1,78 @@
1
+ development:
2
+ # Configure available database sessions. (required)
3
+ sessions:
4
+ # Defines the default session. (required)
5
+ default:
6
+ # Defines the name of the default database that Mongoid can connect to.
7
+ # (required).
8
+ database: volontariat_development
9
+ # Provides the hosts the default session can connect to. Must be an array
10
+ # of host:port pairs. (required)
11
+ hosts:
12
+ - localhost:27017
13
+ options:
14
+ # Change whether the session persists in safe mode by default.
15
+ # (default: false)
16
+ # safe: false
17
+
18
+ # Change the default consistency model to :eventual or :strong.
19
+ # :eventual will send reads to secondaries, :strong sends everything
20
+ # to master. (default: :eventual)
21
+ consistency: :strong
22
+ # Configure Mongoid specific options. (optional)
23
+ options:
24
+ # Configuration for whether or not to allow access to fields that do
25
+ # not have a field definition on the model. (default: true)
26
+ # allow_dynamic_fields: true
27
+
28
+ # Enable the identity map, needed for eager loading. (default: false)
29
+ # identity_map_enabled: false
30
+
31
+ # Includes the root model name in json serialization. (default: false)
32
+ # include_root_in_json: false
33
+
34
+ # Include the _type field in serializaion. (default: false)
35
+ # include_type_for_serialization: false
36
+
37
+ # Preload all models in development, needed when models use
38
+ # inheritance. (default: false)
39
+ # preload_models: false
40
+
41
+ # Protect id and type from mass assignment. (default: true)
42
+ # protect_sensitive_fields: true
43
+
44
+ # Raise an error when performing a #find and the document is not found.
45
+ # (default: true)
46
+ # raise_not_found_error: true
47
+
48
+ # Raise an error when defining a scope with the same name as an
49
+ # existing method. (default: false)
50
+ # scope_overwrite_exception: false
51
+
52
+ # Skip the database version check, used when connecting to a db without
53
+ # admin access. (default: false)
54
+ # skip_version_check: false
55
+
56
+ # User Active Support's time zone in conversions. (default: true)
57
+ # use_activesupport_time_zone: true
58
+
59
+ # Ensure all times are UTC in the app side. (default: false)
60
+ # use_utc: false
61
+ test:
62
+ sessions:
63
+ default:
64
+ database: volontariat_test
65
+ hosts:
66
+ - localhost:27017
67
+ options:
68
+ consistency: :strong
69
+
70
+ production:
71
+ sessions:
72
+ default:
73
+ database: volontariat_production
74
+ hosts:
75
+ - localhost:27017
76
+ options:
77
+ consistency: :strong
78
+
@@ -0,0 +1,3 @@
1
+ Dummy::Application.routes.draw do
2
+ root to: 'home#index'
3
+ end
@@ -0,0 +1,17 @@
1
+ Then /^I can't edit areas$/ do
2
+ steps %{
3
+ Given an area named "area 1"
4
+ When I go to the edit area page
5
+ Then I should see "Access denied"
6
+ }
7
+ end
8
+
9
+ Then /^I can't delete areas$/ do
10
+ steps %{
11
+ Given an area named "area 1"
12
+ When I am on the area page
13
+ Then I should not see "Actions"
14
+ }
15
+ end
16
+
17
+
@@ -0,0 +1,11 @@
1
+ Given /^an area named "([^\"]*)"$/ do |name|
2
+ # WORKAROUND: get rid of area query. Don't know why it doesn't work without (e.g. /roles/2_users/projects.feature)
3
+ @area = Area.where(name: name).first || Factory(:area, name: name)
4
+ @area.reload
5
+ end
6
+
7
+ Then /^I should see the following areas:$/ do |expected_table|
8
+ rows = find("table").all('tr')
9
+ table = rows.map { |r| r.all('th,td').map { |c| c.text.strip } }
10
+ expected_table.diff!(table)
11
+ end
@@ -0,0 +1,34 @@
1
+ module CandidatureFactoryMethods
2
+ def set_candidature_defaults(attributes)
3
+ attributes[:user_id] ||= @me.id unless attributes[:user] || attributes[:user_id] || !@me
4
+ attributes[:vacancy_id] ||= Vacancy.last.id unless attributes[:vacancy_id] || Vacancy.all.none?
5
+ attributes[:offeror_id] ||= Vacancy.find(attributes[:vacancy_id]).project.user_id if attributes[:vacancy_id]
6
+ end
7
+
8
+ def new_candidature(name, state = nil)
9
+ attributes = { name: name }
10
+ attributes[:state] = state if state
11
+
12
+ set_candidature_defaults(attributes)
13
+
14
+ @candidature = Factory(:candidature, attributes)
15
+
16
+ @candidature.reload
17
+ end
18
+ end
19
+
20
+ World(CandidatureFactoryMethods)
21
+
22
+ Given /^a candidature named "([^\"]*)"$/ do |name|
23
+ new_candidature(name)
24
+ end
25
+
26
+ Given /^a candidature named "([^\"]*)" with state "([^\"]*)"$/ do |name,state|
27
+ new_candidature(name, state)
28
+ end
29
+
30
+ Then /^I should see the following candidatures:$/ do |expected_table|
31
+ rows = find('table').all('tr')
32
+ table = rows.map { |r| r.all('th,td').map { |c| c.text.strip } }
33
+ expected_table.diff!(table)
34
+ end
@@ -0,0 +1,23 @@
1
+ When /^I fill out a comment form$/ do
2
+ fill_in 'Subject', with: 'Comment 1'
3
+ fill_in 'Text', with: 'Dummy 1'
4
+ end
5
+
6
+ When /^I fill out a comment's comment form$/ do
7
+ fill_in 'Subject', with: 'Comment 2'
8
+ fill_in 'Text', with: 'Dummy 2'
9
+ end
10
+
11
+ Then /^I should see the comment$/ do
12
+ steps %{
13
+ Then I should see "Comment 1"
14
+ And I should see "Dummy 1"
15
+ }
16
+ end
17
+
18
+ Then /^I should see the comment's comment$/ do
19
+ page.should have_xpath(
20
+ '//div[@class="nested_comments"]//div[@class="comment"]//div[@class="content"]//p',
21
+ text: 'Dummy 2'
22
+ )
23
+ end
@@ -0,0 +1,25 @@
1
+ Given /^a comment$/ do
2
+ attributes = { commentable: @project || @vacancy || @candidature }
3
+ attributes[:user_id] ||= @me.id if @me
4
+ @comment = Factory(:comment, attributes)
5
+ @comment.reload
6
+ end
7
+
8
+ When /^I reply the (\d+)(?:st|nd|rd|th) comment$/ do |pos|
9
+ find(:xpath, "//a[@class='new_comment'][#{pos.to_i}]").click
10
+ end
11
+
12
+ When /^I edit the (\d+)(?:st|nd|rd|th) comment$/ do |pos|
13
+ find(:xpath, "//a[@class='edit_comment'][#{pos.to_i}]").click
14
+ end
15
+
16
+ When /^I delete the (\d+)(?:st|nd|rd|th) comment$/ do |pos|
17
+ page.execute_script 'window.confirm = function () { return true }'
18
+ find(:xpath, "//a[@class='destroy_comment'][#{pos.to_i}]").click
19
+ end
20
+
21
+ Then /^I should see the following comments:$/ do |expected_table|
22
+ expected_table.hashes.each do |hash|
23
+ steps %{Then I should see "#{hash['Name']}"}
24
+ end
25
+ end
@@ -0,0 +1,89 @@
1
+ Before do
2
+ ActionMailer::Base.deliveries.clear
3
+ end
4
+
5
+ Given /^I have an empty inbox$/ do
6
+ ActionMailer::Base.deliveries.clear
7
+ end
8
+
9
+ Then /^(an|no) email should have been sent((?: |and|with|from "[^"]+"|to "[^"]+"|the subject "[^"]+"|the body "[^"]+"|the attachments "[^"]+")+)$/ do |mode, query|
10
+ conditions = {}
11
+ conditions[:to] = $1 if query =~ /to "([^"]+)"/
12
+ conditions[:from] = $1 if query =~ /from "([^"]+)"/
13
+ conditions[:subject] = $1 if query =~ /the subject "([^"]+)"/
14
+ conditions[:body] = $1 if query =~ /the body "([^"]+)"/
15
+ conditions[:attachments] = $1 if query =~ /the attachments "([^"]+)"/
16
+
17
+ @mail = TestMails.find(conditions)
18
+ expectation = mode == 'no' ? 'should_not' : 'should'
19
+ @mail.send(expectation, be_present)
20
+ end
21
+
22
+ When /^I follow the (first|second|third)? ?link in the email$/ do |index_in_words|
23
+ # Caveat: will not only take a-href but also img-src and other http-values
24
+ mail = @mail || ActionMailer::Base.deliveries.last
25
+ # index = { nil => 0, 'first' => 0, 'second' => 1, 'third' => 2 }[index_in_words]
26
+ # visit mail.body.scan(Patterns::URL)[index][2]
27
+ visit mail.body.to_s.scan(/http(?:s?):\/\/[^"\s]+/).send(index_in_words).split(':3000').last
28
+ end
29
+
30
+ Then /^no email should have been sent$/ do
31
+ ActionMailer::Base.deliveries.should be_empty
32
+ end
33
+
34
+ Then /^show me the emails$/ do
35
+ #raise ActionMailer::Base.deliveries.length.inspect
36
+ puts "emails count:" + ActionMailer::Base.deliveries.length.inspect
37
+
38
+ ActionMailer::Base.deliveries.each do |mail|
39
+ p [mail.from, mail.to, mail.subject, mail.body]
40
+ end
41
+ end
42
+
43
+ Then /^that mail should have "([^"]*)" in the body$/ do |word|
44
+ @mail.body.include?(word).should be_true
45
+ end
46
+ #
47
+ #
48
+ class TestMails
49
+ class << self
50
+
51
+ attr_accessor :user_identity
52
+
53
+ def find(conditions)
54
+ ActionMailer::Base.deliveries.detect do |mail|
55
+ [ conditions[:to].nil? || mail.to.include?(resolve_email conditions[:to]),
56
+ conditions[:from].nil? || mail.from.include?(resolve_email conditions[:from]),
57
+ conditions[:subject].nil? || mail.subject.include?(conditions[:subject]),
58
+ conditions[:body].nil? || mail.body.include?(conditions[:body]),
59
+ conditions[:attachments].nil? || conditions[:attachments].split(/\s*,\s*/).sort == Array(mail.attachments).collect(&:original_filename).sort
60
+ ].all?
61
+ end.tap do |mail|
62
+ puts "Die Mail: #{mail}"
63
+ log(mail)
64
+ end
65
+ end
66
+
67
+ def resolve_email(identity)
68
+ if identity =~ /^.+\@.+$/
69
+ identity
70
+ else
71
+ User.send("find_by_#{user_identity || 'email'}!", identity).email
72
+ end
73
+ end
74
+
75
+ def log(mail)
76
+ puts "Aufruf: #{mail}"
77
+ if mail.present?
78
+ File.open("log/test_mails.log", "a") do |file|
79
+ file << "From: #{mail.from}\n"
80
+ file << "To: #{mail.to.join(', ')}\n"
81
+ file << "Subject: #{mail.subject}\n\n"
82
+ file << mail.body
83
+ file << "\n-------------------------\n\n"
84
+ end
85
+ end
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,120 @@
1
+ module FactoryMethods
2
+ def create_from_table(model_name, table, extra = {})
3
+ factory_name = model_name.gsub(/\W+/, '_').downcase.singularize.to_sym
4
+ is_singular = model_name.to_s.singularize == model_name.to_s
5
+
6
+ hashes = if is_singular
7
+ if table.kind_of?(Hash)
8
+ [table]
9
+ else
10
+ [table.rows_hash]
11
+ end
12
+ elsif table.is_a?(Array)
13
+ table
14
+ else
15
+ table.hashes
16
+ end
17
+
18
+ @klass = factory_name.to_s.classify.constantize
19
+ @they = hashes.map do |hash|
20
+ hash = hash.merge(extra).inject({}) do |h,(k,v)|
21
+ k = k.gsub(/\W+/,'_')
22
+
23
+ # mongo db model classes are not responding to serialized attributes
24
+ # TODO: take care of serialized attributes in future mongo db model implementations here
25
+ if @klass.respond_to?(:serialized_attributes) && @klass.serialized_attributes[k] == Array
26
+ v = v.split(/\s*,\s*/)
27
+ end
28
+
29
+ h.update(k.to_sym => v)
30
+ end
31
+
32
+ hash.keys.each do |attribute|
33
+ set_value(hash, attribute)
34
+ end
35
+
36
+ eval("set_#{factory_name}_defaults(hash)") if "#{factory_name.to_s.classify}FactoryMethods".constantize rescue nil
37
+
38
+ object = nil
39
+
40
+ object = @klass.where(name: hash[:name]).first if hash.has_key? :name
41
+ object = object ? object : Factory.build(factory_name, hash)
42
+
43
+ yield object if block_given?
44
+
45
+ object.save!
46
+
47
+ object
48
+ end
49
+
50
+ if is_singular
51
+ @it = @they.last
52
+ instance_variable_set("@#{factory_name}", @it)
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def set_value(hash, attribute)
59
+ value = hash[attribute]
60
+
61
+ if value.match '@'
62
+ if eval(value)
63
+ hash[attribute] = eval(value)
64
+ else
65
+ hash.delete attribute
66
+ end
67
+ elsif @klass.reflections.values.select{|v| v.macro == :belongs_to }.map(&:name).include? attribute
68
+ reflection_value = @klass.reflections.values.select{|v| v.name == attribute }.first
69
+
70
+ if reflection_value.options[:polymorphic]
71
+ polymorphic_type = "#{@klass.name}::#{attribute.to_s.upcase}_TYPES".constantize.first
72
+ resource = polymorphic_type.classify.constantize.find_by_name(value)
73
+ hash[attribute] = resource || create_from_table(polymorphic_type.tableize, [{ 'name' => value }])
74
+ else
75
+ resource = attribute.to_s.classify.constantize.find_by_name(value)
76
+ hash[attribute] = resource || create_from_table(attribute.to_s.tableize, [{ 'name' => value }])
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ World(FactoryMethods)
83
+
84
+ Given %r{^I have a (.+)$} do |model_name|
85
+ create_from_table(model_name, {}, 'user' => @me)
86
+ end
87
+
88
+ Given %r{^I have the following (.+):$} do |child, table|
89
+ step "that me has the following #{child}:", table
90
+ end
91
+
92
+ Given %r{^the following (.+):$} do |model_name, table|
93
+ create_from_table(model_name, table)
94
+ end
95
+
96
+ Given %r{^that (.+) has the following (.+):$} do |parent, child, table|
97
+ child= child.gsub(/\W+/,'_')
98
+ parent = parent.gsub(/\W+/,'_').downcase.sub(/^_/, '')
99
+ parent_instance = instance_variable_get("@#{parent}")
100
+ parent_class = parent_instance.class
101
+
102
+ if assoc = parent_class.reflect_on_association(child.to_sym) || parent_class.reflect_on_association(child.pluralize.to_sym)
103
+ parent = (assoc.options[:as] || parent).to_s
104
+ child = (assoc.options[:class_name] || child).to_s
105
+ end
106
+
107
+ if child.classify.constantize.method_defined?(parent.pluralize)
108
+ create_from_table(child, table, parent.pluralize => [parent_instance])
109
+ elsif child.classify.constantize.method_defined?(parent)
110
+ create_from_table(child, table, parent => parent_instance)
111
+ else
112
+ create_from_table(child, table)
113
+
114
+ if assoc.macro == :has_many
115
+ parent_instance.send("#{assoc.name}=", @they)
116
+ else
117
+ parent_instance.send("#{assoc.name}=", @they.first)
118
+ end
119
+ end
120
+ end