summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Chao <mchao@gitlab.com>2019-01-23 16:50:19 +0800
committerMark Chao <mchao@gitlab.com>2019-03-06 15:50:55 +0800
commit90527b9f842d53595fb14a97a8f8ad19d9dc505a (patch)
treefed26f765da312e42b19e720b94dc3eab7c423b2
parent154720cadc05d79fd5a89bfec18b9385964447ec (diff)
downloadgitlab-ce-90527b9f842d53595fb14a97a8f8ad19d9dc505a.tar.gz
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.
-rw-r--r--app/controllers/projects/blob_controller.rb19
-rw-r--r--app/presenters/blobs/unfold_presenter.rb44
-rw-r--r--lib/unfold_form.rb14
-rw-r--r--spec/controllers/projects/blob_controller_spec.rb12
-rw-r--r--spec/presenters/blobs/unfold_presenter_spec.rb84
5 files changed, 145 insertions, 28 deletions
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index 77672e7d9fc..63e04539b40 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -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
diff --git a/app/presenters/blobs/unfold_presenter.rb b/app/presenters/blobs/unfold_presenter.rb
new file mode 100644
index 00000000000..908b2f97f89
--- /dev/null
+++ b/app/presenters/blobs/unfold_presenter.rb
@@ -0,0 +1,44 @@
+# 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
diff --git a/lib/unfold_form.rb b/lib/unfold_form.rb
deleted file mode 100644
index 05bb3ed7f1c..00000000000
--- a/lib/unfold_form.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# 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
diff --git a/spec/controllers/projects/blob_controller_spec.rb b/spec/controllers/projects/blob_controller_spec.rb
index 38957e96798..250c4aad87f 100644
--- a/spec/controllers/projects/blob_controller_spec.rb
+++ b/spec/controllers/projects/blob_controller_spec.rb
@@ -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
diff --git a/spec/presenters/blobs/unfold_presenter_spec.rb b/spec/presenters/blobs/unfold_presenter_spec.rb
new file mode 100644
index 00000000000..c4d7d457705
--- /dev/null
+++ b/spec/presenters/blobs/unfold_presenter_spec.rb
@@ -0,0 +1,84 @@
+# 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