From ef21450be7130acf9ce7577a6fb3180d5ecff75f Mon Sep 17 00:00:00 2001
From: Joffrey JAFFEUX <j.jaffeux@gmail.com>
Date: Fri, 14 Jul 2023 08:26:18 +0200
Subject: [PATCH] FIX: redirects to browse after removing last followed
 (#22563)

Prior to this change you might end up in a loop where removing a channel would redirect you to this channel and as we auto-follow opened direct message channels, you could never unfollow this last direct message channel.
---
 .../javascripts/discourse/services/chat.js    |  4 ++
 .../system/page_objects/sidebar/sidebar.rb    | 10 +++-
 .../chat/spec/system/removing_channel_spec.rb | 48 +++++++++++++++++++
 3 files changed, 60 insertions(+), 2 deletions(-)
 create mode 100644 plugins/chat/spec/system/removing_channel_spec.rb

diff --git a/plugins/chat/assets/javascripts/discourse/services/chat.js b/plugins/chat/assets/javascripts/discourse/services/chat.js
index cb79d938597..d3a03a70626 100644
--- a/plugins/chat/assets/javascripts/discourse/services/chat.js
+++ b/plugins/chat/assets/javascripts/discourse/services/chat.js
@@ -303,6 +303,10 @@ export default class Chat extends Service {
     this.chatChannelsManager.channels.forEach((channel) => {
       const membership = channel.currentUserMembership;
 
+      if (!membership.following) {
+        return;
+      }
+
       if (channel.isDirectMessageChannel) {
         if (!dmChannelWithUnread && channel.tracking.unreadCount > 0) {
           dmChannelWithUnread = channel.id;
diff --git a/plugins/chat/spec/system/page_objects/sidebar/sidebar.rb b/plugins/chat/spec/system/page_objects/sidebar/sidebar.rb
index 70de387e958..341970ad139 100644
--- a/plugins/chat/spec/system/page_objects/sidebar/sidebar.rb
+++ b/plugins/chat/spec/system/page_objects/sidebar/sidebar.rb
@@ -27,11 +27,17 @@ module PageObjects
       end
 
       def open_channel(channel)
-        find(".sidebar-section-link[href='/chat/c/#{channel.slug}/#{channel.id}']").click
+        find(".sidebar-section-link.channel-#{channel.id}").click
+      end
+
+      def remove_channel(channel)
+        selector = ".sidebar-section-link.channel-#{channel.id}"
+        find(selector).hover
+        find(selector + " .sidebar-section-hover-button").click
       end
 
       def find_channel(channel)
-        find(".sidebar-section-link[href='/chat/c/#{channel.slug}/#{channel.id}']")
+        find(".sidebar-section-link.channel-#{channel.id}")
         self
       end
     end
diff --git a/plugins/chat/spec/system/removing_channel_spec.rb b/plugins/chat/spec/system/removing_channel_spec.rb
new file mode 100644
index 00000000000..b52bdac3442
--- /dev/null
+++ b/plugins/chat/spec/system/removing_channel_spec.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+RSpec.describe "Removing channel", type: :system do
+  fab!(:current_user) { Fabricate(:user) }
+
+  let(:chat_page) { PageObjects::Pages::Chat.new }
+  let(:chat_sidebar_page) { PageObjects::Pages::Sidebar.new }
+
+  before do
+    chat_system_bootstrap
+    sign_in(current_user)
+  end
+
+  context "when removing last followed channel" do
+    fab!(:channel_1) { Fabricate(:chat_channel) }
+    fab!(:channel_2) { Fabricate(:direct_message_channel, users: [current_user, Fabricate(:user)]) }
+
+    before do
+      Fabricate(
+        :user_chat_channel_membership,
+        user: current_user,
+        chat_channel: channel_1,
+        following: false,
+      )
+    end
+
+    it "redirects to browse page" do
+      chat_page.visit_channel(channel_2)
+      chat_sidebar_page.remove_channel(channel_2)
+
+      expect(page).to have_current_path("/chat/browse/open")
+    end
+  end
+
+  context "when removing channel" do
+    fab!(:channel_1) { Fabricate(:chat_channel) }
+    fab!(:channel_2) { Fabricate(:direct_message_channel, users: [current_user, Fabricate(:user)]) }
+
+    before { channel_1.add(current_user) }
+
+    it "redirects to another followed channgel" do
+      chat_page.visit_channel(channel_2)
+      chat_sidebar_page.remove_channel(channel_2)
+
+      expect(page).to have_current_path(chat.channel_path(channel_1.slug, channel_1.id))
+    end
+  end
+end