mumuki-laboratory 9.0.4 → 9.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/mumuki_laboratory/application/discussions.js +43 -2
  3. data/app/assets/javascripts/mumuki_laboratory/application/user.js +1 -1
  4. data/app/assets/stylesheets/mumuki_laboratory/application/_modules.scss +1 -0
  5. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_activity.scss +12 -0
  6. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_discussion.scss +14 -2
  7. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_user_menu.scss +1 -1
  8. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_user_profile.scss +1 -0
  9. data/app/controllers/discussions_messages_controller.rb +6 -2
  10. data/app/controllers/users_controller.rb +13 -0
  11. data/app/helpers/discussions_helper.rb +5 -1
  12. data/app/helpers/user_activity_helper.rb +48 -0
  13. data/app/helpers/user_menu_helper.rb +4 -0
  14. data/app/views/discussions/_description_message.html.erb +1 -1
  15. data/app/views/discussions/_message.html.erb +1 -1
  16. data/app/views/discussions/_new_message.html.erb +13 -2
  17. data/app/views/discussions/new.html.erb +1 -1
  18. data/app/views/layouts/_user_menu.html.erb +2 -2
  19. data/app/views/users/_activity_indicator.html.erb +17 -0
  20. data/app/views/users/activity.html.erb +37 -0
  21. data/config/routes.rb +3 -0
  22. data/lib/mumuki/laboratory/extensions.rb +1 -0
  23. data/lib/mumuki/laboratory/extensions/date_and_time.rb +11 -0
  24. data/lib/mumuki/laboratory/locales/en.yml +13 -1
  25. data/lib/mumuki/laboratory/locales/es-CL.yml +18 -3
  26. data/lib/mumuki/laboratory/locales/es.yml +18 -3
  27. data/lib/mumuki/laboratory/locales/pt.yml +19 -1
  28. data/lib/mumuki/laboratory/version.rb +1 -1
  29. data/spec/controllers/discussions_messages_controller_spec.rb +20 -1
  30. data/spec/dummy/db/schema.rb +4 -1
  31. data/spec/features/discussion_flow_spec.rb +2 -0
  32. data/spec/features/user_activity_flow_spec.rb +65 -0
  33. data/spec/helpers/user_activity_helper_spec.rb +32 -0
  34. metadata +110 -102
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c79de66ab1c8248e5715cd1e54ac8e4b1e426fb26bc0a69b35539ba19eb954da
4
- data.tar.gz: 39cbfb28e86a6ae64f5a1164731d472ca65be3bec82d9f1ed6f159273512b078
3
+ metadata.gz: d72de447465b6716ee6b249aae76c6158aaa6ca02c87d58ea4e19fcf783ad85e
4
+ data.tar.gz: 387fef678b907e118266847df85eada3fb2aaea616162bb00e136776f2010629
5
5
  SHA512:
6
- metadata.gz: ed9430f79c8f92f7b02264aa84f7dc757a7ff05915fcdd17e93a5fe4b7aaac5cfd0d87fadec66ce0d4ac204cd270f08fafc1550a986bd367314f5e7130c360d4
7
- data.tar.gz: 8669d687ca7f70178cab77c25f698eef49a58eb74957ed274c73fe6fdf0c6f9139c5963f5c57b08a92ed874a97c6b648030c1be87cd34b107cb831db156e0113
6
+ metadata.gz: ae0f9022a999d502065a58c4fca2224c4ea3f21562c56d55489889793d70c7d561554bbd2eeb0f940295a7fc071adac35cf439219b228aa150799c62ed9f6a25
7
+ data.tar.gz: 5e40cd1dc2accffef46a0a6981d0ad588f031070c611d67d8c0811cdd6919a6d4733b8363b1bf6d02018c41f9d72945c4b6b497bc465ebe6621c00e17087d6c5
@@ -1,9 +1,13 @@
1
1
  mumuki.load(() => {
2
2
  var $subscriptionSpans = $('.discussion-subscription > span');
3
3
  var $upvoteSpans = $('.discussion-upvote > span');
4
+ let $messagePreviewButton = $('.discussion-new-message-preview-button.preview');
5
+ let $messageEditButton = $('.discussion-new-message-preview-button.edit');
6
+ let $newMessageContent = $('.discussion-new-message-content');
7
+ let $newMessagePreview = $('#discussion-new-message-preview');
4
8
 
5
9
  function createNewMessageEditor() {
6
- var $textarea = $("#new-discussion-message");
10
+ var $textarea = $("#discussion-new-message");
7
11
  var textarea = $textarea[0];
8
12
  if (!textarea) return;
9
13
 
@@ -26,7 +30,7 @@ mumuki.load(() => {
26
30
  }
27
31
 
28
32
  createReadOnlyEditors();
29
- createNewMessageEditor();
33
+ let editor = createNewMessageEditor();
30
34
 
31
35
  var Forum = {
32
36
  toggleButton: function (spans) {
@@ -67,9 +71,46 @@ mumuki.load(() => {
67
71
  const params = new URLSearchParams(location.search);
68
72
  elem.is(':checked') ? params.set(key, elem.val()) : params.delete(key);
69
73
  location.search = params.toString();
74
+ },
75
+ discussionMessagePreview: function (url) {
76
+ return Forum.tokenRequest({
77
+ url: url,
78
+ method: 'GET',
79
+ processData: false,
80
+ dataType: 'json',
81
+ data: new URLSearchParams({ content: editor.getValue() } ),
82
+ success: function (response) {
83
+ showPreview(response.preview);
84
+ },
85
+ error: function (e) {
86
+ error = $messagePreviewButton.attr('error-text');
87
+ showPreview(error);
88
+ },
89
+ xhrFields: {withCredentials: true}
90
+ });
91
+ },
92
+ hidePreviewAndShowEditor: function(elem) {
93
+ togglePreviewAndEditButtons();
94
+ togglePreviewAndContentMessage();
70
95
  }
71
96
  };
72
97
 
98
+ function showPreview(preview) {
99
+ $newMessagePreview.html($.parseHTML(preview));
100
+ togglePreviewAndEditButtons();
101
+ togglePreviewAndContentMessage();
102
+ }
103
+
104
+ function togglePreviewAndEditButtons() {
105
+ $messagePreviewButton.toggleClass('hidden');
106
+ $messageEditButton.toggleClass('hidden');
107
+ }
108
+
109
+ function togglePreviewAndContentMessage() {
110
+ $newMessagePreview.toggleClass('hidden');
111
+ $newMessageContent.toggleClass('hidden');
112
+ }
113
+
73
114
  mumuki.Forum = Forum;
74
115
 
75
116
  });
@@ -34,7 +34,7 @@ mumuki.load(() => {
34
34
  let onUserProfile = document.querySelector('.mu-profile-info') !== null;
35
35
 
36
36
  $userMenuHeader.click(() => {
37
- $('.mu-user-menu-items').toggleClass('hidden-sm-screen');
37
+ $('.mu-user-menu-items').toggleClass('mu-hidden-sm-screen');
38
38
  $('#mu-user-menu-header-icon').toggleClass('fa-chevron-up fa-chevron-down');
39
39
  });
40
40
 
@@ -1,3 +1,4 @@
1
+ @import "modules/activity";
1
2
  @import "modules/avatar";
2
3
  @import "modules/book_header";
3
4
  @import "modules/breadcrumb";
@@ -0,0 +1,12 @@
1
+ .mu-user-activity-indicator {
2
+ text-align: center;
3
+ border-radius: 10px;
4
+
5
+ &.jumbotron {
6
+ padding: 0.5em 0;
7
+ }
8
+ }
9
+
10
+ .mu-user-activity-selector {
11
+ padding-top: 15px;
12
+ }
@@ -287,9 +287,21 @@ summary.discussion-summary {
287
287
  }
288
288
  }
289
289
 
290
+ .discussion-new-message-buttons {
291
+ display: flex;
292
+ margin: 0 -10px;
293
+
294
+ .btn {
295
+ margin: 15px 10px;
296
+ }
297
+ }
298
+
299
+ .discussion-new-message-preview-button {
300
+ flex-grow: 0.2;
301
+ }
302
+
290
303
  .discussion-new-message-button {
291
- border-radius: 0;
292
- margin-top: 15px;
304
+ flex-grow: 1;
293
305
  }
294
306
 
295
307
  .discussion-message {
@@ -31,7 +31,7 @@
31
31
  .mu-user-menu-items {
32
32
  margin-top: 30px;
33
33
 
34
- &.hidden-sm-screen {
34
+ &.mu-hidden-sm-screen {
35
35
  @media only screen and (max-width: $screen-sm-max) {
36
36
  display: none;
37
37
  }
@@ -3,7 +3,7 @@ class DiscussionsMessagesController < AjaxController
3
3
 
4
4
  before_action :set_discussion!, only: [:create, :destroy]
5
5
  before_action :authorize_user!, only: [:destroy]
6
- before_action :authorize_moderator!, only: [:question, :approve]
6
+ before_action :authorize_moderator!, only: [:question, :approve, :preview]
7
7
 
8
8
  def create
9
9
  @discussion.submit_message! message_params, current_user
@@ -15,8 +15,12 @@ class DiscussionsMessagesController < AjaxController
15
15
  redirect_back(fallback_location: root_path)
16
16
  end
17
17
 
18
+ def preview
19
+ render json: { preview: Message.new(content: params[:content]).content_html }
20
+ end
21
+
18
22
  def approve
19
- current_message.toggle_approved!
23
+ current_message.toggle_approved! current_user
20
24
  head :ok
21
25
  end
22
26
 
@@ -30,6 +30,10 @@ class UsersController < ApplicationController
30
30
  @watched_discussions = current_user.watched_discussions_in_organization
31
31
  end
32
32
 
33
+ def activity
34
+ @activity = UserStats.stats_for(current_user).activity date_range_params
35
+ end
36
+
33
37
  def certificates
34
38
  @certificates ||= current_user.certificates_in_organization
35
39
  end
@@ -54,4 +58,13 @@ class UsersController < ApplicationController
54
58
  @user = current_user
55
59
  end
56
60
 
61
+ def date_range_params
62
+ @date_from = params[:date_from].try { |it| Date.parse it }
63
+ to = params[:date_to].try { |it| Date.parse it }
64
+ if @date_from && to
65
+ @date_from.beginning_of_day..(to - 1.day).end_of_day
66
+ else
67
+ nil
68
+ end
69
+ end
57
70
  end
@@ -12,7 +12,7 @@ module DiscussionsHelper
12
12
  end
13
13
 
14
14
  def user_discussions_link
15
- discussions_link user_discussions_icon(t(:my_doubts)), user_path(anchor: 'discussions') if current_user.watched_discussions.present?
15
+ discussions_link(user_discussions_icon(t(:my_doubts)), discussions_user_path) if current_user.watched_discussions.present?
16
16
  end
17
17
 
18
18
  def others_discussions_icon(text)
@@ -195,4 +195,8 @@ module DiscussionsHelper
195
195
  def should_show_approved_for?(user, message)
196
196
  !user&.moderator_here? && message.approved? && !message.from_moderator?
197
197
  end
198
+
199
+ def discussion_user_name(user)
200
+ user.name
201
+ end
198
202
  end
@@ -0,0 +1,48 @@
1
+ module UserActivityHelper
2
+ def activity_selector_week_range_for(organization = Organization.current)
3
+ start = organization.activity_start_date min_week
4
+ (start.prev_occurring(:monday) + 1..Date.today)
5
+ .step(7)
6
+ .to_a
7
+ .reverse
8
+ .map { |it| [it, it + 7.days] }
9
+ end
10
+
11
+ def mark_period_if_active(period_start)
12
+ active_period?(period_start) && 'class=active'
13
+ end
14
+
15
+ def solved_exercises_percentage
16
+ percentage = @activity[:exercises][:solved_count].to_f / @activity[:exercises][:count] * 100
17
+ "#{percentage.ceil}%"
18
+ end
19
+
20
+ def exercises_activity_stats
21
+ solved_count = {
22
+ name: t(:solved_exercises_count, count: @activity[:exercises][:solved_count]),
23
+ value: @activity[:exercises][:solved_count] }
24
+ solved_percentage = {
25
+ name: t(:solved_exercises_percentage),
26
+ value: solved_exercises_percentage }
27
+
28
+ @date_from ? [solved_count] : [solved_count, solved_percentage]
29
+ end
30
+
31
+ def messages_activity_stats
32
+ count = @activity[:messages][:count]
33
+ approved = @activity[:messages][:approved]
34
+
35
+ [{name: t(:messages_pluralized, count: count), value: count},
36
+ {name: t(:approved_messages, count: approved), value: approved}]
37
+ end
38
+
39
+ private
40
+
41
+ def active_period?(period_start)
42
+ period_start ? @date_from == period_start : !@date_from
43
+ end
44
+
45
+ def min_week
46
+ 8.week.ago.to_date
47
+ end
48
+ end
@@ -19,6 +19,10 @@ module UserMenuHelper
19
19
  user_menu_item t(:discussions), discussions_user_path, 'discussions' if current_user&.can_discuss_here?
20
20
  end
21
21
 
22
+ def activity_user_menu_link
23
+ user_menu_item t(:activity), activity_user_path, 'activity'
24
+ end
25
+
22
26
  def certificates_user_menu_link
23
27
  user_menu_item t(:certificates), certificates_user_path, 'certificates'
24
28
  end
@@ -2,7 +2,7 @@
2
2
  <div class="discussion-message-bubble">
3
3
  <div class="discussion-message-bubble-header">
4
4
  <div class="discussion-message-bubble-title">
5
- <%= discussion.initiator.name %>
5
+ <%= discussion_user_name(discussion.initiator) %>
6
6
  <span class="message-date">
7
7
  <%= t(:time_since, time: time_ago_in_words(discussion.created_at)) %>
8
8
  </span>
@@ -2,7 +2,7 @@
2
2
  <div class="discussion-message-bubble">
3
3
  <div class="discussion-message-bubble-header">
4
4
  <div class="discussion-message-bubble-title">
5
- <%= user.name %>
5
+ <%= discussion_user_name user %>
6
6
  <% if user.moderator_here? %>
7
7
  <span class="moderator-badge"><%= t(:moderation) %></span>
8
8
  <% end %>
@@ -10,12 +10,23 @@
10
10
  <div class="container-fluid">
11
11
  <div class="row">
12
12
  <div class="discussion-new-message-content">
13
- <%= f.editor :content, '', { id: 'new-discussion-message', class: 'form-control', placeholder: t(:message) } %>
13
+ <%= f.editor :content, '', { id: 'discussion-new-message', class: 'form-control', placeholder: t(:message) } %>
14
14
  </div>
15
+ <div class="discussion-message-content hidden" id="discussion-new-message-preview"></div>
15
16
  </div>
16
17
  </div>
17
18
  </div>
18
19
  </div>
19
- <button class="btn btn-success btn-block discussion-new-message-button"> <%= t :comment %> </button>
20
+ <div class="discussion-new-message-buttons">
21
+ <% if user.moderator_here? %>
22
+ <button class="btn btn-default discussion-new-message-preview-button preview" type="button" error-text="<%= t :preview_error %>"
23
+ onclick="mumuki.Forum.discussionMessagePreview('<%= preview_discussion_message_url %>')"> <%= fa_icon('eye', text: t(:preview)) %> </button>
24
+ <button class="btn btn-default discussion-new-message-preview-button edit hidden" type="button"
25
+ onclick="mumuki.Forum.hidePreviewAndShowEditor()"> <%= fa_icon('pencil-alt', text: t(:edit_message)) %> </button>
26
+ <% end %>
27
+ <%= button_tag type: 'submit', class: 'btn btn-success discussion-new-message-button', data: { disable: true } do %>
28
+ <%= fa_icon('comment', text: t(:comment)) %>
29
+ <% end %>
30
+ </div>
20
31
  <% end %>
21
32
  <% end %>
@@ -22,7 +22,7 @@
22
22
  <div class="container-fluid">
23
23
  <div class="row">
24
24
  <div class="discussion-new-message-content">
25
- <%= f.editor :description, '', {id: 'new-discussion-message', class: 'form-control', placeholder: t(:discussion_description_placeholder)} %>
25
+ <%= f.editor :description, '', {id: 'discussion-new-message', class: 'form-control', placeholder: t(:discussion_description_placeholder)} %>
26
26
  </div>
27
27
  </div>
28
28
  </div>
@@ -2,13 +2,13 @@
2
2
  <div class="mu-user-menu">
3
3
  <div class="mu-user-menu-content">
4
4
  <%= user_menu_header %>
5
- <div class="col-xs-12 mu-user-menu-items hidden-sm-screen">
5
+ <div class="col-xs-12 mu-user-menu-items mu-hidden-sm-screen">
6
6
  <%= profile_user_menu_link %>
7
7
  <%= user_menu_divider %>
8
8
  <%= messages_user_menu_link %>
9
9
  <%= discussions_user_menu_link %>
10
10
  <%= user_menu_divider %>
11
- <%= certificates_user_menu_link %>
11
+ <%= activity_user_menu_link %>
12
12
  </div>
13
13
  </div>
14
14
  <div class="mu-user-menu-divider vertical hidden-sm hidden-xs"></div>
@@ -0,0 +1,17 @@
1
+ <div class="row">
2
+ <div class="col-md-12">
3
+ <h3><%= title %></h3>
4
+ </div>
5
+ </div>
6
+ <div class="row">
7
+ <% stats.each do |s| %>
8
+ <div class="col-md-6">
9
+ <div class="jumbotron mu-user-activity-indicator">
10
+ <h1>
11
+ <%= s[:value] %>
12
+ <p><%= s[:name].downcase %></p>
13
+ </h1>
14
+ </div>
15
+ </div>
16
+ <% end %>
17
+ </div>
@@ -0,0 +1,37 @@
1
+ <%= content_for :breadcrumbs do %>
2
+ <%= breadcrumbs_for_my_account %>
3
+ <% end %>
4
+
5
+ <%= render partial: 'layouts/user_menu' %>
6
+
7
+ <div class="col-md-9 mu-tab-body">
8
+ <div class="mu-user-header">
9
+ <h1><%= t(:activity) %></h1>
10
+ </div>
11
+ <div class="col-md-8">
12
+ <%= render partial: 'activity_indicator',
13
+ locals: {
14
+ title: t(:exercises),
15
+ stats: exercises_activity_stats
16
+ } %>
17
+
18
+ <%= render partial: 'activity_indicator',
19
+ locals: {
20
+ title: t(:forum),
21
+ stats: messages_activity_stats
22
+ } %>
23
+ </div>
24
+
25
+ <div class="col-md-4">
26
+ <ul class="nav nav-pills nav-stacked mu-user-activity-selector">
27
+ <li <%= mark_period_if_active nil %>>
28
+ <%= link_to t(:total), activity_user_path %>
29
+ </li>
30
+ <% activity_selector_week_range_for.each do |(week_start, week_end)| %>
31
+ <li <%= mark_period_if_active week_start %>>
32
+ <%= link_to t(:week_of, date: l(week_start)), activity_user_path(date_from: week_start, date_to: week_end) %>
33
+ </li>
34
+ <% end %>
35
+ </ul>
36
+ </div>
37
+ </div>
data/config/routes.rb CHANGED
@@ -21,6 +21,7 @@ Rails.application.routes.draw do
21
21
  post :question, on: :member
22
22
  end
23
23
  end
24
+ get '/discussions/messages/preview', to: 'discussions_messages#preview', as: :preview_discussion_message
24
25
 
25
26
  resources :exam_registrations, only: [:show]
26
27
  resources :exam_authorization_requests, only: [:show, :create, :update]
@@ -65,7 +66,9 @@ Rails.application.routes.draw do
65
66
 
66
67
  get :messages
67
68
  get :discussions
69
+ get :activity
68
70
  get :certificates
71
+
69
72
  end
70
73
 
71
74
  resources :faqs, only: [:index]
@@ -1 +1,2 @@
1
+ require_relative './extensions/date_and_time'
1
2
  require_relative './extensions/request'
@@ -0,0 +1,11 @@
1
+ module DateAndTime
2
+ module Calculations
3
+ # Polyfill, already implemented on Rails 5.2
4
+ # https://api.rubyonrails.org/classes/DateAndTime/Calculations.html#method-i-prev_occurring
5
+ def prev_occurring(day_of_week)
6
+ ago = wday - DAYS_INTO_WEEK.fetch(day_of_week)
7
+ ago += 7 unless ago > 0
8
+ advance(days: -ago)
9
+ end
10
+ end
11
+ end
@@ -14,6 +14,8 @@ en:
14
14
  appendix: Appendix
15
15
  appendix_teaser: Do you want to learn more? <a href="%{link}">Check this chapter's appendix</a>"
16
16
  approved_message: Validated by mentor
17
+ approved_messages:
18
+ other: validated
17
19
  are_you_sure: Are you sure you want to %{action}?
18
20
  ask_a_question: Ask a question!
19
21
  ask_community: Ask community for help
@@ -77,6 +79,7 @@ en:
77
79
  dont_leave_us: Don't leave us! Learning is fun. You just have to keep at it.
78
80
  download: Download your solution
79
81
  edit: Edit
82
+ edit_message: Edit message
80
83
  edit_profile: Edit profile
81
84
  editor_placeholder: "write your solution here..."
82
85
  email: Email
@@ -176,6 +179,9 @@ en:
176
179
  messages: Messages
177
180
  messages_error: Previous messages are unavailable. Please try again later.
178
181
  moderation: Mentoring
182
+ messages_pluralized:
183
+ one: Message
184
+ other: Messages
179
185
  moderator: Mentor
180
186
  more_messages: More
181
187
  my_account: My account
@@ -224,6 +230,8 @@ en:
224
230
  permissions: Permissions
225
231
  please_fill_profile_data: Please complete your profile data to continue!
226
232
  please_validate: 'Please validate your data before continue:'
233
+ preview: Preview
234
+ preview_error: The preview cannot be shown. Check your internet connection or try with a shorter message.
227
235
  previous_exercise: Previous
228
236
  problem_with_exercise: '[Mumuki] Problem with exercise: %{title}'
229
237
  processing_your_solution: We are processing you solution
@@ -256,11 +264,13 @@ en:
256
264
  skipped_solve_anyway: Solve anyway
257
265
  solution: Solution
258
266
  solved: Solved
259
- solved_count: '%{count} solved'
260
267
  solve_doubts: Solve other's doubts
261
268
  solve_more_exercises_to_level_up: Solve <span>number</span> more exercises to advance to the next level.
262
269
  solve_your_doubts: Solve your doubts
263
270
  solve_your_doubts_teaser: Do you have any doubts?
271
+ solved_count: '%{count} solved'
272
+ solved_exercises_count: solved
273
+ solved_exercises_percentage: done
264
274
  something_went_wrong: Something went wrong!
265
275
  sort: Sort
266
276
  sources: Sources
@@ -293,6 +303,7 @@ en:
293
303
  to_pending_review: Mark as solved
294
304
  to_solved: Mark as solved
295
305
  unauthorized_explanation: You have no permissions for this content. Maybe you logged in with another account.
306
+ total: Total
296
307
  undo_upvote: Undo upvote
297
308
  unlocked_medal_as_avatar: You earned this medal! You can now choose it as an avatar.
298
309
  unspecified: I'd rather not say
@@ -310,6 +321,7 @@ en:
310
321
  view_details: View details
311
322
  want_permissions: The next user requires permissions
312
323
  we_miss_you: We miss you!
324
+ week_of: Week of %{date}
313
325
  welcome: Welcome to %{name}!
314
326
  working: "Working"
315
327
  wrong_answer: The answer is wrong
@@ -13,6 +13,9 @@ es-CL:
13
13
  appendix_teaser: ¿Quieres saber más? <a href="%{link}">Consulta el apéndice de este capítulo</a>
14
14
  are_you_sure: '¿Estás seguro que quieres %{action}?'
15
15
  ask_a_question: ¡Haz una pregunta!
16
+ approved_messages:
17
+ one: validado
18
+ other: validados
16
19
  ask_community: Pregunta a la comunidad
17
20
  ask_redirect: ¿Quieres que te llevemos ahí?
18
21
  ask_the_first_question: ¡Haz la primera pregunta!
@@ -77,6 +80,7 @@ es-CL:
77
80
  dont_leave_us: ¡No nos abandones! Aprender a programar es divertido. Sólo tienes que seguir practicando.
78
81
  download: "Descarga lo que hiciste"
79
82
  edit: Editar
83
+ edit_message: Editar mensaje
80
84
  editor_placeholder: "...escribe tu solución acá..."
81
85
  email: Email
82
86
  error_description: Esto es lo que se conoce como <span class="error-link">%{error}</span>.
@@ -174,6 +178,9 @@ es-CL:
174
178
  message: Mensaje
175
179
  messages: Mensajes
176
180
  messages_error: Los mensajes anteriores no están disponibles en este momento. ¡Vuelve a intentar más tarde!
181
+ messages_pluralized:
182
+ one: Mensaje
183
+ other: Mensajes
177
184
  minute: minuto
178
185
  minutes: minutos
179
186
  moderation: Mentoría
@@ -230,6 +237,8 @@ es-CL:
230
237
  permissions: Permisos
231
238
  please_fill_profile_data: ¡Completa tus datos personales para continuar!
232
239
  please_validate: 'Estás a punto de ingresar al curso. Para poder ofrecerte una mejor experiencia, por favor valida que tus datos a continuación sean reales y correctos.'
240
+ preview: Vista previa
241
+ preview_error: No se puede mostrar la vista previa. Revisa tu conexión a internet o prueba con un mensaje más corto.
233
242
  previous_exercise: Anterior
234
243
  problem_with_exercise: '[Mumuki] Error con el ejercicio: %{title}'
235
244
  processing_your_solution: Estamos procesando tu solución
@@ -260,15 +269,19 @@ es-CL:
260
269
  skipped_solve_anyway: Resolver de todos modos
261
270
  solution: Solución
262
271
  solved: Resuelta
263
- solved_count:
264
- one: 1 resuelta
265
- other: '%{count} resueltas'
266
272
  solved_exercises: Ejercicios Resueltos
267
273
  solve_doubts: Resuelve consultas
268
274
  solve_more_exercises_to_level_up: Resuelve <span>number</span> ejercicios más para pasar al siguiente nivel.
269
275
  solve_your_doubts: Consulta tus dudas
270
276
  solve_your_doubts_teaser: ¿Tienes alguna consulta?
271
277
  something_went_wrong: ¡Ups!, algo no anduvo bien...
278
+ solved_count:
279
+ one: 1 resuelta
280
+ other: '%{count} resueltas'
281
+ solved_exercises_count:
282
+ one: resuelto
283
+ other: resueltos
284
+ solved_exercises_percentage: realizado
272
285
  sort: Ordenar
273
286
  sources: Bibliografía
274
287
  start_lesson: ¡Comienza esta lección!
@@ -300,6 +313,7 @@ es-CL:
300
313
  to_pending_review: Resolver
301
314
  to_solved: Resolver
302
315
  unauthorized_explanation: ¡Ups! Esto es lo que se conoce como %{error}, es decir que no iniciaste sesión.
316
+ total: Total
303
317
  uncategorized: No categorizado
304
318
  undo_upvote: No es útil
305
319
  unlocked_medal_as_avatar: ¡Obtuviste esta medalla! Ya puedes elegirla como avatar.
@@ -318,6 +332,7 @@ es-CL:
318
332
  view_details: Ver detalles
319
333
  want_permissions: El siguiente usuario requiere permisos
320
334
  we_miss_you: ¡Te extrañamos!
335
+ week_of: Semana del %{date}
321
336
  will_paginate:
322
337
  previous_label: "&#8592; Anterior"
323
338
  next_label: "Siguiente &#8594;"
@@ -17,6 +17,9 @@ es:
17
17
  approved_message: Validado por mentor
18
18
  are_you_sure: '¿Estás seguro que querés %{action}?'
19
19
  ask_a_question: ¡Hacé una pregunta!
20
+ approved_messages:
21
+ one: validado
22
+ other: validados
20
23
  ask_community: Preguntá a la comunidad
21
24
  ask_redirect: ¿Querés que te llevemos ahí?
22
25
  ask_the_first_question: ¡Hacé la primera pregunta!
@@ -84,6 +87,7 @@ es:
84
87
  dont_leave_us: ¡No nos abandones! Aprender a programar es divertido. Sólo tenés que seguir practicando.
85
88
  download: "Descargá lo que hiciste"
86
89
  edit: Editar
90
+ edit_message: Editar mensaje
87
91
  edit_profile: Editar perfil
88
92
  editor_placeholder: "...escribí tu solución acá..."
89
93
  email: Email
@@ -185,6 +189,9 @@ es:
185
189
  message: Mensaje
186
190
  messages: Mensajes
187
191
  messages_error: Los mensajes anteriores no están disponibles en este momento. ¡Volvé a intentar mas tarde!
192
+ messages_pluralized:
193
+ one: Mensaje
194
+ other: Mensajes
188
195
  minute: minuto
189
196
  minutes: minutos
190
197
  moderation: Mentoría
@@ -241,6 +248,8 @@ es:
241
248
  permissions: Permisos
242
249
  please_fill_profile_data: ¡Completá tus datos personales para continuar!
243
250
  please_validate: 'Estás a punto de ingresar al curso. Para poder ofrecerte una mejor experiencia, por favor validá que tus datos a continuación sean reales y correctos.'
251
+ preview: Vista previa
252
+ preview_error: No se puede mostrar la vista previa. Revisá tu conexión a internet o probá con un mensaje más corto.
244
253
  previous_exercise: Anterior
245
254
  problem_with_exercise: '[Mumuki] Error con el ejercicio: %{title}'
246
255
  processing_your_solution: Estamos procesando tu solución
@@ -275,15 +284,19 @@ es:
275
284
  skipped_solve_anyway: Resolver de todos modos
276
285
  solution: Solución
277
286
  solved: Resuelta
278
- solved_count:
279
- one: 1 resuelta
280
- other: '%{count} resueltas'
281
287
  solved_exercises: Ejercicios Resueltos
282
288
  solve_doubts: Resolvé consultas
283
289
  solve_more_exercises_to_level_up: Resolvé <span>number</span> ejercicios más para pasar al siguiente nivel.
284
290
  solve_your_doubts: Consultá tus dudas
285
291
  solve_your_doubts_teaser: ¿Tenés alguna consulta?
286
292
  something_went_wrong: ¡Ups!, algo no anduvo bien...
293
+ solved_count:
294
+ one: 1 resuelta
295
+ other: '%{count} resueltas'
296
+ solved_exercises_count:
297
+ one: resuelto
298
+ other: resueltos
299
+ solved_exercises_percentage: realizado
287
300
  sort: Ordenar
288
301
  sources: Bibliografía
289
302
  start_lesson: ¡Comenzá esta lección!
@@ -316,6 +329,7 @@ es:
316
329
  to_pending_review: Resolver
317
330
  to_solved: Resolver
318
331
  unauthorized_explanation: ¡Ups! Esto es lo que se conoce como %{error}, es decir que no iniciaste sesión.
332
+ total: Total
319
333
  uncategorized: No categorizado
320
334
  undo_upvote: No es útil
321
335
  unlocked_medal_as_avatar: ¡Obtuviste esta medalla! Ya podés elegirla como avatar.
@@ -335,6 +349,7 @@ es:
335
349
  want_permissions: El siguiente usuario requiere permisos
336
350
  we_miss_you: ¡Te extrañamos!
337
351
  welcome: ¡Te damos la bienvenida a %{name}!
352
+ week_of: Semana del %{date}
338
353
  will_paginate:
339
354
  previous_label: "&#8592; Anterior"
340
355
  next_label: "Siguiente &#8594;"
@@ -16,6 +16,9 @@ pt:
16
16
  appendix_teaser: Você quer saber mais? <a href="%{link}"> Consulte o apêndice deste capítulo </a>
17
17
  approved_message: Validado pelo mentor
18
18
  are_you_sure: 'Tem certeza de que deseja %{action}?'
19
+ approved_messages:
20
+ one: validado
21
+ other: validados
19
22
  ask_a_question: Faça uma pergunta!
20
23
  ask_community: Pergunte à comunidade
21
24
  ask_redirect: Você quer que nós o levemos para lá?
@@ -80,6 +83,7 @@ pt:
80
83
  discussions_will_be_here: As perguntas que você fizer no espaço de consulta aparecerão aqui.
81
84
  download: Faça o download do que você fez
82
85
  edit: Editar
86
+ edit_message: Editar mensagem
83
87
  edit_profile: Editar perfil
84
88
  editor_placeholder: ... Escreva sua solução aqui ...
85
89
  email: E-mail
@@ -179,6 +183,10 @@ pt:
179
183
  message: Mensagem
180
184
  messages: Mensagens
181
185
  messages_error: As mensagens acima não estão disponíveis no momento. Eu tentei novamente mais tarde!
186
+ mais tarde!
187
+ messages_pluralized:
188
+ one: Mensagem
189
+ other: Mensagens
182
190
  minute: minuto
183
191
  minutes: minutos
184
192
  moderation: Mentoria
@@ -232,6 +240,8 @@ pt:
232
240
  permissions: Permissões
233
241
  please_fill_profile_data: Preencha suas informações pessoais para continuar!
234
242
  please_validate: Você está prestes a entrar no curso. Para oferecer uma experiência melhor, valide que seus dados abaixo sejam reais e corretos.
243
+ preview: Vista prévia
244
+ 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
245
  previous_exercise: Anterior
236
246
  problem_with_exercise: '[Mumuki] Erro com exercício %{title}'
237
247
  processing_your_solution: Estamos processando sua solução
@@ -264,12 +274,18 @@ pt:
264
274
  skipped_solve_anyway: Resolver mesmo assim
265
275
  solution: Solução
266
276
  solved: Resolvido
267
- solved_count: '%{count} resolvido'
268
277
  solved_exercises: Exercícios resolvidos
278
+ solved_count:
279
+ one: 1 resolvido
280
+ other: '%{count} resolvidos'
269
281
  solve_doubts: Resolvi dúvidas
270
282
  solve_more_exercises_to_level_up: Resolva mais <span>number</span> exercícios para avançar para o próximo nível.
271
283
  solve_your_doubts: Consulte suas dúvidas
272
284
  solve_your_doubts_teaser: Você tem alguma dúvida?
285
+ solved_exercises_count:
286
+ one: resolvido
287
+ other: resolvidos
288
+ solved_exercises_percentage: realizado
273
289
  something_went_wrong: Oops!, Algo não estava certo ...
274
290
  sort: Ordenar
275
291
  sources: Bibliografia
@@ -301,6 +317,7 @@ pt:
301
317
  to_pending_review: Marcar como resolvida
302
318
  to_solved: Marcar como resolvida
303
319
  unauthorized_explanation: Opa! Isso é o que é conhecido como %{error}, ou seja, você não fez logon.
320
+ total: Total
304
321
  uncategorized: Não classificado
305
322
  unlocked_medal_as_avatar: Você ganhou essa medalha! Agora você pode escolhê-la como avatar.
306
323
  unspecified: Eu preferiria não dizer
@@ -313,6 +330,7 @@ pt:
313
330
  username: Nome de usuário
314
331
  view_details: Ver detalhes
315
332
  want_permissions: O próximo usuário requer permissões
333
+ week_of: Semana de %{date}
316
334
  welcome: Convidamos você a {name}!
317
335
  working: Processamento
318
336
  wrong_answer: A resposta não é correta
@@ -1,5 +1,5 @@
1
1
  module Mumuki
2
2
  module Laboratory
3
- VERSION = '9.0.4'
3
+ VERSION = '9.0.5'
4
4
  end
5
5
  end
@@ -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
 
@@ -69,5 +69,24 @@ describe DiscussionsMessagesController, organization_workspace: :test do
69
69
  it { expect(response.status).to eq 200 }
70
70
  it { expect(message.reload.not_actually_a_question).to be true }
71
71
  end
72
+
73
+ describe 'preview' do
74
+ let(:message) { create(:message, content: 'Message in **bold** and _italics_', discussion: discussion, sender: student.uid) }
75
+
76
+ describe 'for student' do
77
+ before { set_current_user! student }
78
+ before { get :preview, params: {content: message.content} }
79
+
80
+ it { expect(response.status).to eq 403 }
81
+ end
82
+
83
+ describe 'for moderator' do
84
+ before { set_current_user! moderator }
85
+ before { get :preview, params: {content: message.content} }
86
+
87
+ it { expect(response.status).to eq 200 }
88
+ it { expect(JSON.parse(response.body)['preview']).to eq "<p>Message in <strong>bold</strong> and <em>italics</em></p>\n" }
89
+ end
90
+ end
72
91
  end
73
92
  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: 20210308145910) do
14
14
 
15
15
  # These are extensions that must be enabled in order to support this database
16
16
  enable_extension "plpgsql"
@@ -368,6 +368,9 @@ ActiveRecord::Schema.define(version: 20210302181654) do
368
368
  t.integer "discussion_id"
369
369
  t.boolean "approved", default: false
370
370
  t.boolean "not_actually_a_question", default: false
371
+ t.datetime "approved_at"
372
+ t.bigint "approved_by_id"
373
+ t.index ["approved_by_id"], name: "index_messages_on_approved_by_id"
371
374
  end
372
375
 
373
376
  create_table "notifications", force: :cascade do |t|
@@ -169,6 +169,7 @@ feature 'Discussion Flow', organization_workspace: :test do
169
169
  expect(page).to have_text(problem_2.name)
170
170
  expect(page).to have_text('Open')
171
171
  expect(page).to have_text('Messages')
172
+ expect(page).not_to have_text('Preview')
172
173
  expect(page).not_to have_xpath("//div[@class='discussion-actions']")
173
174
  end
174
175
 
@@ -180,6 +181,7 @@ feature 'Discussion Flow', organization_workspace: :test do
180
181
  expect(page).to have_text(problem_2.name)
181
182
  expect(page).to have_text('Open')
182
183
  expect(page).to have_text('Messages')
184
+ expect(page).to have_text('Preview')
183
185
  expect(page).to have_xpath("//div[@class='discussion-actions']")
184
186
  end
185
187
  end
@@ -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
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe UserActivityHelper, organization_workspace: :test do
4
+ helper UserActivityHelper
5
+
6
+ let(:organization) { Organization.current }
7
+
8
+ before do
9
+ # Set today date to Wednesday to test week always starts on Monday
10
+ allow(Date).to receive(:today).and_return(Date.new(2021, 2, 10))
11
+ allow_any_instance_of(UserActivityHelper).to receive(:min_week).and_return(8.weeks.ago(Date.today))
12
+ end
13
+
14
+ describe 'activity_selector_week_range_for' do
15
+ let(:range) { activity_selector_week_range_for organization }
16
+ let(:closest_monday) { Date.new(2021, 2, 8) }
17
+
18
+ context 'organization without in preparation until' do
19
+ it { expect(range.length).to eq 9 }
20
+ it { expect(range.first).to eq [closest_monday, 1.week.since(closest_monday).to_date] }
21
+ it { expect(range.last).to eq [8.week.ago(closest_monday).to_date, 7.week.ago(closest_monday).to_date] }
22
+ end
23
+
24
+ context 'organization with in preparation until' do
25
+ before { organization.update! in_preparation_until: 3.week.ago(Date.today) }
26
+
27
+ it { expect(range.length).to eq 4 }
28
+ it { expect(range.first).to eq [closest_monday, 1.week.since(closest_monday).to_date] }
29
+ it { expect(range.last).to eq [3.week.ago(closest_monday).to_date, 2.week.ago(closest_monday).to_date] }
30
+ end
31
+ end
32
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mumuki-laboratory
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.0.4
4
+ version: 9.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Franco Bulgarelli
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-11 00:00:00.000000000 Z
11
+ date: 2021-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 9.0.2
33
+ version: 9.0.5
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 9.0.2
40
+ version: 9.0.5
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: mumukit-bridge
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -456,6 +456,7 @@ files:
456
456
  - app/assets/stylesheets/mumuki_laboratory/application/_vendor.scss
457
457
  - app/assets/stylesheets/mumuki_laboratory/application/codemirror-themes/_mu-light.scss
458
458
  - app/assets/stylesheets/mumuki_laboratory/application/hovers.scss
459
+ - app/assets/stylesheets/mumuki_laboratory/application/modules/_activity.scss
459
460
  - app/assets/stylesheets/mumuki_laboratory/application/modules/_avatar.scss
460
461
  - app/assets/stylesheets/mumuki_laboratory/application/modules/_book_header.scss
461
462
  - app/assets/stylesheets/mumuki_laboratory/application/modules/_breadcrumb.scss
@@ -571,6 +572,7 @@ files:
571
572
  - app/helpers/progress_bar_helper.rb
572
573
  - app/helpers/progress_helper.rb
573
574
  - app/helpers/runner_assets_helper.rb
575
+ - app/helpers/user_activity_helper.rb
574
576
  - app/helpers/user_menu_helper.rb
575
577
  - app/mailers/application_mailer.rb
576
578
  - app/mailers/user_mailer.rb
@@ -702,11 +704,13 @@ files:
702
704
  - app/views/user_mailer/certificate.text.erb
703
705
  - app/views/user_mailer/no_submissions_reminder.html.erb
704
706
  - app/views/user_mailer/no_submissions_reminder.text.erb
707
+ - app/views/users/_activity_indicator.html.erb
705
708
  - app/views/users/_avatar_list.html.erb
706
709
  - app/views/users/_edit_user_form.html.erb
707
710
  - app/views/users/_profile_fields.html.erb
708
711
  - app/views/users/_term.html.erb
709
712
  - app/views/users/_user_form.html.erb
713
+ - app/views/users/activity.html.erb
710
714
  - app/views/users/certificates.html.erb
711
715
  - app/views/users/discussions.html.erb
712
716
  - app/views/users/edit.html.erb
@@ -736,6 +740,7 @@ files:
736
740
  - lib/mumuki/laboratory/engine.rb
737
741
  - lib/mumuki/laboratory/events/events.rb
738
742
  - lib/mumuki/laboratory/extensions.rb
743
+ - lib/mumuki/laboratory/extensions/date_and_time.rb
739
744
  - lib/mumuki/laboratory/extensions/request.rb
740
745
  - lib/mumuki/laboratory/locales/datetime.es.yml
741
746
  - lib/mumuki/laboratory/locales/en.yml
@@ -849,6 +854,7 @@ files:
849
854
  - spec/features/standard_flow_spec.rb
850
855
  - spec/features/terms_flow_spec.rb
851
856
  - spec/features/topic_flow_spec.rb
857
+ - spec/features/user_activity_flow_spec.rb
852
858
  - spec/helpers/application_helper_spec.rb
853
859
  - spec/helpers/authors_helper_spec.rb
854
860
  - spec/helpers/avatar_helper_spec.rb
@@ -859,6 +865,7 @@ files:
859
865
  - spec/helpers/icons_helper_spec.rb
860
866
  - spec/helpers/page_title_helper_spec.rb
861
867
  - spec/helpers/test_results_rendering_spec.rb
868
+ - spec/helpers/user_activity_helper_spec.rb
862
869
  - spec/helpers/with_choices_spec.rb
863
870
  - spec/helpers/with_navigation_spec.rb
864
871
  - spec/javascripts/bridge-spec.js
@@ -943,138 +950,139 @@ required_rubygems_version: !ruby/object:Gem::Requirement
943
950
  - !ruby/object:Gem::Version
944
951
  version: '0'
945
952
  requirements: []
946
- rubyforge_project:
947
- rubygems_version: 2.7.6
953
+ rubygems_version: 3.1.2
948
954
  signing_key:
949
955
  specification_version: 4
950
956
  summary: Code assement web application for the Mumuki Platform.
951
957
  test_files:
952
- - spec/controllers/invitations_controller_spec.rb
953
- - spec/controllers/discussions_controller_spec.rb
954
- - spec/controllers/api_clients_controller.rb
955
- - spec/controllers/guide_progress_controller_spec.rb
956
- - spec/controllers/exercise_solutions_controller_spec.rb
957
- - spec/controllers/courses_api_controller_spec.rb
958
- - spec/controllers/exam_registrations_controller_spec.rb
959
- - spec/controllers/students_api_controller_spec.rb
960
- - spec/controllers/messages_controller_spec.rb
961
- - spec/controllers/exam_authorization_requests_controller_spec.rb
962
- - spec/controllers/confirmations_controller_spec.rb
963
- - spec/controllers/discussions_messages_controller_spec.rb
964
- - spec/controllers/users_api_controller_spec.rb
965
- - spec/controllers/chapters_controller_spec.rb
966
- - spec/controllers/certificates_controller_spec.rb
967
- - spec/controllers/organizations_api_controller_spec.rb
968
- - spec/controllers/users_controller_spec.rb
969
- - spec/evaluation_helper.rb
970
- - spec/capybara_helper.rb
971
- - spec/login_helper.rb
972
- - spec/mailers/previews/user_mailer_preview.rb
973
- - spec/mailers/user_mailer_spec.rb
974
- - spec/spec_helper.rb
958
+ - spec/dummy/config/cable.yml
959
+ - spec/dummy/config/application.rb
960
+ - spec/dummy/config/spring.rb
961
+ - spec/dummy/config/database.yml
962
+ - spec/dummy/config/environment.rb
963
+ - spec/dummy/config/rabbit.yml
964
+ - spec/dummy/config/puma.rb
965
+ - spec/dummy/config/locales/en.yml
966
+ - spec/dummy/config/secrets.yml
967
+ - spec/dummy/config/environments/development.rb
968
+ - spec/dummy/config/environments/test.rb
969
+ - spec/dummy/config/boot.rb
970
+ - spec/dummy/config/initializers/cookies_serializer.rb
971
+ - spec/dummy/config/initializers/wrap_parameters.rb
972
+ - spec/dummy/config/initializers/filter_parameter_logging.rb
973
+ - spec/dummy/config/initializers/assets.rb
974
+ - spec/dummy/config/routes.rb
975
975
  - spec/dummy/package.json
976
+ - spec/dummy/Rakefile
977
+ - spec/dummy/config.ru
978
+ - spec/dummy/bin/rails
979
+ - spec/dummy/bin/yarn
980
+ - spec/dummy/bin/rake
976
981
  - spec/dummy/bin/bundle
977
982
  - spec/dummy/bin/update
978
983
  - spec/dummy/bin/setup
979
- - spec/dummy/bin/rake
980
- - spec/dummy/bin/rails
981
- - spec/dummy/bin/yarn
982
- - spec/dummy/public/character/kibi/jump.svg
983
- - spec/dummy/public/character/kibi/context.svg
984
- - spec/dummy/public/character/kibi/success_l.svg
984
+ - spec/dummy/public/character/animations.json
985
985
  - spec/dummy/public/character/kibi/failure.svg
986
- - spec/dummy/public/character/kibi/success2_l.svg
986
+ - spec/dummy/public/character/kibi/success_l.svg
987
987
  - spec/dummy/public/character/kibi/passed_with_warnings.svg
988
+ - spec/dummy/public/character/kibi/success2_l.svg
989
+ - spec/dummy/public/character/kibi/jump.svg
990
+ - spec/dummy/public/character/kibi/context.svg
988
991
  - spec/dummy/public/character/magnifying_glass/apparition.svg
989
992
  - spec/dummy/public/character/magnifying_glass/loop.svg
990
- - spec/dummy/public/character/animations.json
991
- - spec/dummy/public/medal/outline.svg
992
- - spec/dummy/public/error/403.svg
993
- - spec/dummy/public/error/410.svg
993
+ - spec/dummy/public/error/timeout_2.svg
994
994
  - spec/dummy/public/error/401.svg
995
- - spec/dummy/public/error/404.svg
996
- - spec/dummy/public/error/500.svg
995
+ - spec/dummy/public/error/403.svg
997
996
  - spec/dummy/public/error/timeout_1.svg
998
997
  - spec/dummy/public/error/timeout_3.svg
999
- - spec/dummy/public/error/timeout_2.svg
1000
- - spec/dummy/config.ru
1001
- - spec/dummy/db/schema.rb
998
+ - spec/dummy/public/error/404.svg
999
+ - spec/dummy/public/error/410.svg
1000
+ - spec/dummy/public/error/500.svg
1001
+ - spec/dummy/public/medal/outline.svg
1002
1002
  - spec/dummy/db/seeds.rb
1003
- - spec/dummy/config/application.rb
1004
- - spec/dummy/config/boot.rb
1005
- - spec/dummy/config/initializers/filter_parameter_logging.rb
1006
- - spec/dummy/config/initializers/cookies_serializer.rb
1007
- - spec/dummy/config/initializers/wrap_parameters.rb
1008
- - spec/dummy/config/initializers/assets.rb
1009
- - spec/dummy/config/puma.rb
1010
- - spec/dummy/config/environments/development.rb
1011
- - spec/dummy/config/environments/test.rb
1012
- - spec/dummy/config/database.yml
1013
- - spec/dummy/config/locales/en.yml
1014
- - spec/dummy/config/secrets.yml
1015
- - spec/dummy/config/environment.rb
1016
- - spec/dummy/config/spring.rb
1017
- - spec/dummy/config/cable.yml
1018
- - spec/dummy/config/rabbit.yml
1019
- - spec/dummy/config/routes.rb
1020
- - spec/dummy/Rakefile
1021
- - spec/api_helper.rb
1022
- - spec/features/profile_flow_spec.rb
1023
- - spec/features/not_found_public_flow_spec.rb
1024
- - spec/features/home_private_flow_spec.rb
1025
- - spec/features/login_flow_spec.rb
1026
- - spec/features/certificate_programs_flow_spec.rb
1027
- - spec/features/links_flow_spec.rb
1028
- - spec/features/complements_flow_spec.rb
1003
+ - spec/dummy/db/schema.rb
1029
1004
  - spec/features/notifications_flow_spec.rb
1030
- - spec/features/topic_flow_spec.rb
1031
- - spec/features/guide_reset_spec.rb
1032
1005
  - spec/features/menu_bar_spec.rb
1033
- - spec/features/disabled_organization_flow_spec.rb
1034
- - spec/features/dynamic_exam_spec.rb
1006
+ - spec/features/user_activity_flow_spec.rb
1035
1007
  - spec/features/standard_flow_spec.rb
1036
- - spec/features/home_public_flow_spec.rb
1037
- - spec/features/chapters_flow_spec.rb
1038
- - spec/features/not_found_private_flow_spec.rb
1039
- - spec/features/immersive_redirection_spec.rb
1008
+ - spec/features/exams_flow_spec.rb
1009
+ - spec/features/discussion_flow_spec.rb
1010
+ - spec/features/login_flow_spec.rb
1011
+ - spec/features/links_flow_spec.rb
1040
1012
  - spec/features/terms_flow_spec.rb
1041
1013
  - spec/features/progressive_tips_spec.rb
1042
- - spec/features/lessons_flow_spec.rb
1043
- - spec/features/disable_user_flow_spec.rb
1044
- - spec/features/invitations_flow_spec.rb
1014
+ - spec/features/immersive_redirection_spec.rb
1015
+ - spec/features/not_found_public_flow_spec.rb
1045
1016
  - spec/features/guides_flow_spec.rb
1017
+ - spec/features/chapters_flow_spec.rb
1018
+ - spec/features/dynamic_exam_spec.rb
1019
+ - spec/features/home_private_flow_spec.rb
1020
+ - spec/features/complements_flow_spec.rb
1021
+ - spec/features/disable_user_flow_spec.rb
1022
+ - spec/features/disabled_organization_flow_spec.rb
1046
1023
  - spec/features/runner_assets_spec.rb
1047
- - spec/features/discussion_flow_spec.rb
1024
+ - spec/features/home_public_flow_spec.rb
1025
+ - spec/features/topic_flow_spec.rb
1026
+ - spec/features/guide_reset_spec.rb
1027
+ - spec/features/not_found_private_flow_spec.rb
1028
+ - spec/features/invitations_flow_spec.rb
1029
+ - spec/features/certificate_programs_flow_spec.rb
1030
+ - spec/features/profile_flow_spec.rb
1031
+ - spec/features/lessons_flow_spec.rb
1048
1032
  - spec/features/exercise_flow_spec.rb
1049
- - spec/features/exams_flow_spec.rb
1050
- - spec/javascripts/i18n-spec.js
1051
- - spec/javascripts/bridge-spec.js
1033
+ - spec/teaspoon_env.rb
1034
+ - spec/login_helper.rb
1035
+ - spec/mailers/user_mailer_spec.rb
1036
+ - spec/mailers/previews/user_mailer_preview.rb
1037
+ - spec/evaluation_helper.rb
1038
+ - spec/spec_helper.rb
1052
1039
  - spec/javascripts/timeout-spec.js
1053
- - spec/javascripts/results-renderers-spec.js
1054
- - spec/javascripts/kids-button-spec.js
1055
- - spec/javascripts/timer-spec.js
1056
1040
  - spec/javascripts/sync-mode-spec.js
1057
- - spec/javascripts/events-spec.js
1041
+ - spec/javascripts/kids-button-spec.js
1042
+ - spec/javascripts/csrf-token-spec.js
1058
1043
  - spec/javascripts/editors-spec.js
1044
+ - spec/javascripts/i18n-spec.js
1045
+ - spec/javascripts/submissions-store-spec.js
1059
1046
  - spec/javascripts/exercise-spec.js
1047
+ - spec/javascripts/speech-bubble-renderer-spec.js
1048
+ - spec/javascripts/events-spec.js
1060
1049
  - spec/javascripts/elipsis-spec.js
1061
1050
  - spec/javascripts/upload-spec.js
1051
+ - spec/javascripts/results-renderers-spec.js
1052
+ - spec/javascripts/timer-spec.js
1062
1053
  - spec/javascripts/spec-helper.js
1063
- - spec/javascripts/submissions-store-spec.js
1064
- - spec/javascripts/gamification-spec.js
1065
- - spec/javascripts/csrf-token-spec.js
1054
+ - spec/javascripts/bridge-spec.js
1066
1055
  - spec/javascripts/global-spec.js
1067
- - spec/javascripts/speech-bubble-renderer-spec.js
1068
- - spec/teaspoon_env.rb
1069
- - spec/helpers/exercise_input_helper_spec.rb
1070
- - spec/helpers/application_helper_spec.rb
1071
- - spec/helpers/page_title_helper_spec.rb
1072
- - spec/helpers/with_navigation_spec.rb
1056
+ - spec/javascripts/gamification-spec.js
1057
+ - spec/controllers/users_api_controller_spec.rb
1058
+ - spec/controllers/exercise_solutions_controller_spec.rb
1059
+ - spec/controllers/guide_progress_controller_spec.rb
1060
+ - spec/controllers/exam_registrations_controller_spec.rb
1061
+ - spec/controllers/courses_api_controller_spec.rb
1062
+ - spec/controllers/organizations_api_controller_spec.rb
1063
+ - spec/controllers/discussions_messages_controller_spec.rb
1064
+ - spec/controllers/confirmations_controller_spec.rb
1065
+ - spec/controllers/exam_authorization_requests_controller_spec.rb
1066
+ - spec/controllers/students_api_controller_spec.rb
1067
+ - spec/controllers/certificates_controller_spec.rb
1068
+ - spec/controllers/chapters_controller_spec.rb
1069
+ - spec/controllers/api_clients_controller.rb
1070
+ - spec/controllers/discussions_controller_spec.rb
1071
+ - spec/controllers/users_controller_spec.rb
1072
+ - spec/controllers/invitations_controller_spec.rb
1073
+ - spec/controllers/messages_controller_spec.rb
1074
+ - spec/api_helper.rb
1075
+ - spec/capybara_helper.rb
1073
1076
  - spec/helpers/authors_helper_spec.rb
1077
+ - spec/helpers/exercise_input_helper_spec.rb
1078
+ - spec/helpers/avatar_helper_spec.rb
1074
1079
  - spec/helpers/certificate_helper_spec.rb
1075
- - spec/helpers/email_helper_spec.rb
1080
+ - spec/helpers/breadcrumbs_helper_spec.rb
1076
1081
  - spec/helpers/with_choices_spec.rb
1077
- - spec/helpers/avatar_helper_spec.rb
1082
+ - spec/helpers/with_navigation_spec.rb
1083
+ - spec/helpers/email_helper_spec.rb
1084
+ - spec/helpers/user_activity_helper_spec.rb
1085
+ - spec/helpers/page_title_helper_spec.rb
1086
+ - spec/helpers/application_helper_spec.rb
1078
1087
  - spec/helpers/icons_helper_spec.rb
1079
1088
  - spec/helpers/test_results_rendering_spec.rb
1080
- - spec/helpers/breadcrumbs_helper_spec.rb