mumuki-domain 7.5.1 → 7.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5ef144a131abd81dec63a202e154365daa60a369f157f3dacd86fae7b6b078c7
4
- data.tar.gz: f3b58dde606295d1e3c5edc5c901259bfff933570927e66fb112c58f062fcc7d
3
+ metadata.gz: 40391bc2dcc0ab54965e1d82a289c8960dac3f68cf4c8fb2a3d097e774b899b4
4
+ data.tar.gz: 205ce356bcc3365491551226eaa2b076ae58d7ac1255fb51294424b419ea4ffb
5
5
  SHA512:
6
- metadata.gz: c6d190e5ebdb654e7be93ddd9b5b3938e67fc334d8dfe0ac769aa62cb44ec8e8acc1fefde7a5418a0b9fc01f07d2956ab5464025e0b7cf953d1c983a1c6a942c
7
- data.tar.gz: 647aa6b8fbd360d2cc5a306dcc58ad148316aa5c6ed3a893fe08e11462e732075d9775dc6c038f9dca03c7dac3ad2236f81f74b05a06473fa93f3ea53331a953
6
+ metadata.gz: 3741ef7ad7daf3f6cfc2d829d8fbf336512e4ec719257734d2e3bcc0b960081a6c50bdc3f31e2c82dc59abbc1d2d1719ab68ace80ec8c7ff1a908613b1123409
7
+ data.tar.gz: cf4e192e33fcdd94f68398f074715b22088169d50b88acc9d1aa0457bb15850a8288f2280ecbcf5aec874dd8c85f01c952a430762113fe5a383c19816bcbb5c2
@@ -62,4 +62,17 @@ class Book < Content
62
62
  def structural_parent
63
63
  nil
64
64
  end
65
+
66
+ ## progressive display
67
+
68
+ def enabled_chapters_in(workspace)
69
+ workspace.enabled_containers(chapters)
70
+ end
71
+
72
+ # experimental API - it may change in the future.
73
+ # This method assumes no gaps in the sequences are introduced
74
+ # by enabled_chapters_in
75
+ def chapter_visibilities_in(workspace)
76
+ chapters.zip(enabled_chapters_in(workspace)).map { |chapter, enabled| [chapter, !enabled.nil?] }
77
+ end
65
78
  end
@@ -1,4 +1,4 @@
1
- module WithContent
1
+ module Container
2
2
  extend ActiveSupport::Concern
3
3
 
4
4
  included do
@@ -1,6 +1,6 @@
1
1
  module GuideContainer
2
2
  extend ActiveSupport::Concern
3
- include WithContent
3
+ include Container
4
4
 
5
5
  included do
6
6
  associated_content :guide
@@ -1,6 +1,6 @@
1
1
  module TopicContainer
2
2
  extend ActiveSupport::Concern
3
- include WithContent
3
+ include Container
4
4
 
5
5
  included do
6
6
  associated_content :topic
@@ -19,6 +19,10 @@ module WithProgress
19
19
  self
20
20
  end
21
21
 
22
+ def completed_for?(user, organization)
23
+ progress_for(user, organization).completed?
24
+ end
25
+
22
26
  private
23
27
 
24
28
  def structural_children_changed?(old_structural_children)
@@ -1,6 +1,7 @@
1
1
  class Course < ApplicationRecord
2
2
  include Mumuki::Domain::Syncable
3
3
  include Mumuki::Domain::Helpers::Course
4
+ include Mumuki::Domain::Area
4
5
 
5
6
  validates_presence_of :slug, :shifts, :code, :days, :period, :description, :organization_id
6
7
  validates_uniqueness_of :slug
@@ -48,4 +49,8 @@ class Course < ApplicationRecord
48
49
  def self.sync_key_id_field
49
50
  :slug
50
51
  end
52
+
53
+ def to_organization
54
+ organization
55
+ end
51
56
  end
@@ -1,6 +1,7 @@
1
1
  class Organization < ApplicationRecord
2
2
  include Mumuki::Domain::Syncable
3
3
  include Mumuki::Domain::Helpers::Organization
4
+ include Mumuki::Domain::Area
4
5
 
5
6
  include Mumukit::Login::OrganizationHelpers
6
7
 
@@ -11,6 +12,7 @@ class Organization < ApplicationRecord
11
12
  markdown_on :description
12
13
 
13
14
  validate :ensure_consistent_public_login
15
+ validate :ensure_valid_activity_range
14
16
 
15
17
  belongs_to :book
16
18
  has_many :usages
@@ -126,12 +128,26 @@ class Organization < ApplicationRecord
126
128
  super.merge(book: book.slug)
127
129
  end
128
130
 
131
+ def to_organization
132
+ self
133
+ end
134
+
135
+ def enable_progressive_display!(lookahead: 1)
136
+ update! progressive_display_lookahead: lookahead
137
+ end
138
+
129
139
  private
130
140
 
131
141
  def ensure_consistent_public_login
132
142
  errors.add(:base, :consistent_public_login) if settings.customized_login_methods? && public?
133
143
  end
134
144
 
145
+ def ensure_valid_activity_range
146
+ if in_preparation_until.present? && disabled_from.present?
147
+ errors.add(:base, :invalid_activity_range) if in_preparation_until.to_datetime >= disabled_from.to_datetime
148
+ end
149
+ end
150
+
135
151
  def notify_assignments!(assignments)
136
152
  assignments.each { |assignment| assignment.notify! }
137
153
  end
@@ -154,6 +154,21 @@ class User < ApplicationRecord
154
154
  update! self.class.buried_profile.merge(accepts_reminders: false, gender: nil, birthdate: nil)
155
155
  end
156
156
 
157
+ # Takes a didactic - ordered - sequence of content containers
158
+ # and returns those that have been completed
159
+ def completed_containers(sequence, organization)
160
+ sequence.take_while { |it| it.content.completed_for?(self, organization) }
161
+ end
162
+
163
+ # Like `completed_containers`, returns a slice of the completed containers
164
+ # in the sequence, but adding a configurable number of trailing, non-completed contaienrs
165
+ def completed_containers_with_lookahead(sequence, organization, lookahead: 1)
166
+ raise 'invalid lookahead' if lookahead < 1
167
+
168
+ count = completed_containers(sequence, organization).size
169
+ sequence[0..count + lookahead - 1]
170
+ end
171
+
157
172
  private
158
173
 
159
174
  def set_uid!
@@ -0,0 +1,5 @@
1
+ class AddProgressiveDisplayLookaheadToOrganizations < ActiveRecord::Migration[5.1]
2
+ def change
3
+ add_column :organizations, :progressive_display_lookahead, :integer
4
+ end
5
+ end
@@ -25,6 +25,7 @@ Mumukit::Platform.configure do |config|
25
25
  config.organization_class_name = 'Organization'
26
26
  end
27
27
 
28
+ require_relative './domain/area'
28
29
  require_relative './domain/evaluation'
29
30
  require_relative './domain/submission'
30
31
  require_relative './domain/status'
@@ -32,6 +33,7 @@ require_relative './domain/exceptions'
32
33
  require_relative './domain/file'
33
34
  require_relative './domain/extensions'
34
35
  require_relative './domain/organization'
36
+ require_relative './domain/workspace'
35
37
  require_relative './domain/helpers'
36
38
  require_relative './domain/syncable'
37
39
  require_relative './domain/store'
@@ -0,0 +1,13 @@
1
+ module Mumuki::Domain::Area
2
+ extend ActiveSupport::Concern
3
+
4
+ def to_mumukit_grant
5
+ slug.to_mumukit_grant
6
+ end
7
+
8
+ def to_mumukit_slug
9
+ slug
10
+ end
11
+
12
+ required :to_organization
13
+ end
@@ -4,3 +4,5 @@ require_relative './exceptions/not_found_error'
4
4
  require_relative './exceptions/unauthorized_error'
5
5
  require_relative './exceptions/disabled_error'
6
6
  require_relative './exceptions/blocked_forum_error'
7
+ require_relative './exceptions/unprepared_organization_error'
8
+ require_relative './exceptions/disabled_organization_error'
@@ -0,0 +1,2 @@
1
+ class Mumuki::Domain::DisabledOrganizationError < StandardError
2
+ end
@@ -0,0 +1,2 @@
1
+ class Mumuki::Domain::UnpreparedOrganizationError < StandardError
2
+ end
@@ -4,7 +4,7 @@ module Mumuki::Domain::Helpers::Organization
4
4
 
5
5
  included do
6
6
  delegate *Mumuki::Domain::Organization::Theme.accessors, to: :theme
7
- delegate *Mumuki::Domain::Organization::Settings.accessors, :private?, :login_settings, to: :settings
7
+ delegate *Mumuki::Domain::Organization::Settings.accessors, :private?, :login_settings, :in_preparation?, :disabled?, to: :settings
8
8
  delegate *Mumuki::Domain::Organization::Profile.accessors, :locale_json, to: :profile
9
9
  end
10
10
 
@@ -48,6 +48,11 @@ module Mumuki::Domain::Helpers::Organization
48
48
  Mumukit::Platform.application.organic_domain(name)
49
49
  end
50
50
 
51
+ def validate_active!
52
+ raise Mumuki::Domain::DisabledOrganizationError if disabled?
53
+ raise Mumuki::Domain::UnpreparedOrganizationError if in_preparation?
54
+ end
55
+
51
56
  ## API Exposure
52
57
 
53
58
  def to_param
@@ -28,9 +28,9 @@ module Mumuki::Domain::Helpers::User
28
28
  role_here = "#{role}_here?"
29
29
 
30
30
  # Tells whether this user has #{role} permissions in
31
- # the given organization
32
- define_method role_of do |organization|
33
- has_permission? role, organization.slug
31
+ # the given `slug_like`
32
+ define_method role_of do |slug_like|
33
+ has_permission? role, slug_like.to_mumukit_slug
34
34
  end
35
35
 
36
36
  # Tells whether this user has #{role} permissions in
@@ -49,9 +49,9 @@ module Mumuki::Domain::Helpers::User
49
49
  (Mumukit::Auth::Roles::ROLES - [:owner]).each do |role|
50
50
 
51
51
  # Assignes the #{role} role to this user
52
- # for the given slug
53
- define_method "make_#{role}_of!" do |slug|
54
- add_permission! role, slug
52
+ # for the given `grant_like`
53
+ define_method "make_#{role}_of!" do |grant_like|
54
+ add_permission! role, grant_like.to_mumukit_grant
55
55
  end
56
56
  end
57
57
 
@@ -27,3 +27,4 @@ en:
27
27
  attributes:
28
28
  base:
29
29
  consistent_public_login: 'A public organization can not restrict login methods'
30
+ invalid_activity_range: 'The organization activity range are not valid'
@@ -44,6 +44,7 @@ es:
44
44
  attributes:
45
45
  base:
46
46
  consistent_public_login: 'Una organización pública no puede restringir los métodos de login'
47
+ invalid_activity_range: 'La fecha de deshabilitación no puede ser anterior a la de inicio del recorrido'
47
48
  models:
48
49
  exercise:
49
50
  one: Ejercicio
@@ -27,3 +27,4 @@ pt:
27
27
  attributes:
28
28
  base:
29
29
  consistent_public_login: 'Uma organização pública não pode restringir métodos de login'
30
+ invalid_activity_range: 'O intervalo de atividades da organização não é válido'
@@ -11,7 +11,9 @@ class Mumuki::Domain::Organization::Settings < Mumukit::Platform::Model
11
11
  :embeddable?,
12
12
  :immersive?,
13
13
  :forum_enabled?,
14
- :report_issue_enabled?
14
+ :report_issue_enabled?,
15
+ :disabled_from,
16
+ :in_preparation_until
15
17
 
16
18
  def private?
17
19
  !public?
@@ -24,4 +26,12 @@ class Mumuki::Domain::Organization::Settings < Mumukit::Platform::Model
24
26
  def forum_discussions_minimal_role
25
27
  (@forum_discussions_minimal_role || 'student').to_sym
26
28
  end
29
+
30
+ def disabled?
31
+ disabled_from.present? && disabled_from.to_datetime < DateTime.now
32
+ end
33
+
34
+ def in_preparation?
35
+ in_preparation_until.present? && in_preparation_until.to_datetime > DateTime.now
36
+ end
27
37
  end
@@ -41,4 +41,8 @@ module Mumuki::Domain::Status::Discussion
41
41
  def allowed_statuses_for(user, discussion)
42
42
  STATUSES.select { |it| it.allowed_for?(user, discussion) }
43
43
  end
44
+
45
+ def as_json(_options={})
46
+ to_s
47
+ end
44
48
  end
@@ -1,5 +1,5 @@
1
1
  module Mumuki
2
2
  module Domain
3
- VERSION = '7.5.1'
3
+ VERSION = '7.6.0'
4
4
  end
5
5
  end
@@ -0,0 +1,38 @@
1
+ class Mumuki::Domain::Workspace
2
+ attr_accessor :user, :area
3
+
4
+ # area is a organization-like or course-like object
5
+ # that can be converted into slugs, has content and access-rules information
6
+ def initialize(user, area)
7
+ @user = user
8
+ @area = area
9
+ end
10
+
11
+ def annonymous?
12
+ user.nil?
13
+ end
14
+
15
+ def teacher?
16
+ user.teacher_of? area
17
+ end
18
+
19
+ # Takes a didactic sequence of containers and retuns the enabled containers
20
+ # for this user in this workspace.
21
+ #
22
+ # This method does not check the user is actually member of the area,
23
+ # you should check that before sending this message
24
+ #
25
+ def enabled_containers(sequence)
26
+ return sequence if annonymous? || teacher?
27
+
28
+ # TODO refactor when introducing access rules
29
+ if area.progressive_display_lookahead
30
+ user.completed_containers_with_lookahead(
31
+ sequence,
32
+ area.to_organization,
33
+ lookahead: area.progressive_display_lookahead)
34
+ else
35
+ sequence
36
+ end
37
+ end
38
+ 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: 7.5.1
4
+ version: 7.6.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: 2020-06-05 00:00:00.000000000 Z
11
+ date: 2020-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -252,6 +252,7 @@ files:
252
252
  - app/models/chapter.rb
253
253
  - app/models/complement.rb
254
254
  - app/models/concerns/assistable.rb
255
+ - app/models/concerns/container.rb
255
256
  - app/models/concerns/contextualization.rb
256
257
  - app/models/concerns/disabling.rb
257
258
  - app/models/concerns/friendly_name.rb
@@ -268,7 +269,6 @@ files:
268
269
  - app/models/concerns/topic_container.rb
269
270
  - app/models/concerns/with_assignments.rb
270
271
  - app/models/concerns/with_case_insensitive_search.rb
271
- - app/models/concerns/with_content.rb
272
272
  - app/models/concerns/with_description.rb
273
273
  - app/models/concerns/with_discussion_creation.rb
274
274
  - app/models/concerns/with_discussion_creation/subscription.rb
@@ -604,7 +604,9 @@ files:
604
604
  - db/migrate/20200508191543_create_avatars.rb
605
605
  - db/migrate/20200518135658_add_avatar_to_users.rb
606
606
  - db/migrate/20200527180729_add_disabled_at_to_users.rb
607
+ - db/migrate/20200608132959_add_progressive_display_lookahead_to_organizations.rb
607
608
  - lib/mumuki/domain.rb
609
+ - lib/mumuki/domain/area.rb
608
610
  - lib/mumuki/domain/engine.rb
609
611
  - lib/mumuki/domain/evaluation.rb
610
612
  - lib/mumuki/domain/evaluation/automated.rb
@@ -612,10 +614,12 @@ files:
612
614
  - lib/mumuki/domain/exceptions.rb
613
615
  - lib/mumuki/domain/exceptions/blocked_forum_error.rb
614
616
  - lib/mumuki/domain/exceptions/disabled_error.rb
617
+ - lib/mumuki/domain/exceptions/disabled_organization_error.rb
615
618
  - lib/mumuki/domain/exceptions/forbidden_error.rb
616
619
  - lib/mumuki/domain/exceptions/gone_error.rb
617
620
  - lib/mumuki/domain/exceptions/not_found_error.rb
618
621
  - lib/mumuki/domain/exceptions/unauthorized_error.rb
622
+ - lib/mumuki/domain/exceptions/unprepared_organization_error.rb
619
623
  - lib/mumuki/domain/extensions.rb
620
624
  - lib/mumuki/domain/extensions/array.rb
621
625
  - lib/mumuki/domain/extensions/hash.rb
@@ -690,6 +694,7 @@ files:
690
694
  - lib/mumuki/domain/syncable.rb
691
695
  - lib/mumuki/domain/syncable/with_resource_fields.rb
692
696
  - lib/mumuki/domain/version.rb
697
+ - lib/mumuki/domain/workspace.rb
693
698
  homepage: https://mumuki.org
694
699
  licenses:
695
700
  - AGPL-3.0