mumuki-laboratory 7.12.1 → 8.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/mumuki_laboratory/application/bridge.js +1 -1
  3. data/app/assets/javascripts/mumuki_laboratory/application/button.js +2 -2
  4. data/app/assets/javascripts/mumuki_laboratory/application/codemirror-builder.js +2 -2
  5. data/app/assets/javascripts/mumuki_laboratory/application/codemirror.js +5 -5
  6. data/app/assets/javascripts/mumuki_laboratory/application/console.js +2 -2
  7. data/app/assets/javascripts/mumuki_laboratory/application/discussions.js +7 -7
  8. data/app/assets/javascripts/mumuki_laboratory/application/editors.js +1 -1
  9. data/app/assets/javascripts/mumuki_laboratory/application/elipsis.js +1 -1
  10. data/app/assets/javascripts/mumuki_laboratory/application/events.js +2 -2
  11. data/app/assets/javascripts/mumuki_laboratory/application/exercise.js +2 -2
  12. data/app/assets/javascripts/mumuki_laboratory/application/gamification.js +99 -11
  13. data/app/assets/javascripts/mumuki_laboratory/application/inputs.js +1 -1
  14. data/app/assets/javascripts/mumuki_laboratory/application/kids.js +20 -8
  15. data/app/assets/javascripts/mumuki_laboratory/application/kindergarten.js +16 -57
  16. data/app/assets/javascripts/mumuki_laboratory/application/messages.js +6 -6
  17. data/app/assets/javascripts/mumuki_laboratory/application/mu-modal-carrousel.js +63 -0
  18. data/app/assets/javascripts/mumuki_laboratory/application/multiple-choice.js +1 -1
  19. data/app/assets/javascripts/mumuki_laboratory/application/multiple-files.js +3 -3
  20. data/app/assets/javascripts/mumuki_laboratory/application/multiple-scenarios.js +1 -1
  21. data/app/assets/javascripts/mumuki_laboratory/application/number-counter.js +18 -0
  22. data/app/assets/javascripts/mumuki_laboratory/application/pin.js +1 -1
  23. data/app/assets/javascripts/mumuki_laboratory/application/primary.js +3 -2
  24. data/app/assets/javascripts/mumuki_laboratory/application/progress.js +1 -1
  25. data/app/assets/javascripts/mumuki_laboratory/application/results-renderer.js +1 -1
  26. data/app/assets/javascripts/mumuki_laboratory/application/speech-bubble-renderer.js +4 -4
  27. data/app/assets/javascripts/mumuki_laboratory/application/submission.js +3 -3
  28. data/app/assets/javascripts/mumuki_laboratory/application/submissions-store.js +3 -3
  29. data/app/assets/javascripts/mumuki_laboratory/application/sync-mode.js +2 -2
  30. data/app/assets/javascripts/mumuki_laboratory/application/timer.js +1 -1
  31. data/app/assets/stylesheets/mumuki_laboratory/application/_layout.scss +7 -7
  32. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_kids_results.scss +117 -0
  33. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_kindergarten.scss +45 -131
  34. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_terms.scss +9 -12
  35. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_user_profile.scss +31 -3
  36. data/app/controllers/api/courses_controller.rb +1 -2
  37. data/app/controllers/api/organizations_controller.rb +2 -3
  38. data/app/controllers/api/users_controller.rb +2 -4
  39. data/app/controllers/application_controller.rb +41 -8
  40. data/app/controllers/assets_controller.rb +1 -0
  41. data/app/controllers/book_discussions_controller.rb +1 -1
  42. data/app/controllers/chapters_controller.rb +1 -0
  43. data/app/controllers/concerns/with_user_discussion_validation.rb +6 -0
  44. data/app/controllers/discussions_controller.rb +4 -6
  45. data/app/controllers/exercises_controller.rb +1 -0
  46. data/app/controllers/guides_controller.rb +2 -0
  47. data/app/controllers/invitations_controller.rb +2 -2
  48. data/app/controllers/lessons_controller.rb +1 -0
  49. data/app/controllers/login_controller.rb +1 -0
  50. data/app/controllers/users_controller.rb +9 -1
  51. data/app/helpers/assistance_box_helper.rb +7 -5
  52. data/app/helpers/gamification_helper.rb +5 -0
  53. data/app/helpers/links_helper.rb +2 -2
  54. data/app/views/exercise_solutions/_assistant_rules_box.html.erb +13 -0
  55. data/app/views/exercise_solutions/_contextualization_results_container.html.erb +9 -0
  56. data/app/views/exercise_solutions/_kids_level_up.html.erb +11 -0
  57. data/app/views/exercise_solutions/_results.html.erb +19 -19
  58. data/app/views/exercise_solutions/_results_title.html.erb +5 -0
  59. data/app/views/exercises/show.html.erb +4 -1
  60. data/app/views/layouts/_copyright.html.erb +1 -1
  61. data/app/views/layouts/_kindergarten.html.erb +1 -1
  62. data/app/views/layouts/_organizations_listing.html.erb +8 -12
  63. data/app/views/layouts/application.html.erb +23 -15
  64. data/app/views/layouts/embedded.html.erb +14 -11
  65. data/app/views/layouts/modals/_guide_corollary.html.erb +1 -1
  66. data/app/views/layouts/modals/_kids_context.html.erb +1 -1
  67. data/app/views/layouts/modals/_kids_results.html.erb +16 -6
  68. data/app/views/layouts/modals/_kindergarten_context.html.erb +15 -15
  69. data/app/views/layouts/modals/_kindergarten_results.html.erb +20 -7
  70. data/app/views/layouts/modals/_kindergarten_results_aborted.html.erb +4 -4
  71. data/app/views/layouts/modals/_level_up.html.erb +27 -0
  72. data/app/views/users/_edit_user_form.html.erb +1 -1
  73. data/app/views/users/_user_form.html.erb +12 -2
  74. data/app/views/users/terms.html.erb +12 -0
  75. data/config/routes.rb +8 -8
  76. data/lib/mumuki/laboratory.rb +18 -5
  77. data/lib/mumuki/laboratory/controllers.rb +2 -0
  78. data/lib/mumuki/laboratory/controllers/action_redirector.rb +21 -0
  79. data/lib/mumuki/laboratory/controllers/immersive_navigation.rb +7 -0
  80. data/lib/mumuki/laboratory/controllers/results_rendering.rb +1 -0
  81. data/lib/mumuki/laboratory/events/events.rb +0 -33
  82. data/lib/mumuki/laboratory/locales/en.yml +5 -0
  83. data/lib/mumuki/laboratory/locales/es-CL.yml +6 -1
  84. data/lib/mumuki/laboratory/locales/es.yml +7 -2
  85. data/lib/mumuki/laboratory/locales/pt.yml +6 -1
  86. data/lib/mumuki/laboratory/version.rb +1 -1
  87. data/spec/capybara_helper.rb +5 -1
  88. data/spec/controllers/discussions_controller_spec.rb +19 -0
  89. data/spec/controllers/exercise_solutions_controller_spec.rb +1 -1
  90. data/spec/dummy/db/schema.rb +2 -1
  91. data/spec/features/immersive_redirection_spec.rb +181 -0
  92. data/spec/features/profile_flow_spec.rb +35 -3
  93. data/spec/features/terms_flow_spec.rb +155 -0
  94. metadata +110 -101
  95. data/app/helpers/organization_list_helper.rb +0 -5
  96. data/spec/features/choose_organization_spec.rb +0 -74
@@ -101,6 +101,7 @@ es:
101
101
  exercise_success_rate: Tasa de éxito en ejercicios
102
102
  exercises: Ejercicios
103
103
  exit: Salir
104
+ exp_points: puntos de experiencia.
104
105
  expectations: Objetivos
105
106
  expected_state: Tablero esperado
106
107
  explain_redirect: Notamos que te registraste en otra organización.
@@ -111,8 +112,8 @@ es:
111
112
  first_name: Nombre
112
113
  forbidden_explanation: ¿Puede que hayas ingresado con una cuenta incorrecta?
113
114
  format: Dar formato
114
- forum_terms: Reglas del foro
115
- forum_terms_link: Si tenés alguna duda, consultá las %{terms_link}
115
+ forum_terms: Reglas del espacio de consultas
116
+ forum_terms_link: Si tenés alguna duda, accedé a las %{terms_link}
116
117
  fullscreen: "Pantalla completa"
117
118
  gender: Género
118
119
  get_messages: "Ver mensajes"
@@ -155,6 +156,8 @@ es:
155
156
  lessons: Lecciones
156
157
  lesson_number: Lección %{number}
157
158
  let_us_know: ¡Por favor avisanos!
159
+ level: Nivel
160
+ level_up: ¡Subiste de nivel!
158
161
  loading: Cargando
159
162
  load_solution_into_console: Cargar la solución en la consola
160
163
  locked_content: 'Este contenido se desbloqueará cuando termines los capítulos anteriores'
@@ -255,6 +258,7 @@ es:
255
258
  other: '%{count} resueltas'
256
259
  solved_exercises: Ejercicios Resueltos
257
260
  solve_doubts: Resolvé consultas
261
+ solve_more_exercises_to_level_up: Resolvé <span>number</span> ejercicios más para pasar al siguiente nivel.
258
262
  solve_your_doubts: Consultá tus dudas
259
263
  solve_your_doubts_teaser: ¿Tenés alguna consulta?
260
264
  something_went_wrong: ¡Ups!, algo no anduvo bien...
@@ -317,6 +321,7 @@ es:
317
321
  working: "Procesando"
318
322
  wrong_answer: La respuesta no es correcta
319
323
  years: años
324
+ you_earned: Ganaste
320
325
  you_must_sign_in_before_submitting: Tenés que iniciar sesión antes de empezar a enviar tus soluciones
321
326
  you_never_submitted_solutions: Parece que nunca enviaste soluciones desde que creaste tu cuenta.
322
327
  your_new_organization: tu nueva organización
@@ -97,6 +97,7 @@ pt:
97
97
  exercise_success_rate: Taxa de sucesso em exercícios
98
98
  exercises: Exercícios
99
99
  exit: Sair
100
+ exp_points: pontos de experiência.
100
101
  expectations: Objetivos
101
102
  expected_state: Tabuleiro esperado
102
103
  explain_redirect: Percebemos que você se registrou em outra organização.
@@ -107,7 +108,7 @@ pt:
107
108
  first_name: Nome
108
109
  forbidden_explanation: Você poderia ter entrado com uma conta incorreta?
109
110
  format: Formato
110
- forum_terms: Regras do fórum
111
+ forum_terms: Regras do espaço de consulta
111
112
  forum_terms_link: Se você tiver alguma dúvida, consulte as %{terms_link}
112
113
  fullscreen: Tela completa
113
114
  gender: Gênero
@@ -149,6 +150,8 @@ pt:
149
150
  lessons: Lições
150
151
  lesson_number: Lição %{number}
151
152
  let_us_know: Por favor, avise-nos!
153
+ level: Nível
154
+ level_up: Você sobe de nível!
152
155
  loading: Carregando
153
156
  load_solution_into_console: Carregue a solução no console
154
157
  locked_content: 'Este conteúdo será desbloqueado quando você terminar os capítulos anteriores'
@@ -242,6 +245,7 @@ pt:
242
245
  solved_count: '%{count} resolvido'
243
246
  solved_exercises: Exercícios resolvidos
244
247
  solve_doubts: Resolvi dúvidas
248
+ solve_more_exercises_to_level_up: Resolva mais <span>number</span> exercícios para avançar para o próximo nível.
245
249
  solve_your_doubts: Consulte suas dúvidas
246
250
  solve_your_doubts_teaser: Você tem alguma dúvida?
247
251
  something_went_wrong: Oops!, Algo não estava certo ...
@@ -292,5 +296,6 @@ pt:
292
296
  working: Processamento
293
297
  wrong_answer: A resposta não é correta
294
298
  years: anos
299
+ you_earned: Você ganhou
295
300
  you_must_sign_in_before_submitting: Você deve fazer o login antes de começar a enviar suas soluções
296
301
  your_new_organization: sua nova organização
@@ -1,5 +1,5 @@
1
1
  module Mumuki
2
2
  module Laboratory
3
- VERSION = '7.12.1'
3
+ VERSION = '8.1.2'
4
4
  end
5
5
  end
@@ -87,7 +87,11 @@ def exclude_selenium_failing_tests!
87
87
  :json_eq_error,
88
88
  :navigation_error,
89
89
  :organization_not_nil,
90
- :xpath_no_matches
90
+ :xpath_no_matches,
91
+
92
+ # Fails because Rails redirection doesn't include Capybara port.
93
+ # It can be fixed by using path mapping instead of subdomain.
94
+ :subdomain_redirection_without_port
91
95
  )
92
96
  end
93
97
  end
@@ -26,6 +26,25 @@ describe DiscussionsController, organization_workspace: :test do
26
26
  end
27
27
  end
28
28
 
29
+ describe 'index' do
30
+ context 'when user is banned from forum' do
31
+ before { user.update! banned_from_forum: true }
32
+ before { get :index, params: exercise_params }
33
+
34
+ it { expect(response.status).to eq 404 }
35
+ end
36
+
37
+ context 'when user has exam in progress' do
38
+ let!(:exam) { create(:exam) }
39
+ before { exam.authorize! user }
40
+ before { exam.start! user }
41
+
42
+ before { get :index, params: exercise_params }
43
+
44
+ it { expect(response.status).to eq 403 }
45
+ end
46
+ end
47
+
29
48
  describe 'post' do
30
49
  before { allow_any_instance_of(DiscussionsController).to receive(:discussion_params).and_return title: 'A title' }
31
50
  before { post :create, params: exercise_params }
@@ -89,7 +89,7 @@ describe ExerciseSolutionsController, organization_workspace: :test do
89
89
 
90
90
  it { expect(response.body).to json_eq({ status: :failed, guide_finished_by_solution: false },
91
91
  except: [:html, :remaining_attempts_html, :title_html, :button_html,
92
- :expectations, :test_results, :tips, :current_exp]) }
92
+ :expectations, :test_results, :tips, :current_exp, :level_up_html]) }
93
93
 
94
94
  it 'includes kids specific renders' do
95
95
  body = JSON.parse(response.body)
@@ -10,7 +10,7 @@
10
10
  #
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema.define(version: 20201027152806) do
13
+ ActiveRecord::Schema.define(version: 20201130163114) do
14
14
 
15
15
  # These are extensions that must be enabled in order to support this database
16
16
  enable_extension "plpgsql"
@@ -433,6 +433,7 @@ ActiveRecord::Schema.define(version: 20201027152806) do
433
433
  t.datetime "privacy_terms_accepted_at"
434
434
  t.datetime "legal_terms_accepted_at"
435
435
  t.datetime "forum_terms_accepted_at"
436
+ t.boolean "banned_from_forum"
436
437
  t.index ["avatar_type", "avatar_id"], name: "index_users_on_avatar_type_and_avatar_id"
437
438
  t.index ["disabled_at"], name: "index_users_on_disabled_at"
438
439
  t.index ["last_organization_id"], name: "index_users_on_last_organization_id"
@@ -0,0 +1,181 @@
1
+ require 'spec_helper'
2
+
3
+ feature 'Immersive redirection Flow', organization_workspace: :test, subdomain_redirection_without_port: true do
4
+ def create_guide(name)
5
+ create(:guide, name: name)
6
+ end
7
+
8
+ def create_immersive_organization(name, guides)
9
+ create(:organization,
10
+ name: name,
11
+ immersive: true,
12
+ book:
13
+ create(:book,
14
+ chapters: [
15
+ create(:chapter, lessons: guides.map { |it| create(:lesson, guide: it) })
16
+ ]))
17
+ end
18
+
19
+ let(:organization) { Organization.current }
20
+ let(:book) { organization.book }
21
+
22
+ let(:guide_one) { create_guide 'guide one' }
23
+ let(:guide_two) { create_guide 'guide two' }
24
+ let(:guide_three) { create_guide 'guide three' }
25
+
26
+ let(:lesson_one) { create(:lesson, guide: guide_one) }
27
+ let(:lesson_two) { create(:lesson, guide: guide_two) }
28
+ let(:lesson_three) { create(:lesson, guide: guide_three) }
29
+
30
+ before { book.update! chapters: [create(:chapter, lessons: [lesson_one, lesson_two, lesson_three])] }
31
+ before { set_current_user! user }
32
+
33
+ shared_examples 'immersive redirection' do |organization_name|
34
+ scenario 'should redirect to immersive organization' do
35
+ expect(page).to have_text organization_name
36
+ expect(page).not_to have_text "Go to #{organization_name}"
37
+ end
38
+ end
39
+
40
+ shared_examples 'navigate to content' do |guide_name|
41
+ scenario 'should navigate to content' do
42
+ expect(page).to have_text guide_name
43
+ expect(page).to have_text 'Exercises'
44
+ end
45
+ end
46
+
47
+ shared_examples 'navigate to main page' do
48
+ scenario 'should navigate to main page' do
49
+ expect(page).to have_text 'Start Practicing!'
50
+ end
51
+ end
52
+
53
+ shared_examples 'navigate to discussions main page' do
54
+ scenario 'should navigate to discussions main page' do
55
+ expect(page).to have_text 'Discussions'
56
+ end
57
+ end
58
+
59
+ shared_examples 'navigate to user profile' do
60
+ scenario 'should navigate to user profile' do
61
+ expect(page).to have_text user.full_name
62
+ end
63
+ end
64
+
65
+ context 'with one immersive organization' do
66
+ let(:user) { create(:user, permissions: {student: 'immersive-orga/*'}) }
67
+ let!(:immersive_orga) { create_immersive_organization('immersive-orga', [guide_one]) }
68
+
69
+ feature 'when navigating to an available content' do
70
+ before { visit lesson_path(lesson_one) }
71
+ it_behaves_like 'immersive redirection', 'immersive-orga'
72
+ it_behaves_like 'navigate to content', 'guide one'
73
+ end
74
+
75
+ feature 'when navigating to an unavailable content' do
76
+ before { visit lesson_path(lesson_two) }
77
+ it_behaves_like 'immersive redirection', 'immersive-orga'
78
+ it_behaves_like 'navigate to main page'
79
+ end
80
+
81
+ context 'when navigating to a discussion' do
82
+ feature 'and forum enabled' do
83
+ before { immersive_orga.update(forum_enabled: true) }
84
+ before { visit discussions_path }
85
+ it_behaves_like 'immersive redirection', 'immersive-orga'
86
+ it_behaves_like 'navigate to discussions main page'
87
+ end
88
+
89
+ feature 'and forum not enabled' do
90
+ before { visit discussions_path }
91
+ it_behaves_like 'immersive redirection', 'immersive-orga'
92
+ it_behaves_like 'navigate to main page'
93
+ end
94
+ end
95
+
96
+ feature 'when navigating to another route' do
97
+ before { visit user_path }
98
+ it_behaves_like 'immersive redirection', 'immersive-orga'
99
+ it_behaves_like 'navigate to user profile'
100
+ end
101
+ end
102
+
103
+ context 'with many immersive organizations' do
104
+ let(:user) { create(:user, permissions: {student: 'immersive-orga/*:private/*'}) }
105
+
106
+ let!(:private_orga) { create_immersive_organization('private', [guide_one, guide_two]) }
107
+ let!(:immersive_orga) { create_immersive_organization('immersive-orga', [guide_one]) }
108
+
109
+ shared_examples 'organization chooser' do
110
+ scenario 'should display organization chooser' do
111
+ expect(page).to have_text 'You have registered in another organization'
112
+ end
113
+ end
114
+
115
+ def choose_organization(name)
116
+ within '.modal' do
117
+ click_on "Go to #{name}"
118
+ end
119
+ end
120
+
121
+ feature 'when content is present in one of them' do
122
+ before { visit lesson_path(lesson_two) }
123
+ it_behaves_like 'immersive redirection', 'private'
124
+ it_behaves_like 'navigate to content', 'guide two'
125
+ end
126
+
127
+ feature 'when content is present in two of them' do
128
+ before { visit lesson_path(lesson_one) }
129
+ it_behaves_like 'organization chooser'
130
+
131
+ context 'after choosing an organization' do
132
+ before { choose_organization 'private' }
133
+ it_behaves_like 'immersive redirection', 'private'
134
+ it_behaves_like 'navigate to content', 'guide one'
135
+ end
136
+ end
137
+
138
+ describe 'when content is not present on any of them' do
139
+ before { visit lesson_path(lesson_three) }
140
+ it_behaves_like 'organization chooser'
141
+
142
+ context 'after choosing an organization' do
143
+ before { choose_organization 'immersive-orga' }
144
+ it_behaves_like 'immersive redirection', 'immersive-orga'
145
+ it_behaves_like 'navigate to main page'
146
+ end
147
+ end
148
+
149
+ feature 'when navigating to another route' do
150
+ before { visit user_path }
151
+ it_behaves_like 'organization chooser'
152
+
153
+ context 'after choosing an organization' do
154
+ before { choose_organization 'immersive-orga' }
155
+ it_behaves_like 'immersive redirection', 'immersive-orga'
156
+ it_behaves_like 'navigate to user profile'
157
+ end
158
+ end
159
+
160
+ context 'when navigating to a discussion' do
161
+ before { immersive_orga.update(forum_enabled: true) }
162
+ before { visit discussions_path }
163
+
164
+ it_behaves_like 'organization chooser'
165
+
166
+ feature 'and forum enabled' do
167
+ before { choose_organization 'immersive-orga' }
168
+
169
+ it_behaves_like 'immersive redirection', 'immersive-orga'
170
+ it_behaves_like 'navigate to discussions main page'
171
+ end
172
+
173
+ feature 'and forum not enabled' do
174
+ before { choose_organization 'private' }
175
+
176
+ it_behaves_like 'immersive redirection', 'private'
177
+ it_behaves_like 'navigate to main page'
178
+ end
179
+ end
180
+ end
181
+ end
@@ -5,10 +5,9 @@ feature 'Profile Flow', organization_workspace: :test do
5
5
  let(:haskell) { create(:haskell) }
6
6
  let!(:chapter) {
7
7
  create(:chapter, name: 'Functional Programming', lessons: [
8
- build(:lesson, name: 'Values and Functions', language: haskell, description: 'Values are everywhere...', exercises: [
9
- build(:exercise, name: 'The Basic Values', description: "Let's say we want to declare a variable...")
10
- ])
8
+ build(:lesson, name: 'Values and Functions', language: haskell, description: 'Values are everywhere...', exercises: [exercise])
11
9
  ]) }
10
+ let(:exercise) { build(:exercise, name: 'The Basic Values', description: "Let's say we want to declare a variable...") }
12
11
  let(:problem) { create :problem}
13
12
  let(:message) {
14
13
  {'exercise_id' => problem.id,
@@ -71,6 +70,39 @@ feature 'Profile Flow', organization_workspace: :test do
71
70
  context 'logged in user' do
72
71
  before { set_current_user! user }
73
72
 
73
+ context 'user with uncompleted profile after saving' do
74
+ before { user.update! last_name: 'last_name', birthdate: Time.now - 20.years, gender: 'female' }
75
+
76
+ let(:button_options) do
77
+ # Match :first is used because there are two buttons: mobile and desktop.
78
+ { class: 'mu-edit-profile-btn', match: :first }.tap do |options|
79
+ options.merge!(disabled: true) unless run_with_selenium?
80
+ end
81
+ end
82
+
83
+ context 'when visiting an exercise' do
84
+ scenario 'is redirected to previous path' do
85
+ visit "/exercises/#{exercise.transparent_id}"
86
+ fill_in('user_first_name', with: 'first_name')
87
+
88
+ click_on(button_options)
89
+ expect(page).to have_text(exercise.description)
90
+ end
91
+ end
92
+
93
+ context 'when visiting profile edition' do
94
+ scenario 'is redirected to read only profile' do
95
+ visit "/user/edit"
96
+ fill_in('user_first_name', with: 'first_name')
97
+
98
+ # Match :first is used because there are two buttons: mobile and desktop.
99
+ click_on(button_options)
100
+ expect(page).to have_text('Your data was updated successfuly')
101
+ expect(page).to have_text('Profile')
102
+ end
103
+ end
104
+ end
105
+
74
106
  context 'with no messages' do
75
107
 
76
108
  scenario 'visit messages tab' do
@@ -0,0 +1,155 @@
1
+ require 'spec_helper'
2
+
3
+ feature 'Terms Flow', organization_workspace: :test do
4
+ let(:forum_terms_scopes) { Term::FORUM_RELATED }
5
+ let(:general_terms_scopes) { Term::GENERAL }
6
+ let(:role_terms_scopes) { Term::ROLE_SPECIFIC }
7
+
8
+ let(:all_terms_scopes) { forum_terms_scopes + general_terms_scopes + role_terms_scopes }
9
+ let!(:terms) { all_terms_scopes.map { |it| create(:term, scope: it, locale: Organization.current.locale) } }
10
+
11
+ let(:test_organization) { Organization.locate!("test") }
12
+
13
+ let!(:exercise) { create(:indexed_exercise) }
14
+ let(:expected_terms) { [] }
15
+ let(:unexpected_terms) { all_terms_scopes - expected_terms }
16
+
17
+ let(:student) { create(:user, uid: 'user.student@mumuki.org', permissions: {student: 'test/*'}) }
18
+
19
+ let(:janitor) { create(:user, uid: 'user.janitor@mumuki.org', permissions: {student: 'test/*', janitor: 'other/*'}) }
20
+
21
+ before { reindex_current_organization! }
22
+
23
+ shared_context 'has expected terms' do
24
+ scenario 'with expected terms' do
25
+ visit terms_path
26
+
27
+ expected_terms.each do |it|
28
+ expect(page).to have_text(Term.find_by(scope: it).content)
29
+ end
30
+
31
+ unexpected_terms.each do |it|
32
+ expect(page).not_to have_text(Term.find_by(scope: it).content)
33
+ end
34
+ end
35
+ end
36
+
37
+ context 'with student logged in' do
38
+ before { set_current_user! student }
39
+
40
+ describe 'visit user terms path' do
41
+ let(:terms_path) { '/user/terms' }
42
+ let(:expected_terms) { general_terms_scopes }
43
+
44
+ it_behaves_like 'has expected terms'
45
+ end
46
+
47
+ context 'visit forum' do
48
+ let(:terms_path) { '/discussions/terms' }
49
+
50
+ context 'with disabled forum' do
51
+
52
+ it_behaves_like 'has expected terms'
53
+ end
54
+
55
+ context 'with enabled forum' do
56
+ let(:expected_terms) { forum_terms_scopes }
57
+ before { test_organization.update! forum_enabled: true }
58
+
59
+ it_behaves_like 'has expected terms'
60
+ end
61
+ end
62
+ end
63
+
64
+ context 'with janitor logged in' do
65
+ before { set_current_user! janitor }
66
+
67
+ describe 'visit user terms path' do
68
+ let(:terms_path) { '/user/terms' }
69
+ let(:expected_terms) { general_terms_scopes + %w(janitor) }
70
+
71
+ it_behaves_like 'has expected terms'
72
+ end
73
+
74
+ context 'with accepted general terms' do
75
+ before { janitor.accept_profile_terms! }
76
+
77
+ context 'visit forum' do
78
+ let(:terms_path) { '/discussions/terms' }
79
+
80
+ context 'with enabled forum' do
81
+ let(:expected_terms) { forum_terms_scopes }
82
+ before { test_organization.update! forum_enabled: true }
83
+
84
+ it_behaves_like 'has expected terms'
85
+ end
86
+ end
87
+
88
+ scenario 'visit any other path' do
89
+ visit '/'
90
+
91
+ expect(page).to have_text('Start Practicing')
92
+ end
93
+ end
94
+
95
+ context 'with unaccepted role terms' do
96
+
97
+ context 'visit forum' do
98
+ let(:terms_path) { '/discussions/terms' }
99
+ before { test_organization.update! forum_enabled: true }
100
+
101
+ scenario 'with enabled forum' do
102
+ visit '/discussions'
103
+ expect(page).to have_text('Accept terms')
104
+
105
+ click_on 'Accept'
106
+ expect(page).to have_text('Discussions')
107
+ end
108
+ end
109
+
110
+ scenario 'visit any other path' do
111
+ visit '/'
112
+ expect(page).to have_text('Accept terms')
113
+
114
+ click_on 'Accept'
115
+ expect(page).to have_text(test_organization.book.name)
116
+ end
117
+
118
+ scenario 'visit user path' do
119
+ visit '/user'
120
+
121
+ expect(page).to have_text(janitor.first_name)
122
+ end
123
+ end
124
+ end
125
+
126
+ context 'without user logged in' do
127
+ describe 'visit user terms path' do
128
+ let(:terms_path) { '/user/terms' }
129
+ let(:expected_terms) { general_terms_scopes }
130
+
131
+ it_behaves_like 'has expected terms'
132
+ end
133
+
134
+ scenario 'visit any other path' do
135
+ visit '/'
136
+
137
+ expect(page).to have_text('Start Practicing')
138
+ end
139
+
140
+ context 'visit forum' do
141
+ let(:terms_path) { '/discussions/terms' }
142
+
143
+ context 'with enabled forum' do
144
+ before { test_organization.update! forum_enabled: true }
145
+
146
+ scenario 'visit forum' do
147
+ visit '/discussions/terms'
148
+ expect(page).to have_text('You may have mistyped the address or the page may have moved')
149
+ end
150
+ end
151
+ end
152
+ end
153
+
154
+ end
155
+