Commit 90527b9f authored by Mark Chao's avatar Mark Chao

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
......@@ -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
......@@ -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
......
# 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
......@@ -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
......
# 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
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