Skip to content
Snippets Groups Projects
Commit 90527b9f authored by Mark Chao's avatar Mark Chao
Browse files

Add full option for blob diff action

Returns all diff lines for frontend if full is true.
Turn UnfoldForm into presenter, and move controller logic to presenter.
parent 154720ca
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -90,20 +90,9 @@ class Projects::BlobController < Projects::ApplicationController
def diff
apply_diff_view_cookie!
 
@blob.load_all_data!
@lines = @blob.present.highlight.lines
@form = UnfoldForm.new(params.to_unsafe_h)
@lines = @lines[@form.since - 1..@form.to - 1].map(&:html_safe)
if @form.bottom?
@match_line = ''
else
lines_length = @lines.length - 1
line = [@form.since, lines_length].join(',')
@match_line = "@@ -#{line}+#{line} @@"
end
@form = Blobs::UnfoldPresenter.new(blob, params.to_unsafe_h)
@lines = @form.lines
@match_line = @form.match_line_text
 
# We can keep only 'render_diff_lines' from this conditional when
# https://gitlab.com/gitlab-org/gitlab-ce/issues/44988 is done
Loading
Loading
@@ -231,6 +220,8 @@ class Projects::BlobController < Projects::ApplicationController
end
 
def validate_diff_params
return if params[:full]
if [:since, :to, :offset].any? { |key| params[key].blank? }
head :ok
end
Loading
Loading
# frozen_string_literal: true
require 'gt_one_coercion'
module Blobs
class UnfoldPresenter < BlobPresenter
include Virtus.model
include Gitlab::Utils::StrongMemoize
attribute :full, Boolean, default: false
attribute :since, GtOneCoercion
attribute :to, GtOneCoercion
attribute :bottom, Boolean
attribute :unfold, Boolean, default: true
attribute :offset, Integer
attribute :indent, Integer, default: 0
def initialize(blob, params)
@subject = blob
@all_lines = highlight.lines
super(params)
if full?
self.attributes = { since: 1, to: @all_lines.size, bottom: false, unfold: false, offset: 0, indent: 0 }
end
end
def lines
strong_memoize(:lines) do
lines = @all_lines
lines = lines[since - 1..to - 1] unless full?
lines.map(&:html_safe)
end
end
def match_line_text
return '' if bottom?
lines_length = lines.length - 1
line = [since, lines_length].join(',')
"@@ -#{line}+#{line} @@"
end
end
end
# frozen_string_literal: true
require_relative 'gt_one_coercion'
class UnfoldForm
include Virtus.model
attribute :since, GtOneCoercion
attribute :to, GtOneCoercion
attribute :bottom, Boolean
attribute :unfold, Boolean, default: true
attribute :offset, Integer
attribute :indent, Integer, default: 0
end
Loading
Loading
@@ -192,6 +192,18 @@ describe Projects::BlobController do
 
expect(match_line['type']).to be_nil
end
it 'returns all lines if "full" is true' do
commit_id = project.repository.commit('master').id
blob = project.repository.blob_at(commit_id, 'CHANGELOG')
do_get(full: true, from_merge_request: true, bottom: true)
match_lines = JSON.parse(response.body)
expect(match_lines.size).to eq(blob.lines.count - 1)
expect(match_lines.last['type']).to be_nil
expect(match_lines.last['text']).to include(blob.lines.last)
end
end
end
end
Loading
Loading
# frozen_string_literal: true
require 'spec_helper'
describe Blobs::UnfoldPresenter do
include FakeBlobHelpers
let(:project) { create(:project, :repository) }
let(:blob) { fake_blob(path: 'foo', data: "1\n2\n3") }
let(:subject) { described_class.new(blob, params) }
describe '#initialize' do
context 'when full is false' do
let(:params) { { full: false, since: 2, to: 3, bottom: false, offset: 1, indent: 1 } }
it 'sets attributes' do
result = subject
expect(result.full?).to eq(false)
expect(result.since).to eq(2)
expect(result.to).to eq(3)
expect(result.bottom).to eq(false)
expect(result.offset).to eq(1)
expect(result.indent).to eq(1)
end
end
context 'when full is true' do
let(:params) { { full: true, since: 2, to: 3, bottom: false, offset: 1, indent: 1 } }
it 'sets other attributes' do
result = subject
expect(result.full?).to eq(true)
expect(result.since).to eq(1)
expect(result.to).to eq(blob.lines.size)
expect(result.bottom).to eq(false)
expect(result.offset).to eq(0)
expect(result.indent).to eq(0)
end
end
end
describe '#lines' do
context 'when scope is specified' do
let(:params) { { since: 2, to: 3 } }
it 'returns lines cropped by params' do
expect(subject.lines.size).to eq(2)
expect(subject.lines[0]).to include('LC2')
expect(subject.lines[1]).to include('LC3')
end
end
context 'when full is true' do
let(:params) { { full: true } }
it 'returns all lines' do
expect(subject.lines.size).to eq(3)
expect(subject.lines[0]).to include('LC1')
expect(subject.lines[1]).to include('LC2')
expect(subject.lines[2]).to include('LC3')
end
end
end
describe '#match_line_text' do
context 'when bottom is true' do
let(:params) { { since: 2, to: 3, bottom: true } }
it 'returns empty string' do
expect(subject.match_line_text).to eq('')
end
end
context 'when bottom is false' do
let(:params) { { since: 2, to: 3, bottom: false } }
it 'returns match line string' do
expect(subject.match_line_text).to eq("@@ -2,1+2,1 @@")
end
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment