Commit 76ccb848 authored by Oswaldo Ferreira's avatar Oswaldo Ferreira

Move listing logic to RelatedIssues::ListService

parent b0e56289
module Projects module Projects
class RelatedIssuesController < ApplicationController class RelatedIssuesController < ApplicationController
include IssuesHelper
before_action :authorize_read_related_issue! before_action :authorize_read_related_issue!
before_action :authorize_admin_related_issue!, only: [:create] before_action :authorize_admin_related_issue!, only: [:create]
def index def index
render json: serialize_as_json render json: RelatedIssues::ListService.new(issue, current_user).execute
end end
def create def create
...@@ -26,27 +24,6 @@ module Projects ...@@ -26,27 +24,6 @@ module Projects
return render_404 unless can?(current_user, :read_related_issue, @project) return render_404 unless can?(current_user, :read_related_issue, @project)
end end
# TODO: Move to service class
def serialize_as_json
related_issues.map do |related_issue|
referenced_issue = related_issue.related_issue == issue ? related_issue.issue : related_issue.related_issue
{
title: referenced_issue.title,
state: referenced_issue.state,
reference: referenced_issue.to_reference(@project),
path: url_for_issue(referenced_issue.iid, @project, only_path: true),
}
end
end
def related_issues
RelatedIssue
.where("issue_id = #{issue.id} OR related_issue_id = #{issue.id}")
.preload(:related_issue, :issue)
.order(:created_at)
end
def issue def issue
@issue ||= @issue ||=
IssuesFinder.new(current_user, project_id: project.id) IssuesFinder.new(current_user, project_id: project.id)
......
module RelatedIssues
class ListService
include Gitlab::Routing
def initialize(issue, user)
@issue, @current_user = issue, user
end
def execute
related_issues.map do |related_issue|
referenced_issue =
if related_issue.related_issue == @issue
related_issue.issue
else
related_issue.related_issue
end
{
title: referenced_issue.title,
state: referenced_issue.state,
reference: referenced_issue.to_reference(@issue.project),
path: namespace_project_issue_path(referenced_issue.project.namespace, referenced_issue.project, referenced_issue.iid)
}
end
end
private
def related_issues
RelatedIssue
.where("issue_id = #{@issue.id} OR related_issue_id = #{@issue.id}")
.preload(related_issue: :project, issue: :project)
.order(:created_at)
end
end
end
\ No newline at end of file
...@@ -6,65 +6,28 @@ describe Projects::RelatedIssuesController, type: :controller do ...@@ -6,65 +6,28 @@ describe Projects::RelatedIssuesController, type: :controller do
let(:issue) { create :issue, project: project } let(:issue) { create :issue, project: project }
describe 'GET #index' do describe 'GET #index' do
let(:issue_b) { create :issue, project: project } let(:service) { double(RelatedIssues::ListService, execute: service_response) }
let(:issue_c) { create :issue, project: project } let(:service_response) { [{ 'foo' => 'bar' }] }
let(:issue_d) { create :issue, project: project }
let!(:related_issue_a) do before do
create(:related_issue, issue: issue, project.team << [user, :guest]
related_issue: issue_b, sign_in user
created_at: 2.days.ago)
end
let!(:related_issue_b) do
create(:related_issue, issue: issue,
related_issue: issue_c,
created_at: 1.day.ago)
end
let!(:related_issue_c) do allow(RelatedIssues::ListService).to receive(:new)
create(:related_issue, issue: issue_d, .with(issue, user)
related_issue: issue, .and_return(service)
created_at: Date.today)
end end
it 'returns related issues JSON' do subject do
sign_in user
project.team << [user, :developer]
get :index, namespace_id: issue.project.namespace, get :index, namespace_id: issue.project.namespace,
project_id: issue.project, project_id: issue.project,
issue_id: issue, issue_id: issue,
format: :json format: :json
end
expect(json_response.size).to eq(3) it 'returns JSON response' do
is_expected.to have_http_status(200)
expect(json_response[0]).to eq( expect(json_response).to eq(service_response)
{
"title" => issue_b.title,
"state" => issue_b.state,
"reference" => issue_b.to_reference(project),
"path" => "/#{project.full_path}/issues/#{issue_b.iid}"
}
)
expect(json_response[1]).to eq(
{
"title" => issue_c.title,
"state" => issue_c.state,
"reference" => issue_c.to_reference(project),
"path" => "/#{project.full_path}/issues/#{issue_c.iid}"
}
)
expect(json_response[2]).to eq(
{
"title" => issue_d.title,
"state" => issue_d.state,
"reference" => issue_d.to_reference(project),
"path" => "/#{project.full_path}/issues/#{issue_d.iid}"
}
)
end end
end end
...@@ -76,6 +39,7 @@ describe Projects::RelatedIssuesController, type: :controller do ...@@ -76,6 +39,7 @@ describe Projects::RelatedIssuesController, type: :controller do
before do before do
project.team << [user, user_role] project.team << [user, user_role]
sign_in user
allow(RelatedIssues::CreateService).to receive(:new) allow(RelatedIssues::CreateService).to receive(:new)
.with(issue, user, { issue_references: issue_references }) .with(issue, user, { issue_references: issue_references })
...@@ -83,8 +47,6 @@ describe Projects::RelatedIssuesController, type: :controller do ...@@ -83,8 +47,6 @@ describe Projects::RelatedIssuesController, type: :controller do
end end
subject do subject do
sign_in user
post :create, namespace_id: issue.project.namespace, post :create, namespace_id: issue.project.namespace,
project_id: issue.project, project_id: issue.project,
issue_id: issue, issue_id: issue,
......
require 'spec_helper'
describe RelatedIssues::ListService, service: true do
describe '#execute' do
let(:user) { create :user }
let(:project) { create(:project_empty_repo) }
let(:issue) { create :issue, project: project }
let(:issue_b) { create :issue, project: project }
let(:issue_c) { create :issue, project: project }
let(:issue_d) { create :issue, project: project }
let!(:related_issue_c) do
create(:related_issue, issue: issue_d,
related_issue: issue,
created_at: Date.today)
end
let!(:related_issue_b) do
create(:related_issue, issue: issue,
related_issue: issue_c,
created_at: 1.day.ago)
end
let!(:related_issue_a) do
create(:related_issue, issue: issue,
related_issue: issue_b,
created_at: 2.days.ago)
end
subject { described_class.new(issue, user).execute }
it 'verifies number of queries' do
recorded = ActiveRecord::QueryRecorder.new { subject }
expect(recorded.count).to be_within(1).of(29)
end
it 'returns related issues JSON' do
expect(subject.size).to eq(3)
expect(subject[0]).to eq(
{
title: issue_b.title,
state: issue_b.state,
reference: issue_b.to_reference(project),
path: "/#{project.full_path}/issues/#{issue_b.iid}"
}
)
expect(subject[1]).to eq(
{
title: issue_c.title,
state: issue_c.state,
reference: issue_c.to_reference(project),
path: "/#{project.full_path}/issues/#{issue_c.iid}"
}
)
expect(subject[2]).to eq(
{
title: issue_d.title,
state: issue_d.state,
reference: issue_d.to_reference(project),
path: "/#{project.full_path}/issues/#{issue_d.iid}"
}
)
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment