voluntary 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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