mumuki-classroom 9.22.0 → 9.23.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: e69915472d5d00dbff99a60c08be0f0ba39ac528031fed66d8dc15197209166b
4
- data.tar.gz: 7ea3bf7cb8a2d6d8d914f91a0a4e9f5d5d6d3c65fd3a0a8d88096d1b1bc3fded
3
+ metadata.gz: cabe7b354830abd76c73425df9e9ff2c4f7fa806bb6dbc0cac68a319bd12e231
4
+ data.tar.gz: acc653411dc6f1a809d0439d93de48d02a64020bd2c446b32ab25afeaff7dd06
5
5
  SHA512:
6
- metadata.gz: 78e0556dbb3d7dad7df7f09acb8bc2675f06788d995801a14489761199746a3b84669fbb9bf82ad0ef2b09958d595fbbd9a2e54064c72d472cc9be7d850717e3
7
- data.tar.gz: 29fa6f708867854dbc987969ca766612d5f2e9e74692d80b5f7c5e8a4e964f78430cf1202587f0500a4b74440a07fec88b16709deb5e54111d836e8c321b6712
6
+ metadata.gz: 0f0c793f1362ca34c185acd9cd92dfc7bdc660ad84f79fcb96b564d88eba59e05270163ff78dcb1bb56aa7cb16b1eb08914316fff37fdcb4ca02dc1611f4cee1
7
+ data.tar.gz: 041020d946aaece5a110f039050486c0983401b6f42f67d899a328896222b6ab9debaeb6c6c6ec1b8b11940d26f0dcbf5c35ec5e69eee18ddacf0429195cc8c8
@@ -29,8 +29,11 @@ class Mumuki::Classroom::Event::UserChanged
29
29
  if students.exists?
30
30
  students.first.attach!
31
31
  else
32
- student = Mumuki::Classroom::Student.attributes_from_uid uid
33
- Mumuki::Classroom::Student.create! student.merge(organization: organization, course: granted_slug.to_s)
32
+ student = Mumuki::Classroom::Student.new(
33
+ Mumuki::Classroom::Student
34
+ .attributes_from_uid(uid)
35
+ .merge(organization: organization, course: granted_slug.to_s))
36
+ student.save! validate: false
34
37
  end
35
38
  end
36
39
 
@@ -41,8 +44,9 @@ class Mumuki::Classroom::Event::UserChanged
41
44
 
42
45
  def teacher_added(organization, user, granted_slug)
43
46
  uid = user[:uid]
44
- teacher = Mumuki::Classroom::Teacher.find_or_create_by!(organization: organization, course: granted_slug.to_s, uid: uid)
45
- teacher.update_attributes!(Mumuki::Classroom::Teacher.attributes_from_uid(uid))
47
+ teacher = Mumuki::Classroom::Teacher.find_or_initialize_by(organization: organization, course: granted_slug.to_s, uid: uid)
48
+ teacher.assign_attributes(Mumuki::Classroom::Teacher.attributes_from_uid(uid))
49
+ teacher.save! validate: false
46
50
  end
47
51
 
48
52
  def teacher_removed(organization, user, granted_slug)
@@ -0,0 +1,15 @@
1
+ class Mumuki::Classroom::Certificate < Mumuki::Classroom::Document
2
+ include Mongoid::Timestamps
3
+
4
+ field :pg_id, type: Integer
5
+ field :code, type: String
6
+ field :certificate_program_id, type: Integer
7
+ field :organization, type: String
8
+ field :student, type: Hash
9
+ field :started_at, type: Time
10
+ field :ended_at, type: Time
11
+
12
+ create_index(pg_id: 1)
13
+ create_index(organization: 1, 'student.course': 1, 'student.uid': 1)
14
+ create_index(certificate_program_id: 1)
15
+ end
@@ -1,6 +1,8 @@
1
1
  module CourseMember
2
2
  extend ActiveSupport::Concern
3
3
 
4
+ MANDATORY_FIELDS = %w(uid first_name last_name email)
5
+
4
6
  included do
5
7
  include Mongoid::Timestamps
6
8
 
@@ -15,6 +17,9 @@ module CourseMember
15
17
  field :course, type: Mumukit::Auth::Slug
16
18
 
17
19
  create_index({organization: 1, course: 1, uid: 1}, {unique: true})
20
+
21
+ validates_presence_of(*MANDATORY_FIELDS)
22
+ validates :email, email: true
18
23
  end
19
24
 
20
25
  def as_user(verified: true)
@@ -23,6 +28,10 @@ module CourseMember
23
28
  end
24
29
 
25
30
  class_methods do
31
+ def valid_attributes?(json)
32
+ MANDATORY_FIELDS.all? { |it| json[it].present? } && EmailValidator.valid?(json[:email])
33
+ end
34
+
26
35
  def ensure_not_exists!(query)
27
36
  existing_members = where(query)
28
37
  raise Mumuki::Classroom::CourseMemberExistsError, {existing_members: existing_members.map(&:uid)}.to_json if existing_members.exists?
@@ -0,0 +1,12 @@
1
+ class Mumuki::Classroom::ExamAuthorization < Mumuki::Classroom::Document
2
+ field :pg_id, type: Integer
3
+ field :session_id, type: String
4
+ field :guide_slug, type: String
5
+ field :organization, type: String
6
+ field :student, type: Hash
7
+ field :started, type: Mongoid::Boolean
8
+ field :started_at, type: Time
9
+
10
+ create_index(pg_id: 1)
11
+ create_index(organization: 1, 'student.course': 1, guide_slug: 1, 'student.uid': 1)
12
+ end
@@ -0,0 +1,15 @@
1
+ class Mumuki::Classroom::ExamAuthorizationRequest < Mumuki::Classroom::Document
2
+ include Mongoid::Timestamps
3
+
4
+ field :pg_id, type: Integer
5
+ field :status, type: String
6
+ field :guide_slug, type: String
7
+ field :organization, type: String
8
+ field :exam_registration_id, type: Integer
9
+ field :student, type: Hash
10
+
11
+ create_index(pg_id: 1)
12
+ create_index(organization: 1, 'student.course': 1, guide_slug: 1, 'student.uid': 1)
13
+ create_index(exam_registration_id: 1)
14
+ create_index(organization: 1, 'student.course': 1, 'student.uid': 1)
15
+ end
@@ -16,6 +16,9 @@ require_relative './models/student'
16
16
  require_relative './models/teacher'
17
17
  require_relative './models/notification'
18
18
  require_relative './models/suggestion'
19
+ require_relative './models/certificate'
20
+ require_relative './models/exam_authorization'
21
+ require_relative './models/exam_authorization_request'
19
22
 
20
23
  require_relative './models/sorting'
21
24
  require_relative './models/searching'
@@ -37,13 +37,13 @@ class Mumuki::Classroom::App < Sinatra::Application
37
37
 
38
38
  post '/students/detach' do
39
39
  update_students! do |processed|
40
- update_students_at_course! :detach, :remove, processed
40
+ update_students_permissions_at_course! :detach, :remove, processed
41
41
  end
42
42
  end
43
43
 
44
44
  post '/students/attach' do
45
45
  update_students! do |processed|
46
- update_students_at_course! :attach, :add, processed
46
+ update_students_permissions_at_course! :attach, :add, processed
47
47
  end
48
48
  end
49
49
 
@@ -98,7 +98,7 @@ class Mumuki::Classroom::App < Sinatra::Application
98
98
  user = User.find_or_initialize_by(uid: member[:uid])
99
99
  user.assign_attributes user_from_member_json(member)
100
100
  user.add_permission! role, course_slug
101
- user.verify_name!
101
+ user.verify_name! force: true
102
102
  yield user if block_given?
103
103
  end
104
104
 
@@ -143,20 +143,39 @@ class Mumuki::Classroom::App < Sinatra::Application
143
143
 
144
144
  def create_members!(role, &block)
145
145
  members_collection = collection_for role
146
- massive_members = massive_members_for role
147
- existing_members = existing_members_in_course(members_collection, massive_members)
148
- existing_members_uids = existing_members.map { |it| it[:uid] }
149
- processed_members = massive_members.reject { |it| existing_members_uids.include? it[:uid] }.uniq { |it| it[:uid]}
150
- members_collection.collection.insert_many(processed_members.map { |member| with_organization_and_course member })
151
- upsert_users! role, processed_members, &block
152
- massive_response(processed_members, unprocessed_members_for(role), existing_members,
146
+
147
+ existing_members, non_existent_members = partion_existing_members_in_course(
148
+ members_collection,
149
+ massive_members_for(role))
150
+
151
+ valid_members, invalid_members = non_existent_members.partition do |member|
152
+ members_collection.valid_attributes? member
153
+ end
154
+
155
+ errored_members = existing_members + invalid_members
156
+
157
+ members_collection
158
+ .collection
159
+ .insert_many(valid_members.map { |member| with_organization_and_course member })
160
+ upsert_users! role, valid_members, &block
161
+
162
+ massive_response(valid_members, unprocessed_members_for(role), errored_members,
153
163
  "#{role.to_s.pluralize.titleize} already belong to current course", status: :created)
154
164
  end
155
165
 
156
- def existing_members_in_course(col, massive_members)
157
- col.where(with_organization_and_course)
166
+ def partion_existing_members_in_course(collection, massive_members)
167
+ existing_members = existing_members_in_course(collection, massive_members)
168
+ existing_members_uids = existing_members.map { |it| it[:uid] }
169
+ [
170
+ existing_members,
171
+ massive_members.reject { |it| existing_members_uids.include? it[:uid] }.uniq { |it| it[:uid] }
172
+ ]
173
+ end
174
+
175
+ def existing_members_in_course(collection, massive_members)
176
+ collection.where(with_organization_and_course)
158
177
  .in(uid: massive_members.map { |it| it[:uid] })
159
- .map { |it| col.normalized_attributes_from_json(it) }
178
+ .map { |it| collection.normalized_attributes_from_json(it) }
160
179
  end
161
180
 
162
181
  def update_students!
@@ -166,7 +185,7 @@ class Mumuki::Classroom::App < Sinatra::Application
166
185
  students_does_not_belong_msg, status: :updated
167
186
  end
168
187
 
169
- def update_students_at_course!(method, action, students_uids)
188
+ def update_students_permissions_at_course!(method, action, students_uids)
170
189
  Mumuki::Classroom::Student.send "#{method}_all_by!", students_uids, with_organization_and_course
171
190
  User.where(uid: students_uids).each do |user|
172
191
  user.send "#{action}_permission!", :student, course_slug
@@ -1,11 +1,5 @@
1
1
  class Mumuki::Classroom::App < Sinatra::Application
2
2
  helpers do
3
- def normalize_student!
4
- json_body[:email] = json_body[:email]&.downcase
5
- json_body[:last_name] = json_body[:last_name]&.downcase&.titleize
6
- json_body[:first_name] = json_body[:first_name]&.downcase&.titleize
7
- end
8
-
9
3
  def list_students(matcher)
10
4
  authorize! :teacher
11
5
  count, students = Sorting.aggregate(Mumuki::Classroom::Student, with_detached_and_search(matcher, Mumuki::Classroom::Student), paginated_params, query_params)
@@ -243,7 +243,12 @@ HTML
243
243
  json = JSON.parse(error_message.message)
244
244
  response.body = json.to_json
245
245
  rescue
246
- response.body = {message: error_message.message}.to_json
246
+ if error_message.is_a?(Mongoid::Errors::MongoidError)
247
+ message_text = error_message.summary
248
+ else
249
+ message_text = error_message.message
250
+ end
251
+ response.body = {message: message_text}.to_json
247
252
  end
248
253
  end
249
254
  end
@@ -256,6 +261,10 @@ HTML
256
261
  halt 400
257
262
  end
258
263
 
264
+ error Mongoid::Errors::Validations do
265
+ halt 400
266
+ end
267
+
259
268
  error ActiveRecord::RecordNotFound do
260
269
  halt 404
261
270
  end
@@ -1,5 +1,5 @@
1
1
  module Mumuki
2
2
  module Classroom
3
- VERSION = '9.22.0'
3
+ VERSION = '9.23.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mumuki-classroom
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.22.0
4
+ version: 9.23.0
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-11-04 00:00:00.000000000 Z
11
+ date: 2021-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -86,14 +86,14 @@ dependencies:
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 9.22.0
89
+ version: 9.23.0
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 9.22.0
96
+ version: 9.23.0
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: mumukit-login
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -232,11 +232,14 @@ files:
232
232
  - lib/mumuki/classroom/locales/pt.yml
233
233
  - lib/mumuki/classroom/models.rb
234
234
  - lib/mumuki/classroom/models/assignment.rb
235
+ - lib/mumuki/classroom/models/certificate.rb
235
236
  - lib/mumuki/classroom/models/concerns/course_member.rb
236
237
  - lib/mumuki/classroom/models/concerns/extensions.rb
237
238
  - lib/mumuki/classroom/models/concerns/with_failed_submission_reprocess.rb
238
239
  - lib/mumuki/classroom/models/concerns/with_submission_process.rb
239
240
  - lib/mumuki/classroom/models/document.rb
241
+ - lib/mumuki/classroom/models/exam_authorization.rb
242
+ - lib/mumuki/classroom/models/exam_authorization_request.rb
240
243
  - lib/mumuki/classroom/models/exercise.rb
241
244
  - lib/mumuki/classroom/models/failed_submission.rb
242
245
  - lib/mumuki/classroom/models/follower.rb