FIX: sends event creation's notification to all potential invitees

FIX: sends event creation’s notification to all potential invitees

When in private event, we don’t create invitees, although we know the list of people who can join, send an invite to this list.

Also fixes the total count of users on private events.

diff --git a/app/models/discourse_post_event/event.rb b/app/models/discourse_post_event/event.rb
index ade8f55..94488e3 100644
--- a/app/models/discourse_post_event/event.rb
+++ b/app/models/discourse_post_event/event.rb
@@ -46,6 +46,12 @@ module DiscoursePostEvent
 
       ends_at_changes = saved_change_to_ends_at
       self.refresh_ends_at_handlers!(ends_at_changes) if ends_at_changes
+
+      if starts_at_changes
+        self.invitees.update_all(status: nil, notified: false)
+        self.notify_invitees!
+        self.notify_missing_invitees!
+      end
     end
 
     has_many :invitees, foreign_key: :post_id, dependent: :delete_all
@@ -136,7 +142,7 @@ module DiscoursePostEvent
     end
 
     def notify_invitees!(predefined_attendance: false)
-      self.invitees.where(notified: false).each do |invitee|
+      self.invitees.where(notified: false).find_each do |invitee|
         create_notification!(
           invitee.user,
           self.post,
@@ -146,6 +152,14 @@ module DiscoursePostEvent
       end
     end
 
+    def notify_missing_invitees!
+      if self.private?
+        self.missing_group_users.each do |group_user|
+          create_notification!(group_user.user, self.post)
+        end
+      end
+    end
+
     def create_notification!(user, post, predefined_attendance: false)
       message =
         if predefined_attendance
@@ -213,7 +227,6 @@ module DiscoursePostEvent
 
     def enforce_private_invitees!
       self.invitees.where.not(user_id: fetch_users.select(:id)).delete_all
-      self.notify_invitees!(predefined_attendance: false)
     end
 
     def can_user_update_attendance(user)
@@ -263,6 +276,13 @@ module DiscoursePostEvent
       end
     end
 
+    def missing_group_users
+      GroupUser
+        .joins(:group, :user)
+        .where('groups.name' => self.raw_invitees)
+        .where.not('users.id' => self.invitees.select(:user_id))
+    end
+
     def update_with_params!(params)
       params[:custom_fields] =
         (params[:custom_fields] || {}).reject { |_, value| value.blank? }
diff --git a/app/serializers/discourse_post_event/event_serializer.rb b/app/serializers/discourse_post_event/event_serializer.rb
index db987b2..fbdf932 100644
--- a/app/serializers/discourse_post_event/event_serializer.rb
+++ b/app/serializers/discourse_post_event/event_serializer.rb
@@ -91,11 +91,7 @@ module DiscoursePostEvent
       # when a group is private we know the list of possible users
       # even if an invitee has not been created yet
       if object.private?
-        unanswered += GroupUser
-          .includes(:group, :user)
-          .where('groups.name' => object.raw_invitees)
-          .where.not('users.id' => object.invitees.select(:user_id))
-          .count
+        unanswered += object.missing_group_users.count
       end
 
       {
diff --git a/plugin.rb b/plugin.rb
index 0b60e6f..3e51cda 100644
--- a/plugin.rb
+++ b/plugin.rb
@@ -611,8 +611,6 @@ after_initialize do
         next_ends_at = next_starts_at + difference.seconds
 
         event.update!(starts_at: next_starts_at, ends_at: next_ends_at)
-        event.invitees.update_all(status: nil, notified: false)
-        event.notify_invitees!
         event.publish_update!
       end
     end
diff --git a/spec/acceptance/post_spec.rb b/spec/acceptance/post_spec.rb
index d68249e..1e8ea3e 100644
--- a/spec/acceptance/post_spec.rb
+++ b/spec/acceptance/post_spec.rb
@@ -16,416 +16,465 @@ describe Post do
   end
 
   let(:user) { Fabricate(:user, admin: true) }
-  let(:topic) { Fabricate(:topic, user: user) }
-  let(:post1) { Fabricate(:post, topic: topic) }
-  let!(:post_event) do
-    Fabricate(:event, post: post1, status: Event.statuses[:public])
-  end
-
-  context 'when a post is updated' do
-    context 'when the post has a valid event' do
-      context 'when the event markup is removed' do
-        it 'destroys the associated event' do
-          start = Time.now.utc.iso8601(3)
 
-          post = create_post_with_event(user)
+  context 'public event' do
+    let(:post_1) { Fabricate(:post) }
+    let(:event_1) { Fabricate(:event, post: post_1) }
 
-          expect(post.reload.event.persisted?).to eq(true)
+    context 'when a post is updated' do
+      context 'when the post has a valid event' do
+        context 'when the event markup is removed' do
+          it 'destroys the associated event' do
+            start = Time.now.utc.iso8601(3)
 
-          revisor = PostRevisor.new(post, post.topic)
-          revisor.revise!(
-            user,
-            raw: 'The event is over. Come back another day.'
-          )
+            post = create_post_with_event(user)
 
-          expect(post.reload.event).to be(nil)
-        end
-      end
+            expect(post.reload.event.persisted?).to eq(true)
 
-      context 'when event is on going' do
-        let(:going_user) { Fabricate(:user) }
-        let(:interested_user) { Fabricate(:user) }
-        let(:post_1) { create_post_with_event(user) }
-
-        before do
-          SiteSetting.editing_grace_period = 1.minute
-          PostActionNotifier.enable
-          SiteSetting.discourse_post_event_edit_notifications_time_extension =
-            180
-        end
-
-        context 'when in edit grace period' do
-          before do
-            post_1.reload.event.update_with_params!(
-              starts_at: 3.hours.ago, ends_at: 2.hours.ago
-            )
-          end
-
-          it 'sends a post revision to going invitees' do
-            Invitee.create_attendance!(going_user.id, post_1.id, :going)
-            Invitee.create_attendance!(
-              interested_user.id,
-              post_1.id,
-              :interested
-            )
-
-            revisor = PostRevisor.new(post_1)
+            revisor = PostRevisor.new(post, post.topic)
             revisor.revise!(
               user,
-              { raw: post_1.raw + "\nWe are bout half way into our event!" },
-              revised_at: Time.now + 2.minutes
+              raw: 'The event is over. Come back another day.'
             )
 
-            expect(going_user.notifications.count).to eq(1)
-            expect(interested_user.notifications.count).to eq(0)
+            expect(post.reload.event).to be(nil)
           end
         end
 
-        context 'when not edit grace period' do
+        context 'when event is on going' do
+          let(:going_user) { Fabricate(:user) }
+          let(:interested_user) { Fabricate(:user) }
+
           before do
-            post_1.reload.event.update_with_params!(starts_at: 5.hours.ago)
+            SiteSetting.editing_grace_period = 1.minute
+            PostActionNotifier.enable
+            SiteSetting.discourse_post_event_edit_notifications_time_extension =
+              180
           end
 
-          it 'doesn’t send a post revision to anyone' do
-            Invitee.create_attendance!(going_user.id, post_1.id, :going)
-            Invitee.create_attendance!(
-              interested_user.id,
-              post_1.id,
-              :interested
-            )
-
-            revisor = PostRevisor.new(post_1)
-            revisor.revise!(
-              user,
-              { raw: post_1.raw + "\nWe are bout half way into our event!" },
-              revised_at: Time.now + 2.minutes
-            )
+          context 'when in edit grace period' do
+            before do
+              event_1.update_with_params!(
+                starts_at: 3.hours.ago, ends_at: 2.hours.ago
+              )
 
-            expect(going_user.notifications.count).to eq(0)
-            expect(interested_user.notifications.count).to eq(0)
-          end
-        end
+              # clean state
+              Notification.destroy_all
+              interested_user.reload
+              going_user.reload
+            end
 
-        context 'an event with recurrence' do
-          let(:event_1) do
-            create_post_with_event(user, 'recurrence=FREQ=WEEKLY;BYDAY=MO')
-              .event

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

GitHub sha: 2399624f