Commit 1a8ebeda authored by Alex Kalderimis's avatar Alex Kalderimis

Move all logic out of views

This moves even the path generation and permission checking logic out of
the views, making the controller responsible for packing up all the data
needed for display. This has the advantage of allowing view tests to use
the :build strategy, since no persistence is needed.

The @related_branches attribute is combined with @branch_info, so we
have just a single assigment.
parent 4d684170
...@@ -154,13 +154,10 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -154,13 +154,10 @@ class Projects::IssuesController < Projects::ApplicationController
end end
def related_branches def related_branches
@related_branches = Issues::RelatedBranchesService.new(project, current_user).execute(issue) @related_branches = Issues::RelatedBranchesService
@branch_info = @related_branches.map do |branch_name| .new(project, current_user)
branch = @project.repository.find_branch(branch_name) .execute(issue)
target = branch&.dereferenced_target .map { |name| { name: name, link: branch_link(name), pipeline_status: pipeline_status(name) } }
pipeline = @project.pipeline_for(branch_name, target.sha) if target
{ name: branch_name, pipeline: pipeline }
end
respond_to do |format| respond_to do |format|
format.json do format.json do
...@@ -312,6 +309,18 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -312,6 +309,18 @@ class Projects::IssuesController < Projects::ApplicationController
private private
def branch_link(branch_name)
project_compare_path(project, from: project.default_branch, to: branch_name)
end
def pipeline_status(branch_name)
branch = @project.repository.find_branch(branch_name)
target = branch&.dereferenced_target
pipeline = @project.pipeline_for(branch_name, target.sha) if target
pipeline.detailed_status(current_user) if can?(current_user, :read_pipeline, pipeline)
end
def create_rate_limit def create_rate_limit
key = :issues_create key = :issues_create
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
%h2.related-branches-title %h2.related-branches-title
= pluralize(@related_branches.size, 'Related Branch') = pluralize(@related_branches.size, 'Related Branch')
%ul.unstyled-list.related-merge-requests %ul.unstyled-list.related-merge-requests
- @branch_info.each do |branch| - @related_branches.each do |branch|
%li %li
- if can?(current_user, :read_pipeline, branch[:pipeline]) - if branch[:pipeline_status].present?
%span.related-branch-ci-status %span.related-branch-ci-status
= render 'ci/status/icon', status: branch[:pipeline].detailed_status(current_user) = render 'ci/status/icon', status: branch[:pipeline_status]
%span.related-branch-info %span.related-branch-info
%strong %strong
= link_to branch[:name], project_compare_path(@project, from: @project.default_branch, to: branch[:name]), class: "ref-name" = link_to branch[:name], branch[:link], class: "ref-name"
...@@ -243,7 +243,7 @@ describe Projects::IssuesController do ...@@ -243,7 +243,7 @@ describe Projects::IssuesController do
end end
end end
describe '#related_branches', :aggregate_failures do describe '#related_branches' do
subject { get :related_branches, params: params, format: :json } subject { get :related_branches, params: params, format: :json }
before do before do
...@@ -272,12 +272,11 @@ describe Projects::IssuesController do ...@@ -272,12 +272,11 @@ describe Projects::IssuesController do
end end
context 'there are no related branches' do context 'there are no related branches' do
it 'assigns empty arrays' do it 'assigns empty arrays', :aggregate_failures do
subject subject
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:related_branches)).to be_empty expect(assigns(:related_branches)).to be_empty
expect(assigns(:branch_info)).to be_empty
expect(response).to render_template('projects/issues/_related_branches') expect(response).to render_template('projects/issues/_related_branches')
expect(json_response).to eq('html' => '') expect(json_response).to eq('html' => '')
end end
...@@ -285,12 +284,33 @@ describe Projects::IssuesController do ...@@ -285,12 +284,33 @@ describe Projects::IssuesController do
context 'there are related branches' do context 'there are related branches' do
let(:missing_branch) { "#{issue.to_branch_name}-missing" } let(:missing_branch) { "#{issue.to_branch_name}-missing" }
let(:repo) { double('Repo', branch_names: branch_names) } let(:unreadable_branch_name) { "#{issue.to_branch_name}-unreadable" }
let(:repo) { double('Repo', root_ref: 'refs/heads/master', branch_names: branch_names) }
let(:sha) { 'abcdef' } let(:sha) { 'abcdef' }
let(:pipeline) { build(:ci_pipeline, :success) } let(:pipeline) { build(:ci_pipeline, :success, project: project) }
let(:branch) { double('Branch', dereferenced_target: double('Target', sha: sha)) } let(:unreadable_pipeline) { build(:ci_pipeline, :running) }
let(:branch) { make_branch }
let(:unreadable_branch) { make_branch }
let(:branch_names) do let(:branch_names) do
[ generate(:branch), "#{issue.iid}doesnt-match", issue.to_branch_name, missing_branch ] [
generate(:branch),
"#{issue.iid}doesnt-match",
issue.to_branch_name,
missing_branch,
unreadable_branch_name
]
end
def make_branch
double('Branch', dereferenced_target: double('Target', sha: sha))
end
def branch_info(name, status)
{
name: name,
link: controller.project_compare_path(project, from: project.default_branch, to: name),
pipeline_status: status
}
end end
before do before do
...@@ -302,20 +322,25 @@ describe Projects::IssuesController do ...@@ -302,20 +322,25 @@ describe Projects::IssuesController do
.with(issue.to_branch_name).and_return(branch) .with(issue.to_branch_name).and_return(branch)
allow(repo).to receive(:find_branch) allow(repo).to receive(:find_branch)
.with(missing_branch).and_return(nil) .with(missing_branch).and_return(nil)
allow(repo).to receive(:find_branch)
.with(unreadable_branch_name).and_return(unreadable_branch)
allow(project).to receive(:pipeline_for) expect(project).to receive(:pipeline_for)
.with(issue.to_branch_name, sha) .with(issue.to_branch_name, sha)
.and_return(pipeline) .and_return(pipeline)
expect(project).to receive(:pipeline_for)
.with(unreadable_branch_name, sha)
.and_return(unreadable_pipeline)
end end
it 'finds and assigns the appropriate branch information' do it 'finds and assigns the appropriate branch information', :aggregate_failures do
subject subject
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:related_branches)).to contain_exactly(issue.to_branch_name, missing_branch) expect(assigns(:related_branches)).to contain_exactly(
expect(assigns(:branch_info)).to contain_exactly( branch_info(issue.to_branch_name, an_instance_of(Gitlab::Ci::Status::Success)),
a_hash_including(name: issue.to_branch_name, pipeline: pipeline), branch_info(missing_branch, be_nil),
a_hash_including(name: missing_branch, pipeline: nil) branch_info(unreadable_branch_name, be_nil)
) )
expect(response).to render_template('projects/issues/_related_branches') expect(response).to render_template('projects/issues/_related_branches')
expect(json_response).to match('html' => String) expect(json_response).to match('html' => String)
......
...@@ -5,25 +5,25 @@ require 'spec_helper' ...@@ -5,25 +5,25 @@ require 'spec_helper'
describe 'projects/issues/_related_branches' do describe 'projects/issues/_related_branches' do
include Devise::Test::ControllerHelpers include Devise::Test::ControllerHelpers
let(:user) { create(:user) } let(:pipeline) { build(:ci_pipeline, :success) }
let(:project) { create(:project, :repository) } let(:status) { pipeline.detailed_status(build(:user)) }
let(:branch) { project.repository.find_branch('feature') }
let!(:pipeline) { create(:ci_pipeline, project: project, sha: branch.dereferenced_target.id, ref: 'feature') }
before do before do
assign(:project, project) assign(:related_branches, [
assign(:related_branches, %w(other feature)) { name: 'other', link: 'link-to-other', pipeline_status: nil },
assign(:branch_info, [{ name: 'other', pipeline: nil }, { name: 'feature', pipeline: pipeline }]) { name: 'feature', link: 'link-to-feature', pipeline_status: status }
])
project.add_developer(user)
allow(view).to receive(:current_user).and_return(user)
render render
end end
it 'shows the related branches with their build status' do it 'shows the related branches with their build status', :aggregate_failures do
expect(rendered).to match('feature') expect(rendered).to have_text('feature')
expect(rendered).to match('other') expect(rendered).to have_text('other')
expect(rendered).to have_link(href: 'link-to-feature')
expect(rendered).to have_link(href: 'link-to-other')
expect(rendered).to have_css('.related-branch-ci-status') expect(rendered).to have_css('.related-branch-ci-status')
expect(rendered).to have_css('.ci-status-icon')
expect(rendered).to have_css('.related-branch-info')
end 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