DEV: treats private invitees as public and only create them on attendance

DEV: treats private invitees as public and only create them on attendance

diff --git a/app/models/discourse_post_event/event.rb b/app/models/discourse_post_event/event.rb
index 56f0490..b3f62d0 100644
--- a/app/models/discourse_post_event/event.rb
+++ b/app/models/discourse_post_event/event.rb
@@ -179,45 +179,47 @@ module DiscoursePostEvent
     end
 
     def most_likely_going(limit = SiteSetting.displayed_invitees_limit)
-      self.invitees
+      going = self.invitees
         .order([:status, :user_id])
         .limit(limit)
-    end
 
-    def publish_update!
-      self.post.publish_message!("/discourse-post-event/#{self.post.topic_id}", id: self.id)
-    end
+      if self.private? && going.count < limit
+        # invitees are only created when an attendance is set
+        # so we create a dummy invitee object with only what's needed for serializer
+        going = going + GroupUser
+          .includes(:group, :user)
+          .where('groups.name' => self.raw_invitees)
+          .where.not('users.id' => going.pluck(:user_id))
+          .limit(limit - going.count)
+          .map { |gu| Invitee.new(user: gu.user, post_id: self.id) }
+      end
 
-    def destroy_extraneous_invitees!
-      self.invitees.where.not(user_id: fetch_users.select(:id)).delete_all
+      going
     end
 
-    def fill_invitees!
-      invited_users_ids = fetch_users.pluck(:id) - self.invitees.pluck(:user_id)
-      if invited_users_ids.present?
-        self.create_invitees(invited_users_ids.map { |user_id|
-          { user_id: user_id }
-        })
-      end
+    def publish_update!
+      self.post.publish_message!("/discourse-post-event/#{self.post.topic_id}", id: self.id)
     end
 
     def fetch_users
       @fetched_users ||= Invitee.extract_uniq_usernames(self.raw_invitees)
     end
 
-    def enforce_raw_invitees!
-      self.destroy_extraneous_invitees!
-      self.fill_invitees!
+    def enforce_private_invitees!
+      self.invitees.where.not(user_id: fetch_users.select(:id)).delete_all
       self.notify_invitees!(auto: false)
     end
 
     def can_user_update_attendance(user)
       !self.is_expired? &&
       (
-        self.status == Event.statuses[:public] ||
+        self.public? ||
         (
-          self.status == Event.statuses[:private] &&
-          self.invitees.exists?(user_id: user.id)
+          self.private? &&
+          (
+            self.invitees.exists?(user_id: user.id) ||
+            (user.groups.pluck(:name) & self.raw_invitees).any?
+          )
         )
       )
     end
@@ -251,7 +253,7 @@ module DiscoursePostEvent
       when Event.statuses[:private]
         raw_invitees = Array(params[:raw_invitees]) - ['trust_level_0']
         self.update!(params.merge(raw_invitees: raw_invitees))
-        self.enforce_raw_invitees!
+        self.enforce_private_invitees!
       when Event.statuses[:public]
         self.update!(params.merge(raw_invitees: ['trust_level_0']))
       when Event.statuses[:standalone]
diff --git a/app/serializers/discourse_post_event/event_serializer.rb b/app/serializers/discourse_post_event/event_serializer.rb
index e17c718..0ccdb5d 100644
--- a/app/serializers/discourse_post_event/event_serializer.rb
+++ b/app/serializers/discourse_post_event/event_serializer.rb
@@ -113,7 +113,7 @@ module DiscoursePostEvent
     end
 
     def should_display_invitees
-      object.status != Event.statuses[:standalone] && object.invitees.count > 0
+      (object.public? && object.invitees.count > 0) || (object.private? && object.raw_invitees.count > 0)
     end
   end
 end
diff --git a/jobs/regular/discourse_post_event/bulk_invite.rb b/jobs/regular/discourse_post_event/bulk_invite.rb
index 934362b..5f919f7 100644
--- a/jobs/regular/discourse_post_event/bulk_invite.rb
+++ b/jobs/regular/discourse_post_event/bulk_invite.rb
@@ -56,7 +56,7 @@ module Jobs
         group = Group.find_by(name: invitee['identifier'])
         if group
           users = group.users.pluck(:id)
-          @event.update!(raw_invitees: (@event.raw_invitees || []).push(group.name).uniq)
+          @event.update_with_params!(raw_invitees: (@event.raw_invitees || []).push(group.name).uniq)
         end
       end
 
diff --git a/spec/acceptance/post_spec.rb b/spec/acceptance/post_spec.rb
index 2887ddb..07bbef7 100644
--- a/spec/acceptance/post_spec.rb
+++ b/spec/acceptance/post_spec.rb
@@ -54,7 +54,7 @@ describe Post do
 
         context 'when in edit grace period' do
           before do
-            post_1.reload.event.update!(starts_at: 2.hours.ago)
+            post_1.reload.event.update_with_params!(starts_at: 2.hours.ago)
           end
 
           it 'sends a post revision to going invitees' do
@@ -75,7 +75,7 @@ describe Post do
 
         context 'when not edit grace period' do
           before do
-            post_1.reload.event.update!(starts_at: 5.hours.ago)
+            post_1.reload.event.update_with_params!(starts_at: 5.hours.ago)
           end
 
           it 'doesn’t send a post revision to anyone' do
diff --git a/spec/models/discourse_post_event/event_spec.rb b/spec/models/discourse_post_event/event_spec.rb
index a7824b4..8550d30 100644
--- a/spec/models/discourse_post_event/event_spec.rb
+++ b/spec/models/discourse_post_event/event_spec.rb
@@ -164,7 +164,7 @@ describe DiscoursePostEvent::Event do
             expect(first_post.is_first_post?).to be(true)
             expect(first_post.topic.custom_fields[Field]).to eq(starts_at)
 
-            post_event.update!(starts_at: alt_starts_at)
+            post_event.update_with_params!(starts_at: alt_starts_at)
             first_post.topic.reload
 
             expect(first_post.topic.custom_fields[Field]).to eq(alt_starts_at)
@@ -178,7 +178,7 @@ describe DiscoursePostEvent::Event do
             expect(second_post.is_first_post?).to be(false)
             expect(second_post.topic.custom_fields[Field]).to be_blank
 
-            post_event.update!(starts_at: alt_starts_at)
+            post_event.update_with_params!(starts_at: alt_starts_at)
             second_post.topic.reload
 
             expect(second_post.topic.custom_fields[Field]).to be_blank
diff --git a/spec/requests/events_controller_spec.rb b/spec/requests/events_controller_spec.rb
index 8a8dab2..38fa9ec 100644
--- a/spec/requests/events_controller_spec.rb
+++ b/spec/requests/events_controller_spec.rb
@@ -157,7 +157,7 @@ module DiscoursePostEvent
 
           context 'when status changes from standalone to private' do
             it 'changes the status, raw_invitees and invitees' do
-              event.update!(status: Event.statuses[:standalone])
+              event.update_with_params!(status: Event.statuses[:standalone])
 
               put "/discourse-post-event/events/#{event.id}.json", params: {
                 event: {
@@ -170,13 +170,13 @@ module DiscoursePostEvent
 
               expect(event.status).to eq(Event.statuses[:private])
               expect(event.raw_invitees).to eq([group.name])
-              expect(event.invitees.pluck(:user_id)).to match_array(group.group_users.map { |gu| gu.user.id })
+              expect(event.invitees).to eq([])
             end
           end
 
           context 'when status changes from standalone to public' do
             it 'changes the status' do
-              event.update!(status: Event.statuses[:standalone])
+              event.update_with_params!(status: Event.statuses[:standalone])
 
               put "/discourse-post-event/events/#{event.id}.json", params: {
                 event: {
@@ -194,15 +194,14 @@ module DiscoursePostEvent
 
           context 'when status changes from private to standalone' do
             it 'changes the status' do
-              event.update!(
+              event.update_with_params!(
                 status: Event.statuses[:private],
                 raw_invitees: [group.name]
               )
-              event.fill_invitees!
 
               event.reload
 
-              expect(event.invitees.pluck(:user_id)).to match_array(group.group_users.map { |gu| gu.user.id })

[... diff too long, it was truncated ...]

GitHub sha: 86dbc7d2

I am surprised public? and private? are not reserved in Ruby.

2 Likes