From 707769340d1e6341f4793d2507c138e13dd1e168 Mon Sep 17 00:00:00 2001
From: Lindsey Shelton <lshelton@gitlab.com>
Date: Wed, 25 Sep 2024 06:21:01 +0000
Subject: [PATCH] Initial commit for hide duo chat

Modifying show to include only  groups and project pages

Changelog: fixed
---
 .../layouts/nav/_ask_duo_button.html.haml     |  2 +-
 ee/lib/gitlab/llm/tanuki_bot.rb               |  4 +-
 ee/spec/features/duo_chat_spec.rb             | 64 +++++++++++--------
 ee/spec/features/tanuki_bot_chat_spec.rb      |  6 +-
 ee/spec/lib/gitlab/llm/tanuki_bot_spec.rb     | 22 +++++--
 .../16_ai_powered/duo_chat/duo_chat_spec.rb   |  3 +
 6 files changed, 62 insertions(+), 39 deletions(-)

diff --git a/ee/app/views/layouts/nav/_ask_duo_button.html.haml b/ee/app/views/layouts/nav/_ask_duo_button.html.haml
index ccfb1296a98f3..2642d9b9feac0 100644
--- a/ee/app/views/layouts/nav/_ask_duo_button.html.haml
+++ b/ee/app/views/layouts/nav/_ask_duo_button.html.haml
@@ -1,4 +1,4 @@
-- if ::Gitlab::Llm::TanukiBot.show_breadcrumbs_entry_point?(user: current_user)
+- if ::Gitlab::Llm::TanukiBot.show_breadcrumbs_entry_point?(user: current_user, container: @group || @project)
   - label = s_('DuoChat|GitLab Duo Chat')
   - chat_disabled_reason = ::Gitlab::Llm::TanukiBot.chat_disabled_reason(user: current_user, container: @group || @project).to_s
 
diff --git a/ee/lib/gitlab/llm/tanuki_bot.rb b/ee/lib/gitlab/llm/tanuki_bot.rb
index 77422c59780ec..d2343e230461c 100644
--- a/ee/lib/gitlab/llm/tanuki_bot.rb
+++ b/ee/lib/gitlab/llm/tanuki_bot.rb
@@ -15,8 +15,8 @@ def self.enabled_for?(user:, container: nil)
         authorizer_response.allowed?
       end
 
-      def self.show_breadcrumbs_entry_point?(user:)
-        return false unless chat_enabled?(user)
+      def self.show_breadcrumbs_entry_point?(user:, container: nil)
+        return false unless chat_enabled?(user) && container
 
         Gitlab::Llm::Chain::Utils::ChatAuthorizer.user(user: user).allowed?
       end
diff --git a/ee/spec/features/duo_chat_spec.rb b/ee/spec/features/duo_chat_spec.rb
index 8f935ff1c49a0..6ef503f6f4cc4 100644
--- a/ee/spec/features/duo_chat_spec.rb
+++ b/ee/spec/features/duo_chat_spec.rb
@@ -15,7 +15,7 @@
 
     before do
       sign_in(user)
-      visit root_path
+      visit group_path(group)
     end
 
     it 'does not show the button to open chat' do
@@ -24,9 +24,12 @@
   end
 
   context 'when group has an AI features license', :sidekiq_inline do
+    using RSpec::Parameterized::TableSyntax
+
     include_context 'with duo features enabled and ai chat available for group on SaaS'
 
     let_it_be_with_reload(:group) { create(:group_with_plan, plan: :premium_plan) }
+    let_it_be(:project) { create(:project, namespace: group) }
 
     let(:question) { 'Who are you?' }
     let(:answer) { "Hello! I'm GitLab Duo Chat" }
@@ -41,37 +44,44 @@
 
       sign_in(user)
 
-      visit root_path
+      visit group_path(group)
     end
 
-    it 'shows the disabled button with project tooltip when chat is disabled on project level' do
-      allow(::Gitlab::Llm::TanukiBot).to receive(:chat_disabled_reason).and_return('project')
-
-      visit root_path
-
-      expect(page).to have_selector(
-        'span.has-tooltip[title*="An administrator has turned off GitLab Duo for this project"]'
-      )
-      expect(page).to have_button('GitLab Duo Chat', disabled: true)
+    where(:disabled_reason, :visit_path, :expected_button_state, :expected_tooltip) do
+      'project' | :visit_project | :disabled | "An administrator has turned off GitLab Duo for this project"
+      'project' | :visit_root | :hidden | nil
+      'group' | :visit_group | :disabled | "An administrator has turned off GitLab Duo for this group"
+      'group' | :visit_root | :hidden | nil
+      nil | :visit_group | :enabled | nil
+      nil | :visit_project | :enabled | nil
+      nil | :visit_root | :hidden | nil
     end
 
-    it 'shows the disabled button with group tooltip when chat is disabled on group level' do
-      allow(::Gitlab::Llm::TanukiBot).to receive(:chat_disabled_reason).and_return('group')
-
-      visit root_path
-
-      expect(page).to have_selector(
-        'span.has-tooltip[title*="An administrator has turned off GitLab Duo for this group"]'
-      )
-      expect(page).to have_button('GitLab Duo Chat', disabled: true)
-    end
-
-    it 'shows the enabled button when chat is enabled' do
-      allow(::Gitlab::Llm::TanukiBot).to receive(:chat_disabled_reason).and_return(nil)
-
-      visit root_path
+    with_them do
+      it 'shows the correct button state and tooltip' do
+        allow(::Gitlab::Llm::TanukiBot).to receive(:chat_disabled_reason).and_return(disabled_reason)
+
+        case visit_path
+        when :visit_group
+          visit group_path(group)
+        when :visit_project
+          visit project_path(project)
+        when :visit_root
+          visit root_path
+        end
 
-      expect(page).to have_button('GitLab Duo Chat', disabled: false)
+        case expected_button_state
+        when :disabled
+          expect(page).to have_selector(
+            "span.has-tooltip[title*=\"#{expected_tooltip}\"]"
+          )
+          expect(page).to have_button('GitLab Duo Chat', disabled: true)
+        when :enabled
+          expect(page).to have_button('GitLab Duo Chat', disabled: false)
+        when :hidden
+          expect(page).not_to have_button('GitLab Duo Chat')
+        end
+      end
     end
 
     it 'returns response after asking a question', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/462444' do
diff --git a/ee/spec/features/tanuki_bot_chat_spec.rb b/ee/spec/features/tanuki_bot_chat_spec.rb
index 8a5beec80abb5..ccd6927e116c3 100644
--- a/ee/spec/features/tanuki_bot_chat_spec.rb
+++ b/ee/spec/features/tanuki_bot_chat_spec.rb
@@ -20,7 +20,7 @@
       include_context 'with ai features enabled for group'
 
       before do
-        visit root_path
+        visit group_path(group)
       end
 
       shared_examples 'GitLab Duo drawer' do
@@ -46,6 +46,8 @@
   end
 
   context 'for self-managed', :with_cloud_connector do
+    let_it_be_with_reload(:group) { create(:group) }
+
     before do
       sign_in(user)
     end
@@ -54,7 +56,7 @@
       include_context 'with duo features enabled and ai chat available for self-managed'
 
       before do
-        visit root_path
+        visit group_path(group)
       end
 
       shared_examples 'GitLab Duo drawer' do
diff --git a/ee/spec/lib/gitlab/llm/tanuki_bot_spec.rb b/ee/spec/lib/gitlab/llm/tanuki_bot_spec.rb
index 2ddf65045ef18..e4b7e87091816 100644
--- a/ee/spec/lib/gitlab/llm/tanuki_bot_spec.rb
+++ b/ee/spec/lib/gitlab/llm/tanuki_bot_spec.rb
@@ -70,21 +70,29 @@
       allow(described_class).to receive(:chat_enabled?).with(user)
                                                        .and_return(ai_features_enabled_for_user)
       allow(Gitlab::Llm::Chain::Utils::ChatAuthorizer).to receive(:user).with(user: user)
-                                                                        .and_return(authorizer_response)
+                                                                                 .and_return(authorizer_response)
     end
 
-    where(:ai_features_enabled_for_user, :allowed, :result) do
+    where(:container, :ai_features_enabled_for_user, :allowed, :result) do
       [
-        [true, true, true],
-        [true, false, false],
-        [false, false, false],
-        [false, true, false]
+        [:project, true, true, true],
+        [:project, true, false, false],
+        [:project, false, false, false],
+        [:project, false, true, false],
+        [:group, true, true, true],
+        [:group, true, false, false],
+        [:group, false, false, false],
+        [:group, false, true, false],
+        [nil, true, true, false],
+        [nil, true, false, false],
+        [nil, false, false, false],
+        [nil, false, true, false]
       ]
     end
 
     with_them do
       it 'returns correct result' do
-        expect(described_class.show_breadcrumbs_entry_point?(user: user)).to be(result)
+        expect(described_class.show_breadcrumbs_entry_point?(user: user, container: container)).to be(result)
       end
     end
   end
diff --git a/qa/qa/specs/features/ee/browser_ui/16_ai_powered/duo_chat/duo_chat_spec.rb b/qa/qa/specs/features/ee/browser_ui/16_ai_powered/duo_chat/duo_chat_spec.rb
index 5ee5e73215de4..f2cf2a4038246 100644
--- a/qa/qa/specs/features/ee/browser_ui/16_ai_powered/duo_chat/duo_chat_spec.rb
+++ b/qa/qa/specs/features/ee/browser_ui/16_ai_powered/duo_chat/duo_chat_spec.rb
@@ -4,6 +4,8 @@ module QA
   # https://docs.gitlab.com/ee/development/ai_features/duo_chat.html
   RSpec.describe 'Ai-powered', product_group: :duo_chat do
     describe 'Duo Chat' do
+      let(:project) { create(:project, name: 'duo-chat-project') }
+
       shared_examples 'Duo Chat' do |testcase|
         it 'gets a response back from Duo Chat', testcase: testcase do
           QA::EE::Page::Component::DuoChat.perform do |duo_chat|
@@ -23,6 +25,7 @@ module QA
 
       before do
         Flow::Login.sign_in
+        project.visit!
       end
 
       context 'when initiating Duo Chat' do
-- 
GitLab