From c5b3b71e89996ba4e6fb977e3cbb3eebfbbfed4e Mon Sep 17 00:00:00 2001
From: Heinrich Lee Yu <heinrich@gitlab.com>
Date: Wed, 27 Feb 2019 21:08:48 +0800
Subject: [PATCH] CE-port for 7714-view-recent-boards

Adds additional count param to Boards::Visits::LatestService
---
 app/models/board_group_recent_visit.rb        |  9 +++++---
 app/models/board_project_recent_visit.rb      |  9 +++++---
 app/services/boards/visits/latest_service.rb  | 12 +++++-----
 config/routes/group.rb                        |  2 +-
 config/routes/project.rb                      |  3 +--
 spec/models/board_group_recent_visit_spec.rb  | 22 ++++++++++++++-----
 .../models/board_project_recent_visit_spec.rb | 22 ++++++++++++++-----
 .../boards/visits/latest_service_spec.rb      | 12 ++++++++++
 8 files changed, 65 insertions(+), 26 deletions(-)

diff --git a/app/models/board_group_recent_visit.rb b/app/models/board_group_recent_visit.rb
index 92abbb672225..f5b75270595e 100644
--- a/app/models/board_group_recent_visit.rb
+++ b/app/models/board_group_recent_visit.rb
@@ -10,7 +10,7 @@ class BoardGroupRecentVisit < ActiveRecord::Base
   validates :group, presence: true
   validates :board, presence: true
 
-  scope :by_user_group, -> (user, group) { where(user: user, group: group).order(:updated_at) }
+  scope :by_user_group, -> (user, group) { where(user: user, group: group) }
 
   def self.visited!(user, board)
     visit = find_or_create_by(user: user, group: board.group, board: board)
@@ -19,7 +19,10 @@ def self.visited!(user, board)
     retry
   end
 
-  def self.latest(user, group)
-    by_user_group(user, group).last
+  def self.latest(user, group, count: nil)
+    visits = by_user_group(user, group).order(updated_at: :desc)
+    visits = visits.preload(:board) if count && count > 1
+
+    visits.first(count)
   end
 end
diff --git a/app/models/board_project_recent_visit.rb b/app/models/board_project_recent_visit.rb
index 7cffff906d8a..2a1b14b3ae0c 100644
--- a/app/models/board_project_recent_visit.rb
+++ b/app/models/board_project_recent_visit.rb
@@ -10,7 +10,7 @@ class BoardProjectRecentVisit < ActiveRecord::Base
   validates :project, presence: true
   validates :board,   presence: true
 
-  scope :by_user_project, -> (user, project) { where(user: user, project: project).order(:updated_at) }
+  scope :by_user_project, -> (user, project) { where(user: user, project: project) }
 
   def self.visited!(user, board)
     visit = find_or_create_by(user: user, project: board.project, board: board)
@@ -19,7 +19,10 @@ def self.visited!(user, board)
     retry
   end
 
-  def self.latest(user, project)
-    by_user_project(user, project).last
+  def self.latest(user, project, count: nil)
+    visits = by_user_project(user, project).order(updated_at: :desc)
+    visits = visits.preload(:board) if count && count > 1
+
+    visits.first(count)
   end
 end
diff --git a/app/services/boards/visits/latest_service.rb b/app/services/boards/visits/latest_service.rb
index 9e4c77a63174..d8de08c58443 100644
--- a/app/services/boards/visits/latest_service.rb
+++ b/app/services/boards/visits/latest_service.rb
@@ -6,11 +6,13 @@ class LatestService < Boards::BaseService
       def execute
         return nil unless current_user
 
-        if parent.is_a?(Group)
-          BoardGroupRecentVisit.latest(current_user, parent)
-        else
-          BoardProjectRecentVisit.latest(current_user, parent)
-        end
+        recent_visit_model.latest(current_user, parent, count: params[:count])
+      end
+
+      private
+
+      def recent_visit_model
+        parent.is_a?(Group) ? BoardGroupRecentVisit : BoardProjectRecentVisit
       end
     end
   end
diff --git a/config/routes/group.rb b/config/routes/group.rb
index a0aeebe4b91e..b3015529c6ec 100644
--- a/config/routes/group.rb
+++ b/config/routes/group.rb
@@ -67,7 +67,7 @@
       end
     end
 
-    resources :boards, only: [:index, :show]
+    resources :boards, only: [:index, :show], constraints: { id: /\d+/ }
 
     resources :runners, only: [:index, :edit, :update, :destroy, :show] do
       member do
diff --git a/config/routes/project.rb b/config/routes/project.rb
index b4ebc7df4fe7..d60a5cc9ae8a 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -394,8 +394,7 @@
 
       get 'noteable/:target_type/:target_id/notes' => 'notes#index', as: 'noteable_notes'
 
-      # On CE only index and show are needed
-      resources :boards, only: [:index, :show]
+      resources :boards, only: [:index, :show], constraints: { id: /\d+/ }
 
       resources :todos, only: [:create]
 
diff --git a/spec/models/board_group_recent_visit_spec.rb b/spec/models/board_group_recent_visit_spec.rb
index 59ad4e5417e3..558be61824f3 100644
--- a/spec/models/board_group_recent_visit_spec.rb
+++ b/spec/models/board_group_recent_visit_spec.rb
@@ -50,15 +50,25 @@
   end
 
   describe '#latest' do
-    it 'returns the most recent visited' do
-      board2 = create(:board, group: group)
-      board3 = create(:board, group: group)
+    def create_visit(time)
+      create :board_group_recent_visit, group: group, user: user, updated_at: time
+    end
 
-      create :board_group_recent_visit, group: board.group, board: board, user: user, updated_at: 7.days.ago
-      create :board_group_recent_visit, group: board2.group, board: board2, user: user, updated_at: 5.days.ago
-      recent = create :board_group_recent_visit, group: board3.group, board: board3, user: user, updated_at: 1.day.ago
+    it 'returns the most recent visited' do
+      create_visit(7.days.ago)
+      create_visit(5.days.ago)
+      recent = create_visit(1.day.ago)
 
       expect(described_class.latest(user, group)).to eq recent
     end
+
+    it 'returns last 3 visited boards' do
+      create_visit(7.days.ago)
+      visit1 = create_visit(3.days.ago)
+      visit2 = create_visit(2.days.ago)
+      visit3 = create_visit(5.days.ago)
+
+      expect(described_class.latest(user, group, count: 3)).to eq([visit2, visit1, visit3])
+    end
   end
 end
diff --git a/spec/models/board_project_recent_visit_spec.rb b/spec/models/board_project_recent_visit_spec.rb
index 275581945fad..e404fb3bbdb9 100644
--- a/spec/models/board_project_recent_visit_spec.rb
+++ b/spec/models/board_project_recent_visit_spec.rb
@@ -50,15 +50,25 @@
   end
 
   describe '#latest' do
-    it 'returns the most recent visited' do
-      board2 = create(:board, project: project)
-      board3 = create(:board, project: project)
+    def create_visit(time)
+      create :board_project_recent_visit, project: project, user: user, updated_at: time
+    end
 
-      create :board_project_recent_visit, project: board.project, board: board, user: user, updated_at: 7.days.ago
-      create :board_project_recent_visit, project: board2.project, board: board2, user: user, updated_at: 5.days.ago
-      recent = create :board_project_recent_visit, project: board3.project, board: board3, user: user, updated_at: 1.day.ago
+    it 'returns the most recent visited' do
+      create_visit(7.days.ago)
+      create_visit(5.days.ago)
+      recent = create_visit(1.day.ago)
 
       expect(described_class.latest(user, project)).to eq recent
     end
+
+    it 'returns last 3 visited boards' do
+      create_visit(7.days.ago)
+      visit1 = create_visit(3.days.ago)
+      visit2 = create_visit(2.days.ago)
+      visit3 = create_visit(5.days.ago)
+
+      expect(described_class.latest(user, project, count: 3)).to eq([visit2, visit1, visit3])
+    end
   end
 end
diff --git a/spec/services/boards/visits/latest_service_spec.rb b/spec/services/boards/visits/latest_service_spec.rb
index e55d599e2cc6..c8a0a5e42430 100644
--- a/spec/services/boards/visits/latest_service_spec.rb
+++ b/spec/services/boards/visits/latest_service_spec.rb
@@ -23,6 +23,12 @@
 
         service.execute
       end
+
+      it 'queries for last N visits' do
+        expect(BoardProjectRecentVisit).to receive(:latest).with(user, project, count: 5).once
+
+        described_class.new(project_board.parent, user, count: 5).execute
+      end
     end
 
     context 'when a group board' do
@@ -42,6 +48,12 @@
 
         service.execute
       end
+
+      it 'queries for last N visits' do
+        expect(BoardGroupRecentVisit).to receive(:latest).with(user, group, count: 5).once
+
+        described_class.new(group_board.parent, user, count: 5).execute
+      end
     end
   end
 end
-- 
GitLab