diff options
author | Mark Chao <mchao@gitlab.com> | 2019-01-23 16:50:19 +0800 |
---|---|---|
committer | Mark Chao <mchao@gitlab.com> | 2019-03-06 15:50:55 +0800 |
commit | 90527b9f842d53595fb14a97a8f8ad19d9dc505a (patch) | |
tree | fed26f765da312e42b19e720b94dc3eab7c423b2 | |
parent | 154720cadc05d79fd5a89bfec18b9385964447ec (diff) | |
download | gitlab-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.rb | 19 | ||||
-rw-r--r-- | app/presenters/blobs/unfold_presenter.rb | 44 | ||||
-rw-r--r-- | lib/unfold_form.rb | 14 | ||||
-rw-r--r-- | spec/controllers/projects/blob_controller_spec.rb | 12 | ||||
-rw-r--r-- | spec/presenters/blobs/unfold_presenter_spec.rb | 84 |
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 |