mumuki-domain 9.17.0 → 9.21.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6ddb5479d7f8ddd0c1c452f6a27f67ed5423a3d0aadca123e9aebddfed06d062
4
- data.tar.gz: e135a47bc3062fd705d316fd2eb7922dc45bec56620c35ac0ada0c77eac2ebd0
3
+ metadata.gz: 95912abc73b50f774b4e87873ea35afa3ce9016d4cf90ce9af6cfb9c88ea9c56
4
+ data.tar.gz: 3d2cbbf7c128f280edb477d38ad3a37770943ba9a0e6809d54936c62efb54186
5
5
  SHA512:
6
- metadata.gz: 4a1061815ce251506c410550ee976f552e5266da914845f2ae197a89a11d0f7713a4cbcc5e8ee8fcbef92668860bfda60de3d9fb14245c378d5a74096f849e5b
7
- data.tar.gz: d20d53b94de4eda7c28b90bbb0ff095f005c60ee0631a15eb1970d8b853010e4e7f3762662c127b3c674cca0aa1f939c5c9808dfa4ce946cbdd8b973e0419e86
6
+ metadata.gz: 54c74640cdef38c3aeec166b5fded89c82f4f867b37f83a2d0b3e24ef0bb4e0f0b707de265aaae9b56decfe6bdfadc6aa0448fb16506af72119ab3dca0e860c8
7
+ data.tar.gz: 75949f754f836b0315f5e717532e02de38a8222819d2ae4441df4b524e7fda2c55f45a12696d034060f3a1754120c6707f1cc6d3b9682d591d6c9edd8521fa58
@@ -68,6 +68,10 @@ class Assignment < Progress
68
68
  end
69
69
  end
70
70
 
71
+ def randomized_values
72
+ exercise.randomizer.randomized_values(submitter.id)
73
+ end
74
+
71
75
  def save_submission!(submission)
72
76
  transaction do
73
77
  update! submission_id: submission.id
@@ -182,8 +186,8 @@ class Assignment < Progress
182
186
  language: {only: [:name]}},
183
187
  },
184
188
  exercise: {only: [:name, :number]},
185
- submitter: {only: [:email, :social_id, :uid], methods: [:name, :profile_picture]}}).
186
- deep_merge(
189
+ submitter: {only: [:email, :social_id, :uid], methods: [:name, :profile_picture]}})
190
+ .deep_merge(
187
191
  'organization' => Organization.current.name,
188
192
  'sid' => submission_id,
189
193
  'created_at' => submitted_at || updated_at,
@@ -198,6 +202,7 @@ class Assignment < Progress
198
202
  'position' => navigable_parent.try(:number),
199
203
  'chapter' => guide.chapter.as_json(only: [:id], methods: [:name])
200
204
  }})
205
+ .merge({'randomized_values' => randomized_values.presence}.compact)
201
206
  end
202
207
 
203
208
  def tips
@@ -10,6 +10,6 @@ module Gamified
10
10
  end
11
11
 
12
12
  def net_experience
13
- submission_status.exp_given - top_submission_status.exp_given
13
+ submitter.currently_in_exam? ? 0 : (submission_status.exp_given - top_submission_status.exp_given)
14
14
  end
15
15
  end
@@ -9,7 +9,7 @@ class Organization::Status::InPreparation < Organization::Status::Base
9
9
  end
10
10
 
11
11
  def ex_student_access_mode(user)
12
- OrganizationAccessMode::Forbidden.new user, organization
12
+ OrganizationAccessMode::ReadOnly.new user, organization, :faqs, :profile
13
13
  end
14
14
 
15
15
  def outsider_access_mode(user)
@@ -0,0 +1,14 @@
1
+ module WithScopedQueries::Limit
2
+ def self.query_by(params, current_scope, _)
3
+ if params[:limit].present?
4
+ max_limit = [params[:limit].to_i, 25].min
5
+ current_scope.limit(max_limit)
6
+ else
7
+ current_scope
8
+ end
9
+ end
10
+
11
+ def self.add_queriable_attributes_to(klass, _)
12
+ klass.queriable_attributes.merge!(limit: :limit)
13
+ end
14
+ end
@@ -1,10 +1,14 @@
1
1
  module WithScopedQueries::Page
2
2
  def self.query_by(params, current_scope, _)
3
- page_param = params[:page] || 1
4
- current_scope.page(page_param).per(10)
3
+ if params[:limit].present?
4
+ current_scope
5
+ else
6
+ page_param = params[:page] || 1
7
+ current_scope.page(page_param).per(10)
8
+ end
5
9
  end
6
10
 
7
11
  def self.add_queriable_attributes_to(klass, _)
8
- klass.queriable_attributes.merge!(page: :page)
12
+ klass.queriable_attributes.merge!(page: [:page, :limit])
9
13
  end
10
14
  end
@@ -1,7 +1,7 @@
1
1
  module WithScopedQueries
2
2
  extend ActiveSupport::Concern
3
3
 
4
- SCOPING_METHODS = [Filter, Sort, Page]
4
+ SCOPING_METHODS = [Filter, Sort, Page, Limit]
5
5
 
6
6
  included do
7
7
  class_attribute :queriable_attributes, instance_writer: false
@@ -22,14 +22,16 @@ class Discussion < ApplicationRecord
22
22
  .or(where(responsible_moderator_at: nil)) }
23
23
  scope :pending_review, -> { where(status: :pending_review) }
24
24
  scope :unread_first, -> { includes(:subscriptions).reorder('subscriptions.read', created_at: :desc) }
25
+ scope :by_recent, -> (_) { where('created_at > ?', Time.now - 6.months)}
25
26
 
26
27
  after_create :subscribe_initiator!
27
28
 
28
29
  markdown_on :description
29
30
 
30
31
  sortable :responses_count, :upvotes_count, :created_at, default: :created_at_desc
31
- filterable :status, :language, :requires_attention
32
+ filterable :status, :language, :requires_attention, :recent
32
33
  pageable
34
+ limitable
33
35
 
34
36
  delegate :language, to: :item
35
37
  delegate :to_discussion_status, to: :status
data/app/models/exam.rb CHANGED
@@ -49,7 +49,7 @@ class Exam < ApplicationRecord
49
49
  end
50
50
 
51
51
  def accessible_for?(user)
52
- (authorized?(user) && enabled_for?(user)) || user&.teacher_here?
52
+ (authorized?(user) && enabled_for?(user)) || user&.teacher_of?(course)
53
53
  end
54
54
 
55
55
  def timed?
@@ -96,6 +96,10 @@ class Exam < ApplicationRecord
96
96
  end
97
97
  end
98
98
 
99
+ def time_left(user)
100
+ (real_end_time(user) - Time.current).round
101
+ end
102
+
99
103
  def started_at(user)
100
104
  authorization_for(user).started_at
101
105
  end
@@ -76,6 +76,18 @@ class ExamRegistration < ApplicationRecord
76
76
  authorization_criterion.meets_criterion?(user, organization)
77
77
  end
78
78
 
79
+ def available_exams
80
+ return exams unless limited_authorization_requests?
81
+ counts = authorization_request_ids_counts
82
+ exams.select do |it|
83
+ counts[it.id].to_i < authorization_requests_limit
84
+ end
85
+ end
86
+
87
+ def limited_authorization_requests?
88
+ authorization_requests_limit.present?
89
+ end
90
+
79
91
  def multiple_options?
80
92
  exams.count > 1
81
93
  end
@@ -84,9 +96,39 @@ class ExamRegistration < ApplicationRecord
84
96
  end_time.past?
85
97
  end
86
98
 
99
+ def request_authorization!(user, exam)
100
+ with_available_exam exam do
101
+ authorization_requests.find_or_create_by! user: user do |it|
102
+ it.assign_attributes organization: organization, exam: exam
103
+ end
104
+ end
105
+ end
106
+
107
+ def update_authorization_request_by_id!(request_id, exam)
108
+ with_available_exam exam do
109
+ authorization_requests.update request_id, exam: exam
110
+ end
111
+ end
112
+
113
+ def authorization_request_ids_counts
114
+ authorization_requests.group(:exam_id).count
115
+ end
116
+
117
+ def exam_available?(exam)
118
+ available_exams.include? exam
119
+ end
120
+
121
+ def with_available_exam(exam, &block)
122
+ transaction do
123
+ raise Mumuki::Domain::GoneError unless exam_available?(exam)
124
+ block.call
125
+ end
126
+ end
127
+
87
128
  private
88
129
 
89
130
  def notify_registree!(registree)
90
131
  Notification.create_and_notify_via_email! organization: organization, user: registree, subject: :exam_registration, target: self
91
132
  end
133
+
92
134
  end
@@ -10,6 +10,7 @@ class Message < ApplicationRecord
10
10
  validates_presence_of :content, :sender
11
11
  validate :ensure_contextualized
12
12
 
13
+ before_create :mark_from_moderator!
13
14
  after_save :update_counters_cache!
14
15
 
15
16
  markdown_on :content
@@ -53,7 +54,7 @@ class Message < ApplicationRecord
53
54
  end
54
55
 
55
56
  def from_moderator?
56
- sender_user.moderator_here?
57
+ from_moderator || sender_user.moderator_here?
57
58
  end
58
59
 
59
60
  def from_user?(user)
@@ -74,7 +75,7 @@ class Message < ApplicationRecord
74
75
 
75
76
  def to_resource_h
76
77
  as_json(except: [:id, :type, :discussion_id, :approved, :approved_at, :approved_by_id,
77
- :not_actually_a_question, :deletion_motive, :deleted_at, :deleted_by_id],
78
+ :not_actually_a_question, :deletion_motive, :deleted_at, :deleted_by_id, :from_moderator],
78
79
  include: {exercise: {only: [:bibliotheca_id]}})
79
80
  .merge(organization: Organization.current.name)
80
81
  end
@@ -103,6 +104,10 @@ class Message < ApplicationRecord
103
104
  approved? || from_moderator?
104
105
  end
105
106
 
107
+ def mark_from_moderator!
108
+ self.from_moderator = from_moderator?
109
+ end
110
+
106
111
  def update_counters_cache!
107
112
  discussion&.update_counters!
108
113
  end
@@ -17,7 +17,7 @@ class OrganizationAccessMode::ReadOnly < OrganizationAccessMode::Base
17
17
  end
18
18
 
19
19
  def validate_discuss_here!(discussion)
20
- super(discussion) unless discussion&.initiator == user
20
+ super(discussion) unless discuss_here? && discussion&.initiator == user
21
21
  end
22
22
 
23
23
  def show_content?(content)
data/app/models/user.rb CHANGED
@@ -157,8 +157,8 @@ class User < ApplicationRecord
157
157
  save_and_notify!
158
158
  end
159
159
 
160
- def detach!(role, course)
161
- make_ex_student_of! course.slug if student_of?(course.slug) && solved_any_exercises?(course.organization)
160
+ def detach!(role, course, deep: false)
161
+ make_ex_student_of! course.slug if !deep && student_of?(course.slug) && solved_any_exercises?(course.organization)
162
162
  remove_permission! role, course.slug
163
163
  save_and_notify!
164
164
  end
@@ -0,0 +1,5 @@
1
+ class AddAuthorizationRequestsLimitToExamRegistration < ActiveRecord::Migration[5.1]
2
+ def change
3
+ add_column :exam_registrations, :authorization_requests_limit, :integer
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddFromModeratorToMessages < ActiveRecord::Migration[5.1]
2
+ def change
3
+ add_column :messages, :from_moderator, :boolean
4
+ end
5
+ end
@@ -1,6 +1,6 @@
1
1
  FactoryBot.define do
2
-
3
2
  factory :message do
4
3
  content { Faker::Lorem.sentence(word_count: 3) }
4
+ sender { create(:user).uid }
5
5
  end
6
6
  end
@@ -1,5 +1,5 @@
1
1
  module Mumuki
2
2
  module Domain
3
- VERSION = '9.17.0'
3
+ VERSION = '9.21.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mumuki-domain
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.17.0
4
+ version: 9.21.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Franco Leonardo Bulgarelli
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-23 00:00:00.000000000 Z
11
+ date: 2021-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -114,14 +114,14 @@ dependencies:
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '1.0'
117
+ version: '1.2'
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '1.0'
124
+ version: '1.2'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: mumukit-platform
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -306,6 +306,7 @@ files:
306
306
  - app/models/concerns/with_responsible_moderator.rb
307
307
  - app/models/concerns/with_scoped_queries.rb
308
308
  - app/models/concerns/with_scoped_queries/filter.rb
309
+ - app/models/concerns/with_scoped_queries/limit.rb
309
310
  - app/models/concerns/with_scoped_queries/page.rb
310
311
  - app/models/concerns/with_scoped_queries/sort.rb
311
312
  - app/models/concerns/with_slug.rb
@@ -686,6 +687,8 @@ files:
686
687
  - db/migrate/20210707143002_add_assignment_id_to_message.rb
687
688
  - db/migrate/20210719145706_add_new_fields_to_notifications.rb
688
689
  - db/migrate/20210803175124_add_ignored_notifications_to_users.rb
690
+ - db/migrate/20210929223144_add_authorization_requests_limit_to_exam_registration.rb
691
+ - db/migrate/20211020224011_add_from_moderator_to_messages.rb
689
692
  - lib/mumuki/domain.rb
690
693
  - lib/mumuki/domain/area.rb
691
694
  - lib/mumuki/domain/engine.rb