diff --git a/app/services/search/global_service.rb b/app/services/search/global_service.rb
index 8409b592b72f262e9c4c53db795ae164e77d7672..ff188102b621634a4aeac32275e1597bfafcbde9 100644
--- a/app/services/search/global_service.rb
+++ b/app/services/search/global_service.rb
@@ -7,16 +7,13 @@ def initialize(user, params)
     end
 
     def execute
-      group = Group.find_by(id: params[:group_id]) if params[:group_id].present?
-      projects = ProjectsFinder.new(current_user: current_user).execute
-
-      if group
-        projects = projects.inside_path(group.full_path)
-      end
-
       Gitlab::SearchResults.new(current_user, projects, params[:search])
     end
 
+    def projects
+      @projects ||= ProjectsFinder.new(current_user: current_user).execute
+    end
+
     def scope
       @scope ||= begin
         allowed_scopes = %w[issues merge_requests milestones]
diff --git a/app/services/search/group_service.rb b/app/services/search/group_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..29478e3251f39161939ac4d39a49b9a01f109a8f
--- /dev/null
+++ b/app/services/search/group_service.rb
@@ -0,0 +1,18 @@
+module Search
+  class GroupService < Search::GlobalService
+    attr_accessor :group
+
+    def initialize(user, group, params)
+      super(user, params)
+
+      @group = group
+    end
+
+    def projects
+      return Project.none unless group
+      return @projects if defined? @projects
+
+      @projects = super.inside_path(group.full_path)
+    end
+  end
+end
diff --git a/app/services/search_service.rb b/app/services/search_service.rb
index 8d46a8dab3e0738afe231cc38f1b36378ccf8839..22736c717254967095d5053524e626280afe7443 100644
--- a/app/services/search_service.rb
+++ b/app/services/search_service.rb
@@ -54,6 +54,8 @@ def search_service
         Search::ProjectService.new(project, current_user, params)
       elsif show_snippets?
         Search::SnippetService.new(current_user, params)
+      elsif group
+        Search::GroupService.new(current_user, group, params)
       else
         Search::GlobalService.new(current_user, params)
       end
diff --git a/spec/services/search/global_service_spec.rb b/spec/services/search/global_service_spec.rb
index 2531607acad700bd43d8f9c20d075c5969e38148..cbf4f56213da7a38dc31b966aef96c7574e9254d 100644
--- a/spec/services/search/global_service_spec.rb
+++ b/spec/services/search/global_service_spec.rb
@@ -40,27 +40,6 @@
 
         expect(results.objects('projects')).to match_array [found_project]
       end
-
-      context 'nested group' do
-        let!(:nested_group) { create(:group, :nested) }
-        let!(:project) { create(:empty_project, namespace: nested_group) }
-
-        before do
-          project.add_master(user)
-        end
-
-        it 'returns result from nested group' do
-          results = Search::GlobalService.new(user, search: project.path).execute
-
-          expect(results.objects('projects')).to match_array [project]
-        end
-
-        it 'returns result from descendants when search inside group' do
-          results = Search::GlobalService.new(user, search: project.path, group_id: nested_group.parent).execute
-
-          expect(results.objects('projects')).to match_array [project]
-        end
-      end
     end
   end
 end
diff --git a/spec/services/search/group_service_spec.rb b/spec/services/search/group_service_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..38f264f6e7b982a0968d2cb7e90aac40b7cedaa0
--- /dev/null
+++ b/spec/services/search/group_service_spec.rb
@@ -0,0 +1,40 @@
+require 'spec_helper'
+
+describe Search::GroupService, services: true do
+  shared_examples_for 'group search' do
+    context 'finding projects by name' do
+      let(:user) { create(:user) }
+      let(:term) { "Project Name" }
+      let(:nested_group) { create(:group, :nested) }
+
+      # These projects shouldn't be found
+      let!(:outside_project) { create(:empty_project, :public, name: "Outside #{term}") }
+      let!(:private_project) { create(:empty_project, :private, namespace: nested_group, name: "Private #{term}" )}
+      let!(:other_project)   { create(:empty_project, :public, namespace: nested_group, name: term.reverse) }
+
+      # These projects should be found
+      let!(:project1) { create(:empty_project, :internal, namespace: nested_group, name: "Inner #{term} 1") }
+      let!(:project2) { create(:empty_project, :internal, namespace: nested_group, name: "Inner #{term} 2") }
+      let!(:project3) { create(:empty_project, :internal, namespace: nested_group.parent, name: "Outer #{term}") }
+
+      let(:results) { Search::GroupService.new(user, search_group, search: term).execute }
+      subject { results.objects('projects') }
+
+      context 'in parent group' do
+        let(:search_group) { nested_group.parent }
+
+        it { is_expected.to match_array([project1, project2, project3]) }
+      end
+
+      context 'in subgroup' do
+        let(:search_group) { nested_group }
+
+        it { is_expected.to match_array([project1, project2]) }
+      end
+    end
+  end
+
+  describe 'basic search' do
+    include_examples 'group search'
+  end
+end