summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTetiana Chupryna <tchupryna@gitlab.com>2019-05-02 17:22:50 +0000
committerBob Van Landuyt <bob@gitlab.com>2019-05-02 17:22:50 +0000
commit7099b3d3d5d97ec740d90899557077f34c1c5876 (patch)
treefc0c915e9133235639e6d6a0e42dff2700a81d8f
parent434ef10a534fcda65800d7f924aa6353e881ec60 (diff)
downloadgitlab-ce-7099b3d3d5d97ec740d90899557077f34c1c5876.tar.gz
Replace FFaker gem
it doesn't supported in production environment
-rw-r--r--ee/app/controllers/projects/dependencies_controller.rb43
-rw-r--r--ee/app/finders/security/dependencies_finder.rb65
-rw-r--r--ee/changelogs/unreleased/11060-bom-api-preliminary.yml5
-rw-r--r--ee/config/routes/project.rb2
-rw-r--r--ee/spec/controllers/projects/dependencies_controller_spec.rb59
-rw-r--r--ee/spec/finders/security/dependencies_finder_spec.rb44
6 files changed, 218 insertions, 0 deletions
diff --git a/ee/app/controllers/projects/dependencies_controller.rb b/ee/app/controllers/projects/dependencies_controller.rb
new file mode 100644
index 00000000000..edf2f493d4f
--- /dev/null
+++ b/ee/app/controllers/projects/dependencies_controller.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+module Projects
+ class DependenciesController < Projects::ApplicationController
+ SORT_BY_PERMITTED_VALUES = %w(name type).freeze
+ SORT_PERMITTED_VALUES = %w(asc desc).freeze
+
+ before_action :ensure_bill_of_materials_feature_flag_enabled
+
+ def index
+ respond_to do |format|
+ format.json do
+ render json: paginated_dependecies
+ end
+ end
+ end
+
+ private
+
+ def ensure_bill_of_materials_feature_flag_enabled
+ render_404 unless Feature.enabled?(:bill_of_materials, default_enabled: false)
+ end
+
+ def found_dependencies
+ ::Security::DependenciesFinder.new(project: @project, params: query_params).execute
+ end
+
+ def query_params
+ params.permit(:sort, :sort_by).delete_if do |key, value|
+ key == :sort_by && !value.in?(::Security::DependenciesFinder::SORT_BY_VALUES) ||
+ key == :sort && !value.in?(::Security::DependenciesFinder::SORT_VALUES)
+ end
+ end
+
+ # TODO: add proper implementation of edge cases handling
+ # format: { report: 'failed' }
+ # after we'll have more then just mock data
+ # reference: https://gitlab.com/gitlab-org/gitlab-ee/issues/10075#note_164915787
+ def paginated_dependecies
+ Kaminari.paginate_array(found_dependencies).page(params[:page])
+ end
+ end
+end
diff --git a/ee/app/finders/security/dependencies_finder.rb b/ee/app/finders/security/dependencies_finder.rb
new file mode 100644
index 00000000000..b2d95eb209a
--- /dev/null
+++ b/ee/app/finders/security/dependencies_finder.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+module Security
+ class DependenciesFinder
+ attr_accessor :params
+ attr_reader :project
+
+ SORT_BY_VALUES = %w(name type).freeze
+ SORT_VALUES = %w(asc desc).freeze
+
+ # @param project [Project]
+ # @param [Hash] params to sort dependencies
+ # @option params ['asc', 'desc'] :sort ('asc') Order
+ # @option params ['name', 'type'] :sort_by ('name') Field to sort
+ def initialize(project:, params: {})
+ @project = project
+ @params = params
+ end
+
+ # @return [Array<Hash>] collection of found dependencies
+ def execute
+ collection = init_collection
+ collection = sort(collection)
+ collection
+ end
+
+ private
+
+ def init_collection
+ array = []
+ 100.times { array << mock }
+ array
+ end
+
+ def fake_name
+ (0..16).map { ('a'..'z').to_a[rand 26] }.join
+ end
+
+ def mock
+ {
+ name: fake_name,
+ type: %w(gem npm module).sample,
+ location: {
+ blob_path: 'gitlab-org/gitlab-ee/blob/master/Gemfile.lock#L1248'
+ },
+ version: '5.4.1',
+ requirements: [
+ '~>5.4.1'
+ ]
+ }
+ end
+
+ def sort(collection)
+ if @params[:sort_by] == 'type'
+ collection.sort_by! { |a| a[:type] }
+ else
+ collection.sort_by! { |a| a[:name] }
+ end
+
+ collection.reverse! if @params[:sort] == 'desc'
+
+ collection
+ end
+ end
+end
diff --git a/ee/changelogs/unreleased/11060-bom-api-preliminary.yml b/ee/changelogs/unreleased/11060-bom-api-preliminary.yml
new file mode 100644
index 00000000000..20c92b2cf1b
--- /dev/null
+++ b/ee/changelogs/unreleased/11060-bom-api-preliminary.yml
@@ -0,0 +1,5 @@
+---
+title: Basic Rails implementation for BOM
+merge_request: 11613
+author:
+type: added
diff --git a/ee/config/routes/project.rb b/ee/config/routes/project.rb
index b1409bd4314..810f90ad955 100644
--- a/ee/config/routes/project.rb
+++ b/ee/config/routes/project.rb
@@ -62,6 +62,8 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
end
end
+ resources :dependencies, only: [:index]
+
namespace :settings do
resource :operations, only: [:show, :update] do
member do
diff --git a/ee/spec/controllers/projects/dependencies_controller_spec.rb b/ee/spec/controllers/projects/dependencies_controller_spec.rb
new file mode 100644
index 00000000000..51b8ba036d9
--- /dev/null
+++ b/ee/spec/controllers/projects/dependencies_controller_spec.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Projects::DependenciesController do
+ describe 'GET index.json' do
+ set(:project) { create(:project, :repository, :public) }
+ set(:user) { create(:user) }
+
+ subject { get :index, params: { namespace_id: project.namespace, project_id: project }, format: :json }
+
+ before do
+ project.add_developer(user)
+ end
+
+ context 'with authorized user' do
+ before do
+ sign_in(user)
+ end
+
+ context 'when feature is available' do
+ it "returns a list of dependencies" do
+ subject
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response).to be_an(Array)
+ expect(json_response.length).to eq 20
+ end
+
+ it 'returns paginated list' do
+ get :index, params: { namespace_id: project.namespace, project_id: project, page: 2 }, format: :json
+
+ expect(json_response.length).to eq 20
+ end
+
+ it 'returns sorted list' do
+ get :index, params: { namespace_id: project.namespace, project_id: project, sort_by: 'type', sort: 'desc' }, format: :json
+
+ sorted = json_response.sort_by { |a| a[:type] }.reverse
+
+ expect(json_response[0][:type]).to eq(sorted[0][:type])
+ expect(json_response[19][:type]).to eq(sorted[19][:type])
+ end
+ end
+
+ context 'when feature is disabled' do
+ before do
+ stub_feature_flags(bill_of_materials: false)
+ end
+
+ it 'returns 404' do
+ subject
+
+ expect(response).to have_gitlab_http_status(404)
+ end
+ end
+ end
+ end
+end
diff --git a/ee/spec/finders/security/dependencies_finder_spec.rb b/ee/spec/finders/security/dependencies_finder_spec.rb
new file mode 100644
index 00000000000..f5e80abe092
--- /dev/null
+++ b/ee/spec/finders/security/dependencies_finder_spec.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Security::DependenciesFinder do
+ describe '#execute' do
+ let(:project) { create :project }
+
+ subject { described_class.new(project: project, params: params).execute }
+
+ context 'without params' do
+ let(:params) { {} }
+
+ it 'returns array of data sorted by names' do
+ result = subject.sort_by { |a| a[:name] }
+
+ is_expected.to be_an(Array)
+ expect(subject.size).to eq(100)
+ expect(subject.first[:name]).to eq(result.first[:name])
+ expect(subject.last[:name]).to eq(result.last[:name])
+ end
+ end
+
+ context 'with params' do
+ context 'sorted desc by types' do
+ let(:params) do
+ {
+ sort: 'desc',
+ sort_by: 'type'
+ }
+ end
+
+ it 'returns array of data properly sorted' do
+ result = subject.sort_by { |a| a[:type] }.reverse
+
+ is_expected.to be_an(Array)
+ expect(subject.size).to eq(100)
+ expect(subject.first[:type]).to eq(result.first[:type])
+ expect(subject.last[:type]).to eq(result.last[:type])
+ end
+ end
+ end
+ end
+end