mumuki-laboratory 9.0.3 → 9.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (171) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/mumuki_laboratory/application/codemirror.js +10 -2
  3. data/app/assets/javascripts/mumuki_laboratory/application/discussions.js +49 -8
  4. data/app/assets/javascripts/mumuki_laboratory/application/gamification.js +3 -3
  5. data/app/assets/javascripts/mumuki_laboratory/application/kids.js +11 -7
  6. data/app/assets/javascripts/mumuki_laboratory/application/kindergarten.js +3 -3
  7. data/app/assets/javascripts/mumuki_laboratory/application/messages.js +3 -3
  8. data/app/assets/javascripts/mumuki_laboratory/application/mu-modal-carrousel.js +4 -4
  9. data/app/assets/javascripts/mumuki_laboratory/application/multiple-files.js +18 -5
  10. data/app/assets/javascripts/mumuki_laboratory/application/multiple-scenarios.js +1 -1
  11. data/app/assets/javascripts/mumuki_laboratory/application/organization.js +32 -0
  12. data/app/assets/javascripts/mumuki_laboratory/application/primary.js +4 -4
  13. data/app/assets/javascripts/mumuki_laboratory/application/profile.js +0 -6
  14. data/app/assets/javascripts/mumuki_laboratory/application/progress.js +1 -1
  15. data/app/assets/javascripts/mumuki_laboratory/application/speech-bubble-renderer.js +1 -1
  16. data/app/assets/javascripts/mumuki_laboratory/application/submission.js +4 -3
  17. data/app/assets/javascripts/mumuki_laboratory/application/submissions-store.js +1 -1
  18. data/app/assets/javascripts/mumuki_laboratory/application/toast.js +3 -0
  19. data/app/assets/javascripts/mumuki_laboratory/application/tooltip.js +1 -1
  20. data/app/assets/javascripts/mumuki_laboratory/application/upload.js +2 -2
  21. data/app/assets/javascripts/mumuki_laboratory/application/user.js +34 -1
  22. data/app/assets/stylesheets/mumuki_laboratory/application.scss +0 -1
  23. data/app/assets/stylesheets/mumuki_laboratory/application/_errors.scss +1 -1
  24. data/app/assets/stylesheets/mumuki_laboratory/application/_layout.scss +1 -27
  25. data/app/assets/stylesheets/mumuki_laboratory/application/_modules.scss +1 -2
  26. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_activity.scss +14 -0
  27. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_avatar.scss +5 -0
  28. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_breadcrumb.scss +2 -2
  29. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_datepicker.scss +0 -4
  30. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_discussion.scss +49 -59
  31. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_editor.scss +16 -18
  32. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_exercise_assignment.scss +2 -11
  33. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_exercise_results.scss +1 -7
  34. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_faqs.scss +3 -3
  35. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_flash.scss +7 -46
  36. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_kids.scss +19 -4
  37. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_kids_results.scss +18 -23
  38. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_kindergarten.scss +1 -9
  39. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_overlap.scss +1 -1
  40. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_progress_bar.scss +5 -5
  41. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_terms.scss +3 -2
  42. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_timer.scss +1 -3
  43. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_user_menu.scss +14 -7
  44. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_user_profile.scss +1 -2
  45. data/app/controllers/application_controller.rb +4 -2
  46. data/app/controllers/discussions_messages_controller.rb +9 -3
  47. data/app/controllers/users_controller.rb +13 -0
  48. data/app/helpers/application_helper.rb +5 -5
  49. data/app/helpers/assignment_result_helper.rb +3 -2
  50. data/app/helpers/assistance_box_helper.rb +1 -1
  51. data/app/helpers/concerns/with_student_path_navigation.rb +8 -3
  52. data/app/helpers/concerns/with_student_path_navigation/continue_navigation.rb +1 -1
  53. data/app/helpers/concerns/with_student_path_navigation/finish_navigation.rb +1 -1
  54. data/app/helpers/concerns/with_student_path_navigation/next_parent_navigation.rb +7 -0
  55. data/app/helpers/concerns/with_student_path_navigation/revisit_navigation.rb +1 -1
  56. data/app/helpers/discussions_helper.rb +64 -23
  57. data/app/helpers/editor_tabs_helper.rb +10 -6
  58. data/app/helpers/email_helper.rb +2 -2
  59. data/app/helpers/exercise_input_helper.rb +2 -3
  60. data/app/helpers/links_helper.rb +12 -9
  61. data/app/helpers/menu_bar_helper.rb +1 -1
  62. data/app/helpers/messages_helper.rb +1 -1
  63. data/app/helpers/multiple_file_editor_helper.rb +2 -1
  64. data/app/helpers/overlapped_buttons_helper.rb +22 -12
  65. data/app/helpers/profile_helper.rb +3 -3
  66. data/app/helpers/toast_helper.rb +27 -0
  67. data/app/helpers/user_activity_helper.rb +48 -0
  68. data/app/helpers/user_menu_helper.rb +4 -0
  69. data/app/views/book/show.html.erb +2 -2
  70. data/app/views/certificates/verify.html.erb +1 -1
  71. data/app/views/chapters/show.html.erb +2 -2
  72. data/app/views/discussions/_description_message.html.erb +1 -1
  73. data/app/views/discussions/_message.html.erb +32 -7
  74. data/app/views/discussions/_new_message.html.erb +13 -2
  75. data/app/views/discussions/index.html.erb +8 -10
  76. data/app/views/discussions/new.html.erb +2 -2
  77. data/app/views/discussions/show.html.erb +20 -12
  78. data/app/views/exam_registrations/show.html.erb +10 -11
  79. data/app/views/exercise_solutions/_assistant_rules_box.html.erb +1 -1
  80. data/app/views/exercise_solutions/_contextualization_results_body.html.erb +1 -1
  81. data/app/views/exercise_solutions/_contextualization_results_container.html.erb +1 -1
  82. data/app/views/exercise_solutions/_kids_results_button.html.erb +2 -2
  83. data/app/views/exercise_solutions/_results.html.erb +1 -1
  84. data/app/views/exercises/_exercise_assignment.html.erb +2 -2
  85. data/app/views/exercises/_exercise_skipped.html.erb +1 -1
  86. data/app/views/exercises/_read_only.html.erb +108 -105
  87. data/app/views/exercises/show.html.erb +7 -7
  88. data/app/views/guides/_guide.html.erb +1 -1
  89. data/app/views/guides/_guide_container.html.erb +4 -4
  90. data/app/views/invitations/_invitation_form.html.erb +5 -4
  91. data/app/views/layouts/_authoring.html.erb +1 -1
  92. data/app/views/layouts/_discussions.html.erb +7 -7
  93. data/app/views/layouts/_kids.html.erb +5 -5
  94. data/app/views/layouts/_kindergarten.html.erb +10 -6
  95. data/app/views/layouts/_main.html.erb +10 -10
  96. data/app/views/layouts/_organizations_listing.html.erb +2 -2
  97. data/app/views/layouts/_progress_bar.html.erb +2 -0
  98. data/app/views/layouts/_submission_result_error.html.erb +1 -1
  99. data/app/views/layouts/_test_results.html.erb +1 -1
  100. data/app/views/layouts/_timer.html.erb +1 -1
  101. data/app/views/layouts/_user_menu.html.erb +4 -3
  102. data/app/views/layouts/application.html.erb +39 -42
  103. data/app/views/layouts/exercise_inputs/editors/_code.html.erb +4 -4
  104. data/app/views/layouts/exercise_inputs/editors/_free_form.html.erb +1 -1
  105. data/app/views/layouts/exercise_inputs/editors/_multiple_choice.html.erb +7 -9
  106. data/app/views/layouts/exercise_inputs/editors/_multiple_files.html.erb +10 -10
  107. data/app/views/layouts/exercise_inputs/editors/_single_choice.html.erb +6 -8
  108. data/app/views/layouts/exercise_inputs/editors/_text.html.erb +2 -3
  109. data/app/views/layouts/exercise_inputs/editors/_upload.html.erb +5 -5
  110. data/app/views/layouts/exercise_inputs/forms/_form.html.erb +1 -1
  111. data/app/views/layouts/exercise_inputs/forms/_interactive_form.html.erb +2 -2
  112. data/app/views/layouts/exercise_inputs/forms/_kids_form.html.erb +1 -1
  113. data/app/views/layouts/exercise_inputs/forms/_playground_form.html.erb +2 -2
  114. data/app/views/layouts/exercise_inputs/forms/_problem_form.html.erb +13 -9
  115. data/app/views/layouts/exercise_inputs/layouts/_input_primary.html.erb +2 -2
  116. data/app/views/layouts/exercise_inputs/layouts/_input_right.html.erb +2 -2
  117. data/app/views/layouts/exercise_inputs/read_only_editors/_code.html.erb +1 -1
  118. data/app/views/layouts/exercise_inputs/read_only_editors/_free_form.html.erb +1 -1
  119. data/app/views/layouts/exercise_inputs/read_only_editors/_multiple_choice.html.erb +4 -4
  120. data/app/views/layouts/exercise_inputs/read_only_editors/_multiple_files.html.erb +2 -2
  121. data/app/views/layouts/exercise_inputs/read_only_editors/_single_choice.html.erb +4 -4
  122. data/app/views/layouts/exercise_inputs/read_only_editors/_text.erb +1 -1
  123. data/app/views/layouts/modals/_avatar_picker.html.erb +2 -5
  124. data/app/views/layouts/modals/_guide_corollary.html.erb +4 -8
  125. data/app/views/layouts/modals/_kids_context.html.erb +7 -5
  126. data/app/views/layouts/modals/_kids_results.html.erb +2 -2
  127. data/app/views/layouts/modals/_kids_results_aborted.html.erb +2 -2
  128. data/app/views/layouts/modals/_kindergarten_context.html.erb +3 -3
  129. data/app/views/layouts/modals/_kindergarten_results.html.erb +3 -3
  130. data/app/views/layouts/modals/_kindergarten_results_aborted.html.erb +2 -2
  131. data/app/views/layouts/modals/_level_up.html.erb +2 -5
  132. data/app/views/layouts/modals/_new_message.html.erb +5 -5
  133. data/app/views/notifications/_dropdown.html.erb +3 -3
  134. data/app/views/users/_activity_indicator.html.erb +17 -0
  135. data/app/views/users/_edit_user_form.html.erb +6 -6
  136. data/app/views/users/_profile_fields.html.erb +6 -6
  137. data/app/views/users/_user_form.html.erb +2 -2
  138. data/app/views/users/activity.html.erb +37 -0
  139. data/app/views/users/certificates.html.erb +26 -24
  140. data/app/views/users/discussions.html.erb +23 -21
  141. data/app/views/users/messages.html.erb +22 -20
  142. data/app/views/users/show.html.erb +5 -3
  143. data/app/views/users/terms.html.erb +4 -2
  144. data/config/initializers/inflections.rb +3 -0
  145. data/config/routes.rb +3 -0
  146. data/lib/mumuki/laboratory.rb +1 -1
  147. data/lib/mumuki/laboratory/extensions.rb +1 -0
  148. data/lib/mumuki/laboratory/extensions/date_and_time.rb +11 -0
  149. data/lib/mumuki/laboratory/locales/en.yml +28 -2
  150. data/lib/mumuki/laboratory/locales/es-CL.yml +33 -4
  151. data/lib/mumuki/laboratory/locales/es.yml +33 -4
  152. data/lib/mumuki/laboratory/locales/pt.yml +34 -3
  153. data/lib/mumuki/laboratory/version.rb +1 -1
  154. data/spec/capybara_helper.rb +1 -0
  155. data/spec/controllers/discussions_messages_controller_spec.rb +84 -3
  156. data/spec/dummy/db/schema.rb +23 -3
  157. data/spec/features/discussion_flow_spec.rb +22 -2
  158. data/spec/features/exercise_flow_spec.rb +1 -1
  159. data/spec/features/guide_reset_spec.rb +1 -1
  160. data/spec/features/terms_flow_spec.rb +1 -2
  161. data/spec/features/user_activity_flow_spec.rb +65 -0
  162. data/spec/helpers/breadcrumbs_helper_spec.rb +2 -2
  163. data/spec/helpers/user_activity_helper_spec.rb +32 -0
  164. data/spec/helpers/with_navigation_spec.rb +36 -13
  165. data/spec/javascripts/editors-spec.js +3 -3
  166. data/spec/javascripts/kids-button-spec.js +2 -2
  167. data/spec/javascripts/upload-spec.js +8 -8
  168. metadata +133 -123
  169. data/app/assets/stylesheets/mumuki_laboratory/application/hovers.scss +0 -12
  170. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_checkboxes.scss +0 -34
  171. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_guide_corollary.scss +0 -9
@@ -1,4 +1,3 @@
1
- ---
2
1
  pt:
3
2
  aborted: Opa, não pudemos avaliar sua solução
4
3
  abort_explanation_html: <li>Verifique se o seu programa não possui recursão ou um loop infinito</li> <li>Verifique se você tem uma conexão com a internet</li> <li>Espere um pouco e tente novamente</li>
@@ -16,6 +15,9 @@ pt:
16
15
  appendix_teaser: Você quer saber mais? <a href="%{link}"> Consulte o apêndice deste capítulo </a>
17
16
  approved_message: Validado pelo mentor
18
17
  are_you_sure: 'Tem certeza de que deseja %{action}?'
18
+ approved_messages:
19
+ one: validado
20
+ other: validados
19
21
  ask_a_question: Faça uma pergunta!
20
22
  ask_community: Pergunte à comunidade
21
23
  ask_redirect: Você quer que nós o levemos para lá?
@@ -65,6 +67,18 @@ pt:
65
67
  created_exercises: Exercícios criados
66
68
  created_guides: Lições criadas
67
69
  date: Data
70
+ deleted_by: Removido pelo
71
+ deleted_message_warning: Se você violar repetidamente essas ou outras regras da Área de Consulta, seu acesso a ela pode ser proibido ou você pode sofrer consequências mais graves, como a expulsão do curso.
72
+ deletion_motive:
73
+ inappropriate_content:
74
+ present: Inclui conteúdo impróprio
75
+ past: Incluiu conteúdo impróprio
76
+ shares_solution:
77
+ present: Compartilhe a solução correta
78
+ past: Compartilhou a solução correta
79
+ discloses_personal_information:
80
+ present: Divulga informações pessoais
81
+ past: Divulgar informações pessoais
68
82
  day: Dia
69
83
  days: Dias
70
84
  description: Descrição
@@ -80,6 +94,7 @@ pt:
80
94
  discussions_will_be_here: As perguntas que você fizer no espaço de consulta aparecerão aqui.
81
95
  download: Faça o download do que você fez
82
96
  edit: Editar
97
+ edit_message: Editar mensagem
83
98
  edit_profile: Editar perfil
84
99
  editor_placeholder: ... Escreva sua solução aqui ...
85
100
  email: E-mail
@@ -177,8 +192,13 @@ pt:
177
192
  one: 1 mensagem
178
193
  other: '%{count} mensagens'
179
194
  message: Mensagem
195
+ message_deleted: Esta mensagem foi excluída porque %{motive}, o que viola as %{forum_terms}.
180
196
  messages: Mensagens
181
197
  messages_error: As mensagens acima não estão disponíveis no momento. Eu tentei novamente mais tarde!
198
+ mais tarde!
199
+ messages_pluralized:
200
+ one: Mensagem
201
+ other: Mensagens
182
202
  minute: minuto
183
203
  minutes: minutos
184
204
  moderation: Mentoria
@@ -232,6 +252,8 @@ pt:
232
252
  permissions: Permissões
233
253
  please_fill_profile_data: Preencha suas informações pessoais para continuar!
234
254
  please_validate: Você está prestes a entrar no curso. Para oferecer uma experiência melhor, valide que seus dados abaixo sejam reais e corretos.
255
+ preview: Vista prévia
256
+ preview_error: A visualizaçao não pode ser mostrada. Verifique sua conexão com a internet ou tente com uma mensagem mais curta.
235
257
  previous_exercise: Anterior
236
258
  problem_with_exercise: '[Mumuki] Erro com exercício %{title}'
237
259
  processing_your_solution: Estamos processando sua solução
@@ -254,6 +276,7 @@ pt:
254
276
  send: Enviar
255
277
  sending_solution: Solução de envio
256
278
  show: Mostrar
279
+ show_message: Mostrar mensagem
257
280
  sign_in: Iniciar sessão
258
281
  sign_in_action: iniciar sessão
259
282
  sign_out: Fechar Sessão
@@ -264,12 +287,18 @@ pt:
264
287
  skipped_solve_anyway: Resolver mesmo assim
265
288
  solution: Solução
266
289
  solved: Resolvido
267
- solved_count: '%{count} resolvido'
268
290
  solved_exercises: Exercícios resolvidos
291
+ solved_count:
292
+ one: 1 resolvido
293
+ other: '%{count} resolvidos'
269
294
  solve_doubts: Resolvi dúvidas
270
295
  solve_more_exercises_to_level_up: Resolva mais <span>number</span> exercícios para avançar para o próximo nível.
271
296
  solve_your_doubts: Consulte suas dúvidas
272
297
  solve_your_doubts_teaser: Você tem alguma dúvida?
298
+ solved_exercises_count:
299
+ one: resolvido
300
+ other: resolvidos
301
+ solved_exercises_percentage: realizado
273
302
  something_went_wrong: Oops!, Algo não estava certo ...
274
303
  sort: Ordenar
275
304
  sources: Bibliografia
@@ -301,6 +330,7 @@ pt:
301
330
  to_pending_review: Marcar como resolvida
302
331
  to_solved: Marcar como resolvida
303
332
  unauthorized_explanation: Opa! Isso é o que é conhecido como %{error}, ou seja, você não fez logon.
333
+ total: Total
304
334
  uncategorized: Não classificado
305
335
  unlocked_medal_as_avatar: Você ganhou essa medalha! Agora você pode escolhê-la como avatar.
306
336
  unspecified: Eu preferiria não dizer
@@ -312,7 +342,8 @@ pt:
312
342
  user_data_updated: Os seus dados foram atualizados corretamente
313
343
  username: Nome de usuário
314
344
  view_details: Ver detalhes
315
- want_permissions: O próximo usuário requer permissões
345
+ want_permissions: O próximo usuário requer permissões para a organização
346
+ week_of: Semana de %{date}
316
347
  welcome: Convidamos você a {name}!
317
348
  working: Processamento
318
349
  wrong_answer: A resposta não é correta
@@ -1,5 +1,5 @@
1
1
  module Mumuki
2
2
  module Laboratory
3
- VERSION = '9.0.3'
3
+ VERSION = '9.1.1'
4
4
  end
5
5
  end
@@ -83,6 +83,7 @@ def exclude_selenium_failing_tests!
83
83
 
84
84
  # TODO: the following ignored groups should be fixed
85
85
  :element_not_interactable_error,
86
+ :toast_interferes_with_view,
86
87
  :invalid_selector_error,
87
88
  :json_eq_error,
88
89
  :navigation_error,
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe DiscussionsMessagesController, organization_workspace: :test do
3
+ describe DiscussionsMessagesController, type: :controller, organization_workspace: :test do
4
4
  let(:student) { create(:user, permissions: {student: 'test/*'}) }
5
5
  let(:moderator) { create(:user, permissions: {moderator: 'test/*', student: 'test/*'}) }
6
6
 
@@ -31,6 +31,68 @@ describe DiscussionsMessagesController, organization_workspace: :test do
31
31
  end
32
32
  end
33
33
 
34
+ describe 'delete' do
35
+ let(:message) { create(:message, discussion: discussion, sender: student.uid) }
36
+
37
+ describe 'for student' do
38
+ before { set_current_user! student }
39
+
40
+ describe 'own message with permitted motive' do
41
+ before do
42
+ delete :destroy, params: {id: message.id, discussion_id: discussion.id, motive: :self_deleted}
43
+ message.reload
44
+ end
45
+
46
+ it { expect(response.status).to eq 302 }
47
+ it { expect(message.deleted?).to be true }
48
+ it { expect(message.deleted_by).to eq student }
49
+ it { expect(message.deleted_at).to_not eq nil }
50
+ it { expect(message.deletion_motive).to eq 'self_deleted' }
51
+ end
52
+
53
+ describe 'own message with forbidden motive' do
54
+ before do
55
+ delete :destroy, params: {id: message.id, discussion_id: discussion.id, motive: :shares_solution}
56
+ message.reload
57
+ end
58
+
59
+ it { expect(response.status).to eq 403 }
60
+ it { expect(message.deleted?).to be false }
61
+ it { expect(message.deleted_by).to eq nil }
62
+ it { expect(message.deleted_at).to eq nil }
63
+ it { expect(message.deletion_motive).to eq nil }
64
+ end
65
+
66
+ describe 'someone else\'s message' do
67
+ let(:message) { create(:message, discussion: discussion, sender: moderator.uid) }
68
+ before do
69
+ delete :destroy, params: {id: message.id, discussion_id: discussion.id, motive: :self_deleted}
70
+ message.reload
71
+ end
72
+
73
+ it { expect(response.status).to eq 403 }
74
+ it { expect(message.deleted?).to be false }
75
+ it { expect(message.deleted_by).to eq nil }
76
+ it { expect(message.deleted_at).to eq nil }
77
+ it { expect(message.deletion_motive).to eq nil }
78
+ end
79
+ end
80
+
81
+ describe 'for moderator' do
82
+ before do
83
+ set_current_user! moderator
84
+ delete :destroy, params: {id: message.id, discussion_id: discussion.id, motive: :inappropriate_content}
85
+ message.reload
86
+ end
87
+
88
+ it { expect(response.status).to eq 302 }
89
+ it { expect(message.deleted?).to be true }
90
+ it { expect(message.deleted_by).to eq moderator }
91
+ it { expect(message.deleted_at).to_not eq nil }
92
+ it { expect(message.deletion_motive).to eq 'inappropriate_content' }
93
+ end
94
+ end
95
+
34
96
  describe 'approve' do
35
97
  let(:message) { create(:message, discussion: discussion, sender: student.uid) }
36
98
 
@@ -42,7 +104,7 @@ describe DiscussionsMessagesController, organization_workspace: :test do
42
104
  it { expect(message.reload.approved).to be false }
43
105
  end
44
106
 
45
- describe 'for student' do
107
+ describe 'for moderator' do
46
108
  before { set_current_user! moderator }
47
109
  before { post :approve, params: {id: message.id, discussion_id: discussion.id} }
48
110
 
@@ -62,12 +124,31 @@ describe DiscussionsMessagesController, organization_workspace: :test do
62
124
  it { expect(message.reload.not_actually_a_question).to be false }
63
125
  end
64
126
 
65
- describe 'for student' do
127
+ describe 'for moderator' do
66
128
  before { set_current_user! moderator }
67
129
  before { post :question, params: {id: message.id, discussion_id: discussion.id} }
68
130
 
69
131
  it { expect(response.status).to eq 200 }
70
132
  it { expect(message.reload.not_actually_a_question).to be true }
71
133
  end
134
+
135
+ describe 'preview' do
136
+ let(:message) { create(:message, content: 'Message in **bold** and _italics_', discussion: discussion, sender: student.uid) }
137
+
138
+ describe 'for student' do
139
+ before { set_current_user! student }
140
+ before { get :preview, params: {content: message.content} }
141
+
142
+ it { expect(response.status).to eq 403 }
143
+ end
144
+
145
+ describe 'for moderator' do
146
+ before { set_current_user! moderator }
147
+ before { get :preview, params: {content: message.content} }
148
+
149
+ it { expect(response.status).to eq 200 }
150
+ it { expect(JSON.parse(response.body)['preview']).to eq "<p>Message in <strong>bold</strong> and <em>italics</em></p>\n" }
151
+ end
152
+ end
72
153
  end
73
154
  end
@@ -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: 20210302181654) do
13
+ ActiveRecord::Schema.define(version: 20210330175706) do
14
14
 
15
15
  # These are extensions that must be enabled in order to support this database
16
16
  enable_extension "plpgsql"
@@ -79,14 +79,16 @@ ActiveRecord::Schema.define(version: 20210302181654) do
79
79
  t.bigint "organization_id"
80
80
  t.datetime "created_at", null: false
81
81
  t.datetime "updated_at", null: false
82
+ t.datetime "start_date"
83
+ t.datetime "end_date"
82
84
  t.index ["organization_id"], name: "index_certificate_programs_on_organization_id"
83
85
  end
84
86
 
85
87
  create_table "certificates", force: :cascade do |t|
86
88
  t.bigint "user_id"
87
89
  t.bigint "certificate_program_id"
88
- t.datetime "start_date"
89
- t.datetime "end_date"
90
+ t.datetime "started_at"
91
+ t.datetime "ended_at"
90
92
  t.string "code"
91
93
  t.datetime "created_at", null: false
92
94
  t.datetime "updated_at", null: false
@@ -121,6 +123,8 @@ ActiveRecord::Schema.define(version: 20210302181654) do
121
123
  t.integer "organization_id"
122
124
  t.datetime "created_at", null: false
123
125
  t.datetime "updated_at", null: false
126
+ t.datetime "period_start"
127
+ t.datetime "period_end"
124
128
  end
125
129
 
126
130
  create_table "discussions", force: :cascade do |t|
@@ -199,6 +203,13 @@ ActiveRecord::Schema.define(version: 20210302181654) do
199
203
  t.index ["exam_registration_id"], name: "index_exam_registrations_exams_on_exam_registration_id"
200
204
  end
201
205
 
206
+ create_table "exam_registrations_users", id: false, force: :cascade do |t|
207
+ t.bigint "exam_registration_id", null: false
208
+ t.bigint "user_id", null: false
209
+ t.index ["exam_registration_id"], name: "index_exam_registrations_users_on_exam_registration_id"
210
+ t.index ["user_id"], name: "index_exam_registrations_users_on_user_id"
211
+ end
212
+
202
213
  create_table "exams", id: :serial, force: :cascade do |t|
203
214
  t.integer "organization_id"
204
215
  t.integer "guide_id"
@@ -368,6 +379,13 @@ ActiveRecord::Schema.define(version: 20210302181654) do
368
379
  t.integer "discussion_id"
369
380
  t.boolean "approved", default: false
370
381
  t.boolean "not_actually_a_question", default: false
382
+ t.datetime "approved_at"
383
+ t.bigint "approved_by_id"
384
+ t.integer "deletion_motive"
385
+ t.datetime "deleted_at"
386
+ t.bigint "deleted_by_id"
387
+ t.index ["approved_by_id"], name: "index_messages_on_approved_by_id"
388
+ t.index ["deleted_by_id"], name: "index_messages_on_deleted_by_id"
371
389
  end
372
390
 
373
391
  create_table "notifications", force: :cascade do |t|
@@ -507,6 +525,8 @@ ActiveRecord::Schema.define(version: 20210302181654) do
507
525
  t.datetime "forum_terms_accepted_at"
508
526
  t.boolean "banned_from_forum"
509
527
  t.boolean "uppercase_mode"
528
+ t.string "delete_account_token"
529
+ t.datetime "delete_account_token_expiration_date"
510
530
  t.index ["avatar_type", "avatar_id"], name: "index_users_on_avatar_type_and_avatar_id"
511
531
  t.index ["disabled_at"], name: "index_users_on_disabled_at"
512
532
  t.index ["last_organization_id"], name: "index_users_on_last_organization_id"
@@ -162,14 +162,27 @@ feature 'Discussion Flow', organization_workspace: :test do
162
162
  end
163
163
 
164
164
  context 'and forum enabled' do
165
- before { Organization.current.update! forum_enabled: true }
165
+ let!(:problem_2_discussion_message) { create(:message, discussion: problem_2_discussions.first, sender: another_student.uid) }
166
+ let!(:another_problem_2_discussion_message) { create(:message, discussion: problem_2_discussions.first, sender: another_student.uid) }
167
+ before do
168
+ Organization.current.update! forum_enabled: true
169
+ another_problem_2_discussion_message.soft_delete! :inappropriate_content, moderator
170
+ end
166
171
 
167
172
  scenario 'newly created discussion' do
168
173
  visit current_path
169
174
  expect(page).to have_text(problem_2.name)
170
175
  expect(page).to have_text('Open')
171
176
  expect(page).to have_text('Messages')
177
+ expect(page).not_to have_text('Preview')
178
+ expect(page).to have_text(problem_2_discussion_message.content)
179
+ expect(page).not_to have_text(another_problem_2_discussion_message.content)
172
180
  expect(page).not_to have_xpath("//div[@class='discussion-actions']")
181
+ expect(page).to_not have_text('Includes inappropriate content')
182
+ expect(page).to_not have_text('Shares the correct solution')
183
+ expect(page).to_not have_text('Discloses personal information')
184
+ expect(page).to have_text('included inappropriate content')
185
+ expect(page).to_not have_text ("Deleted by #{moderator.name}")
173
186
  end
174
187
 
175
188
  context 'for moderator' do
@@ -180,11 +193,18 @@ feature 'Discussion Flow', organization_workspace: :test do
180
193
  expect(page).to have_text(problem_2.name)
181
194
  expect(page).to have_text('Open')
182
195
  expect(page).to have_text('Messages')
196
+ expect(page).to have_text('Preview')
197
+ expect(page).to have_text(problem_2_discussion_message.content)
198
+ expect(page).to have_text(another_problem_2_discussion_message.content)
183
199
  expect(page).to have_xpath("//div[@class='discussion-actions']")
200
+ expect(page).to have_text('Includes inappropriate content')
201
+ expect(page).to have_text('Shares the correct solution')
202
+ expect(page).to have_text('Discloses personal information')
203
+ expect(page).to have_text('included inappropriate content')
204
+ expect(page).to have_text ("Deleted by #{moderator.name}")
184
205
  end
185
206
  end
186
207
  end
187
208
  end
188
209
  end
189
-
190
210
  end
@@ -190,7 +190,7 @@ feature 'Exercise Flow', organization_workspace: :test do
190
190
  expect(page).to have_text('need a hint?')
191
191
  expect(page).to have_selector('.upload')
192
192
  expect(problem_5.language.extension).to eq('gbs')
193
- expect(page.find("//div[@class = 'form-group']/input")['accept']).to eq(".gbs")
193
+ expect(page.find("//input[@id = 'mu-upload-input']")['accept']).to eq(".gbs")
194
194
 
195
195
  expect(page.find("#mu-exercise-id")['value']).to eq(problem_5.id.to_s)
196
196
  expect(page.find("#mu-exercise-layout")['value']).to eq('input_right')
@@ -18,7 +18,7 @@ feature 'Guide Reset Flow', organization_workspace: :test do
18
18
 
19
19
  before { reindex_current_organization! }
20
20
 
21
- let(:restart_xpath) { "//i[@title='#{I18n.t(:restart)}']" }
21
+ let(:restart_xpath) { "//a[@title='#{I18n.t(:restart)}']" }
22
22
 
23
23
  context 'no logged in user' do
24
24
  scenario 'visit guide' do
@@ -92,8 +92,7 @@ feature 'Terms Flow', organization_workspace: :test do
92
92
  end
93
93
  end
94
94
 
95
- context 'with unaccepted role terms' do
96
-
95
+ context 'with unaccepted role terms', :toast_interferes_with_view do
97
96
  context 'visit forum' do
98
97
  let(:terms_path) { '/discussions/terms' }
99
98
  before { test_organization.update! forum_enabled: true }
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+
3
+ feature 'User Activity Flow', organization_workspace: :test do
4
+ let(:user) { create(:user) }
5
+ before { set_current_user!(user) }
6
+
7
+ let(:fake_stats) { double('stats') }
8
+ before do
9
+ allow(UserStats).to receive(:stats_for).and_return(fake_stats)
10
+ allow(fake_stats).to receive(:activity).and_return(
11
+ { exercises: { solved_count: 8, count: 10 },
12
+ messages: { count: 12, approved: 6 } })
13
+ end
14
+
15
+ let(:week_start) { Time.new(2020, 10, 12) }
16
+ before do
17
+ allow(Time).to receive(:now).and_return(week_start)
18
+ end
19
+
20
+ context 'total' do
21
+ before { visit activity_user_path }
22
+
23
+ scenario 'displays exercises done percentage' do
24
+ expect(page).to have_text('80%')
25
+ expect(page).to have_text('done')
26
+ end
27
+
28
+ scenario 'displays exercises solved count' do
29
+ expect(page).to have_text('8')
30
+ expect(page).to have_text('solved')
31
+ end
32
+
33
+ scenario 'displays messages count' do
34
+ expect(page).to have_text('12')
35
+ expect(page).to have_text('messages')
36
+ end
37
+
38
+ scenario 'displays validated messages count' do
39
+ expect(page).to have_text('6')
40
+ expect(page).to have_text('validated')
41
+ end
42
+
43
+ scenario 'displays recent weeks' do
44
+ expect(page).to have_text 'Week of 2020-10-12'
45
+ expect(page).to have_text 'Week of 2020-10-05'
46
+ expect(page).to have_text 'Week of 2020-09-28'
47
+ end
48
+ end
49
+
50
+ context 'selecting a specific week' do
51
+ before do
52
+ visit activity_user_path
53
+ click_on 'Week of 2020-10-12'
54
+ end
55
+
56
+ scenario "redirects to week activity" do
57
+ expect(page).to have_current_path('/user/activity?date_from=2020-10-12&date_to=2020-10-19')
58
+ end
59
+
60
+ scenario "doesn't display exercises done percentage" do
61
+ expect(page).not_to have_text('80%')
62
+ expect(page).not_to have_text('done')
63
+ end
64
+ end
65
+ end