FEATURE: Send notification when member was accepted to group. (#7614)

FEATURE: Send notification when member was accepted to group. (#7614)

diff --git a/app/assets/javascripts/discourse-common/lib/icon-library.js.es6 b/app/assets/javascripts/discourse-common/lib/icon-library.js.es6
index 9821368..726b49c 100644
--- a/app/assets/javascripts/discourse-common/lib/icon-library.js.es6
+++ b/app/assets/javascripts/discourse-common/lib/icon-library.js.es6
@@ -35,7 +35,8 @@ const REPLACEMENTS = {
   "notification.topic_reminder": "far-clock",
   "notification.watching_first_post": "far-dot-circle",
   "notification.group_message_summary": "users",
-  "notification.post_approved": "check"
+  "notification.post_approved": "check",
+  "notification.membership_request_accepted": "user-plus"
 };
 
 // TODO: use lib/svg_sprite/fa4-renames.json here
diff --git a/app/assets/javascripts/discourse/widgets/membership-request-accepted-notification-item.js.es6 b/app/assets/javascripts/discourse/widgets/membership-request-accepted-notification-item.js.es6
new file mode 100644
index 0000000..de5d2ef
--- /dev/null
+++ b/app/assets/javascripts/discourse/widgets/membership-request-accepted-notification-item.js.es6
@@ -0,0 +1,19 @@
+import { createWidgetFrom } from "discourse/widgets/widget";
+import { DefaultNotificationItem } from "discourse/widgets/default-notification-item";
+import { groupPath } from "discourse/lib/url";
+
+createWidgetFrom(
+  DefaultNotificationItem,
+  "membership-request-accepted-notification-item",
+  {
+    url(data) {
+      return groupPath(data.group_name);
+    },
+
+    text(notificationName, data) {
+      return I18n.t(`notifications.${notificationName}`, {
+        group_name: data.group_name
+      });
+    }
+  }
+);
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index d1cad42..4746262 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -351,7 +351,7 @@ class GroupsController < ApplicationController
       raise Discourse::InvalidParameters.new(:user_id) if user.blank?
 
       if params[:accept]
-        group.add(user)
+        group.add(user, notify: true)
         GroupActionLogger.new(current_user, group).log_add_user_to_group(user)
       end
 
diff --git a/app/models/group.rb b/app/models/group.rb
index 9251524..f4bf49a 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -541,9 +541,20 @@ class Group < ActiveRecord::Base
 
   PUBLISH_CATEGORIES_LIMIT = 10
 
-  def add(user)
+  def add(user, notify: false)
     self.users.push(user) unless self.users.include?(user)
 
+    if notify
+      Notification.create!(
+        notification_type: Notification.types[:membership_request_accepted],
+        user_id: user.id,
+        data: {
+          group_id: id,
+          group_name: name
+        }.to_json
+      )
+    end
+
     if self.categories.count < PUBLISH_CATEGORIES_LIMIT
       MessageBus.publish('/categories', {
         categories: ActiveModel::ArraySerializer.new(self.categories).as_json
diff --git a/app/models/notification.rb b/app/models/notification.rb
index ab420cb..fdfd006 100644
--- a/app/models/notification.rb
+++ b/app/models/notification.rb
@@ -64,7 +64,8 @@ class Notification < ActiveRecord::Base
                         topic_reminder: 18,
                         liked_consolidated: 19,
                         post_approved: 20,
-                        code_review_commit_approved: 21
+                        code_review_commit_approved: 21,
+                        membership_request_accepted: 22
                        )
   end
 
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 63323fa..f0e8a4f 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -1730,6 +1730,7 @@ en:
       granted_badge: "Earned '{{description}}'"
       topic_reminder: "<span>{{username}}</span> {{description}}"
       watching_first_post: "<span>New Topic</span> {{description}}"
+      membership_request_accepted: "Membership accepted in '{{group_name}}'"
 
       group_message_summary:
         one: "{{count}} message in your {{group_name}} inbox"
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index 42cc6ee..68656b1 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -766,6 +766,14 @@ describe Group do
         .and change { user.title }.from('AAAA').to('BBBB')
     end
 
+    it "can send a notification to the user" do
+      expect { group.add(user, notify: true) }.to change { Notification.count }.by(1)
+
+      notification = Notification.last
+      expect(notification.notification_type).to eq(Notification.types[:membership_request_accepted])
+      expect(notification.user_id).to eq(user.id)
+    end
+
     context 'when adding a user into a public group' do
       fab!(:category) { Fabricate(:category) }
 
diff --git a/test/javascripts/fixtures/notification_fixtures.js.es6 b/test/javascripts/fixtures/notification_fixtures.js.es6
index 071df77..9ab4d8d 100644
--- a/test/javascripts/fixtures/notification_fixtures.js.es6
+++ b/test/javascripts/fixtures/notification_fixtures.js.es6
@@ -18,6 +18,38 @@ export default {
         notification_type: NOTIFICATION_TYPES.liked_consolidated,
         read: false,
         data: { display_username: "aquaman", count: "5" }
+      },
+      {
+        id: 789,
+        notification_type: NOTIFICATION_TYPES.group_message_summary,
+        read: false,
+        post_number: null,
+        topic_id: null,
+        slug: null,
+        data: {
+          group_id: 41,
+          group_name: "test",
+          inbox_count: 5,
+          username: "test2"
+        }
+      },
+      {
+        id: 1234,
+        notification_type: NOTIFICATION_TYPES.invitee_accepted,
+        read: false,
+        post_number: null,
+        topic_id: null,
+        slug: null,
+        data: { display_username: "test1" }
+      },
+      {
+        id: 5678,
+        notification_type: NOTIFICATION_TYPES.membership_request_accepted,
+        read: false,
+        post_number: null,
+        topic_id: null,
+        slug: null,
+        data: { group_id: 41, group_name: "test" }
       }
     ]
   }
diff --git a/test/javascripts/widgets/user-menu-test.js.es6 b/test/javascripts/widgets/user-menu-test.js.es6
index a878a47..66abb7c 100644
--- a/test/javascripts/widgets/user-menu-test.js.es6
+++ b/test/javascripts/widgets/user-menu-test.js.es6
@@ -21,7 +21,7 @@ widgetTest("notifications", {
   test(assert) {
     const $links = find(".notifications li a");
 
-    assert.equal($links.length, 2);
+    assert.equal($links.length, 5);
     assert.ok($links[0].href.includes("/t/a-slug/123"));
 
     assert.ok(
@@ -36,6 +36,32 @@ widgetTest("notifications", {
         count: 5
       })}`
     );
+
+    assert.ok($links[2].href.includes("/u/test2/messages/group/test"));
+    assert.ok(
+      $links[2].innerHTML.includes(
+        I18n.t("notifications.group_message_summary", {
+          count: 5,
+          group_name: "test"
+        })
+      )
+    );
+
+    assert.ok($links[3].href.includes("/u/test1"));
+    assert.ok(
+      $links[3].innerHTML.includes(
+        I18n.t("notifications.invitee_accepted", { username: "test1" })
+      )
+    );
+
+    assert.ok($links[4].href.includes("/g/test"));
+    assert.ok(
+      $links[4].innerHTML.includes(
+        I18n.t("notifications.membership_request_accepted", {
+          group_name: "test"
+        })
+      )
+    );
   }
 });

GitHub sha: 37e7998a