From 938ec5acb8894ddcf1f9f99a0b1111feaca27df5 Mon Sep 17 00:00:00 2001 From: Oleksii Kriuchykhin Date: Mon, 6 Aug 2018 17:36:16 +0200 Subject: [PATCH 1/6] Change primary key to bigint on repositories [SCI-2614][SCI-2616][SCI-2617] --- .rubocop.yml | 2 +- Gemfile | 1 - ...e_primary_key_to_bigint_on_repositories.rb | 23 +++++++++++++++++++ db/schema.rb | 18 +++++++-------- docker-compose.production.yml | 2 +- docker-compose.yml | 2 +- 6 files changed, 35 insertions(+), 13 deletions(-) create mode 100644 db/migrate/20180806115201_change_primary_key_to_bigint_on_repositories.rb diff --git a/.rubocop.yml b/.rubocop.yml index c69a64de8..295ae2d66 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -3,7 +3,7 @@ AllCops: - "vendor/**/*" - "db/schema.rb" UseCache: false - TargetRubyVersion: 2.2 + TargetRubyVersion: 2.4 ##################### Style #################################### diff --git a/Gemfile b/Gemfile index 8222fc4b6..563b093de 100644 --- a/Gemfile +++ b/Gemfile @@ -51,7 +51,6 @@ gem 'rgl' # Graph framework for project diagram calculations gem 'nested_form_fields' gem 'ajax-datatables-rails', '~> 0.3.1' gem 'commit_param_routing' # Enables different submit actions in the same form to route to different actions in controller -gem 'kaminari' gem 'i18n-js', '~> 3.0' # Localization in javascript files gem 'roo', '~> 2.7.1' # Spreadsheet parser gem 'wicked_pdf', '~> 1.1.0' diff --git a/db/migrate/20180806115201_change_primary_key_to_bigint_on_repositories.rb b/db/migrate/20180806115201_change_primary_key_to_bigint_on_repositories.rb new file mode 100644 index 000000000..fb7fc0b55 --- /dev/null +++ b/db/migrate/20180806115201_change_primary_key_to_bigint_on_repositories.rb @@ -0,0 +1,23 @@ +class ChangePrimaryKeyToBigintOnRepositories < ActiveRecord::Migration[5.1] + def up + change_column :repository_rows, :id, :bigint + change_column :repository_columns, :id, :bigint + change_column :repository_cells, :id, :bigint + change_column :repository_cells, :repository_row_id, :bigint + change_column :repository_cells, :value_id, :bigint + change_column :repository_text_values, :id, :bigint + change_column :repository_date_values, :id, :bigint + change_column :my_module_repository_rows, :repository_row_id, :bigint + end + + def down + change_column :repository_rows, :id, :integer + change_column :repository_columns, :id, :integer + change_column :repository_cells, :id, :integer + change_column :repository_cells, :repository_row_id, :integer + change_column :repository_cells, :value_id, :integer + change_column :repository_text_values, :id, :integer + change_column :repository_date_values, :id, :integer + change_column :my_module_repository_rows, :repository_row_id, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index ce0aa9260..d8a0ddce9 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180524091143) do +ActiveRecord::Schema.define(version: 20180806115201) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -181,7 +181,7 @@ ActiveRecord::Schema.define(version: 20180524091143) do end create_table "my_module_repository_rows", id: :serial, force: :cascade do |t| - t.integer "repository_row_id", null: false + t.bigint "repository_row_id", null: false t.integer "my_module_id" t.integer "assigned_by_id", null: false t.datetime "created_at" @@ -379,11 +379,11 @@ ActiveRecord::Schema.define(version: 20180524091143) do t.index ["last_modified_by_id"], name: "index_repository_asset_values_on_last_modified_by_id" end - create_table "repository_cells", id: :serial, force: :cascade do |t| - t.integer "repository_row_id" + create_table "repository_cells", force: :cascade do |t| + t.bigint "repository_row_id" t.integer "repository_column_id" t.string "value_type" - t.integer "value_id" + t.bigint "value_id" t.datetime "created_at" t.datetime "updated_at" t.index ["repository_column_id"], name: "index_repository_cells_on_repository_column_id" @@ -391,7 +391,7 @@ ActiveRecord::Schema.define(version: 20180524091143) do t.index ["value_type", "value_id"], name: "index_repository_cells_on_value_type_and_value_id" end - create_table "repository_columns", id: :serial, force: :cascade do |t| + create_table "repository_columns", force: :cascade do |t| t.integer "repository_id" t.integer "created_by_id", null: false t.string "name" @@ -401,7 +401,7 @@ ActiveRecord::Schema.define(version: 20180524091143) do t.index ["repository_id"], name: "index_repository_columns_on_repository_id" end - create_table "repository_date_values", id: :serial, force: :cascade do |t| + create_table "repository_date_values", force: :cascade do |t| t.datetime "data" t.datetime "created_at" t.datetime "updated_at" @@ -435,7 +435,7 @@ ActiveRecord::Schema.define(version: 20180524091143) do t.index ["repository_list_item_id"], name: "index_repository_list_values_on_repository_list_item_id" end - create_table "repository_rows", id: :serial, force: :cascade do |t| + create_table "repository_rows", force: :cascade do |t| t.integer "repository_id" t.integer "created_by_id", null: false t.integer "last_modified_by_id", null: false @@ -456,7 +456,7 @@ ActiveRecord::Schema.define(version: 20180524091143) do t.index ["user_id"], name: "index_repository_table_states_on_user_id" end - create_table "repository_text_values", id: :serial, force: :cascade do |t| + create_table "repository_text_values", force: :cascade do |t| t.string "data" t.datetime "created_at" t.datetime "updated_at" diff --git a/docker-compose.production.yml b/docker-compose.production.yml index f1fdb456c..0877637cb 100644 --- a/docker-compose.production.yml +++ b/docker-compose.production.yml @@ -2,7 +2,7 @@ version: '2' services: db: container_name: scinote_db_production - image: postgres:9.4 + image: postgres:9.6 volumes: - scinote_production_postgres:/var/lib/postgresql/data diff --git a/docker-compose.yml b/docker-compose.yml index 6d89be949..12186ebb6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: '2' services: db: container_name: scinote_db_development - image: postgres:9.4 + image: postgres:9.6 volumes: - scinote_development_postgres:/var/lib/postgresql/data From 8d11e03d47f633ad3f78f03bf64770242035de6a Mon Sep 17 00:00:00 2001 From: Oleksii Kriuchykhin Date: Tue, 7 Aug 2018 14:19:49 +0200 Subject: [PATCH 2/6] Add read inventories and inventory items endpoints [SCI-2614][SCI-2616][SCI-2617] --- app/controllers/api/api_controller.rb | 4 +- .../api/v1/inventories_controller.rb | 31 +++++ .../api/v1/inventory_items_controller.rb | 32 +++++ app/controllers/api/v1/teams_controller.rb | 1 - app/models/repository_cell.rb | 12 +- app/models/repository_row.rb | 2 +- .../api/v1/inventory_cell_serializer.rb | 35 +++++ .../api/v1/inventory_item_serializer.rb | 12 ++ .../api/v1/inventory_serializer.rb | 7 + .../v1/repository_asset_value_serializer.rb | 32 +++++ .../v1/repository_list_value_serializer.rb | 8 ++ .../v1/repository_text_value_serializer.rb | 7 + config/locales/en.yml | 6 + config/routes.rb | 3 + spec/rails_helper.rb | 8 ++ .../api/v1/inventories_controller_spec.rb | 93 +++++++++++++ .../api/v1/inventory_items_controller_spec.rb | 127 ++++++++++++++++++ 17 files changed, 413 insertions(+), 7 deletions(-) create mode 100644 app/controllers/api/v1/inventories_controller.rb create mode 100644 app/controllers/api/v1/inventory_items_controller.rb create mode 100644 app/serializers/api/v1/inventory_cell_serializer.rb create mode 100644 app/serializers/api/v1/inventory_item_serializer.rb create mode 100644 app/serializers/api/v1/inventory_serializer.rb create mode 100644 app/serializers/api/v1/repository_asset_value_serializer.rb create mode 100644 app/serializers/api/v1/repository_list_value_serializer.rb create mode 100644 app/serializers/api/v1/repository_text_value_serializer.rb create mode 100644 spec/requests/api/v1/inventories_controller_spec.rb create mode 100644 spec/requests/api/v1/inventory_items_controller_spec.rb diff --git a/app/controllers/api/api_controller.rb b/app/controllers/api/api_controller.rb index 630e7fa4c..4eae4fb8d 100644 --- a/app/controllers/api/api_controller.rb +++ b/app/controllers/api/api_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Api class ApiController < ActionController::API attr_reader :iss @@ -50,7 +52,7 @@ module Api def authenticate if auth_params[:grant_type] == 'password' user = User.find_by_email(auth_params[:email]) - unless user && user.valid_password?(auth_params[:password]) + unless user&.valid_password?(auth_params[:password]) raise StandardError, 'Default: Wrong user password' end payload = { user_id: user.id } diff --git a/app/controllers/api/v1/inventories_controller.rb b/app/controllers/api/v1/inventories_controller.rb new file mode 100644 index 000000000..136801caa --- /dev/null +++ b/app/controllers/api/v1/inventories_controller.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module Api + module V1 + class InventoriesController < BaseController + before_action :load_team, only: %i(show index) + before_action :load_inventory, only: %i(show) + + def index + inventories = + @team.repositories.page(params[:page]).per(params[:page_size]) + render json: inventories, each_serializer: InventorySerializer + end + + def show + render json: @inventory, serializer: InventorySerializer + end + + private + + def load_team + @team = Team.find(params.require(:team_id)) + return render json: {}, status: :forbidden unless can_read_team?(@team) + end + + def load_inventory + @inventory = @team.repositories.find(params.require(:id)) + end + end + end +end diff --git a/app/controllers/api/v1/inventory_items_controller.rb b/app/controllers/api/v1/inventory_items_controller.rb new file mode 100644 index 000000000..e695e6838 --- /dev/null +++ b/app/controllers/api/v1/inventory_items_controller.rb @@ -0,0 +1,32 @@ +module Api + module V1 + class InventoryItemsController < BaseController + before_action :load_team + before_action :load_inventory + + def index + items = + @inventory.repository_rows + .includes(repository_cells: :repository_column) + .includes( + repository_cells: Extends::REPOSITORY_SEARCH_INCLUDES + ).page(params[:page]) + .per(params[:page_size]) + render json: items, + each_serializer: InventoryItemSerializer, + include: :inventory_cells + end + + private + + def load_team + @team = Team.find(params.require(:team_id)) + return render json: {}, status: :forbidden unless can_read_team?(@team) + end + + def load_inventory + @inventory = @team.repositories.find(params.require(:inventory_id)) + end + end + end +end diff --git a/app/controllers/api/v1/teams_controller.rb b/app/controllers/api/v1/teams_controller.rb index 18faa4f61..fdf00d14e 100644 --- a/app/controllers/api/v1/teams_controller.rb +++ b/app/controllers/api/v1/teams_controller.rb @@ -16,7 +16,6 @@ module Api def load_team @team = Team.find(params.require(:id)) - return render json: {}, status: :not_found unless @team return render json: {}, status: :forbidden unless can_read_team?(@team) end end diff --git a/app/models/repository_cell.rb b/app/models/repository_cell.rb index 60224fa9a..f86c291e2 100644 --- a/app/models/repository_cell.rb +++ b/app/models/repository_cell.rb @@ -8,22 +8,26 @@ class RepositoryCell < ActiveRecord::Base dependent: :destroy belongs_to :repository_text_value, (lambda do - where(repository_cells: { value_type: 'RepositoryTextValue' }) + joins(:repository_cell) + .where(repository_cells: { value_type: 'RepositoryTextValue' }) end), optional: true, foreign_key: :value_id belongs_to :repository_date_value, (lambda do - where(repository_cells: { value_type: 'RepositoryDateValue' }) + joins(:repository_cell) + .where(repository_cells: { value_type: 'RepositoryDateValue' }) end), optional: true, foreign_key: :value_id belongs_to :repository_list_value, (lambda do - where(repository_cells: { value_type: 'RepositoryListValue' }) + joins(:repository_cell) + .where(repository_cells: { value_type: 'RepositoryListValue' }) end), optional: true, foreign_key: :value_id belongs_to :repository_asset_value, (lambda do - where(repository_cells: { value_type: 'RepositoryAssetValue' }) + joins(:repository_cell) + .where(repository_cells: { value_type: 'RepositoryAssetValue' }) end), optional: true, foreign_key: :value_id diff --git a/app/models/repository_row.rb b/app/models/repository_row.rb index 86b789c03..4daa0aae3 100644 --- a/app/models/repository_row.rb +++ b/app/models/repository_row.rb @@ -10,7 +10,7 @@ class RepositoryRow < ApplicationRecord foreign_key: :last_modified_by_id, class_name: 'User', optional: true - has_many :repository_cells, dependent: :destroy + has_many :repository_cells, -> { order(:id) }, dependent: :destroy has_many :repository_columns, through: :repository_cells has_many :my_module_repository_rows, inverse_of: :repository_row, dependent: :destroy diff --git a/app/serializers/api/v1/inventory_cell_serializer.rb b/app/serializers/api/v1/inventory_cell_serializer.rb new file mode 100644 index 000000000..ea25ae20c --- /dev/null +++ b/app/serializers/api/v1/inventory_cell_serializer.rb @@ -0,0 +1,35 @@ +module Api + module V1 + class InventoryCellSerializer < ActiveModel::Serializer + attribute :id + attribute :repository_column_id, key: :column_id + attribute :data_type + attribute :data + + def data_type + type_id = RepositoryColumn + .data_types[object.repository_column.data_type] + I18n.t("api.v1.inventory_data_types.t#{type_id}") + end + + def data + value = + case object.value_type + when 'RepositoryTextValue' + object.repository_text_value + when 'RepositoryDateValue' + object.repository_date_value + when 'RepositoryListValue' + object.repository_list_value + when 'RepositoryAssetValue' + object.repository_list_value + end + ActiveModelSerializers::SerializableResource.new( + value, + namespace: Api::V1, + adapter: :attribute + ).as_json + end + end + end +end diff --git a/app/serializers/api/v1/inventory_item_serializer.rb b/app/serializers/api/v1/inventory_item_serializer.rb new file mode 100644 index 000000000..733e87a32 --- /dev/null +++ b/app/serializers/api/v1/inventory_item_serializer.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Api + module V1 + class InventoryItemSerializer < ActiveModel::Serializer + attributes :id, :name + has_many :repository_cells, key: :inventory_cells, + serializer: InventoryCellSerializer, + class_name: 'RepositoryCell' + end + end +end diff --git a/app/serializers/api/v1/inventory_serializer.rb b/app/serializers/api/v1/inventory_serializer.rb new file mode 100644 index 000000000..d976bcd2e --- /dev/null +++ b/app/serializers/api/v1/inventory_serializer.rb @@ -0,0 +1,7 @@ +module Api + module V1 + class InventorySerializer < ActiveModel::Serializer + attributes :id, :name + end + end +end diff --git a/app/serializers/api/v1/repository_asset_value_serializer.rb b/app/serializers/api/v1/repository_asset_value_serializer.rb new file mode 100644 index 000000000..be1373efb --- /dev/null +++ b/app/serializers/api/v1/repository_asset_value_serializer.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module Api + module V1 + class RepositoryAssetValueSerializer < ActiveModel::Serializer + attributes :file_id, :file_name, :file_size, :url + + def file_id + object.asset&.id + end + + def file_name + object.asset&.file_file_name + end + + def file_size + object.asset&.file_file_size + end + + def url + if !object.asset&.file_present + nil + elsif object.asset&.file&.is_stored_on_s3? + object.asset.presigned_url(download: true) + else + # separate api endpoint for local files download is needed + download_asset_path(object.asset.id) + end + end + end + end +end diff --git a/app/serializers/api/v1/repository_list_value_serializer.rb b/app/serializers/api/v1/repository_list_value_serializer.rb new file mode 100644 index 000000000..7c7ac7a90 --- /dev/null +++ b/app/serializers/api/v1/repository_list_value_serializer.rb @@ -0,0 +1,8 @@ +module Api + module V1 + class RepositoryListValueSerializer < ActiveModel::Serializer + attribute :formatted, key: :value + attribute :repository_list_item_id, key: :list_item_id + end + end +end diff --git a/app/serializers/api/v1/repository_text_value_serializer.rb b/app/serializers/api/v1/repository_text_value_serializer.rb new file mode 100644 index 000000000..85a6be185 --- /dev/null +++ b/app/serializers/api/v1/repository_text_value_serializer.rb @@ -0,0 +1,7 @@ +module Api + module V1 + class RepositoryTextValueSerializer < ActiveModel::Serializer + attribute :formatted, key: :value + end + end +end diff --git a/config/locales/en.yml b/config/locales/en.yml index 8dee84d14..c7440c1de 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1943,6 +1943,12 @@ en: status_ok: "Ok" expired_token: "Token is expired" invalid_token: "Token is invalid" + v1: + inventory_data_types: + t0: "text" + t1: "date" + t2: "list" + t3: "file" Add: "Add" Asset: "File" diff --git a/config/routes.rb b/config/routes.rb index ddca6879a..bc95e9011 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -542,6 +542,9 @@ Rails.application.routes.draw do post 'auth/token', to: 'api#authenticate' namespace :v1 do resources :teams, only: %i(index show) do + resources :inventories, only: %i(index show) do + get 'items', to: 'inventory_items#index' + end end end end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 79e319489..8d77cc69f 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -71,6 +71,14 @@ RSpec.configure do |config| DatabaseCleaner.clean end + config.before(:all) do + DatabaseCleaner.start + end + + config.after(:all) do + DatabaseCleaner.clean + end + config.around(:each, type: :background_job) do |example| run_background_jobs_immediately do example.run diff --git a/spec/requests/api/v1/inventories_controller_spec.rb b/spec/requests/api/v1/inventories_controller_spec.rb new file mode 100644 index 000000000..363661571 --- /dev/null +++ b/spec/requests/api/v1/inventories_controller_spec.rb @@ -0,0 +1,93 @@ +require 'rails_helper' + +RSpec.describe "Api::V1::InventoriesController", type: :request do + before :all do + @user = create(:user) + @teams = create_list(:team, 2, created_by: @user) + create(:user_team, user: @user, team: @teams.first, role: 2) + + # valid_inventories + create(:repository, name: Faker::Name.unique.name, + created_by: @user, team: @teams.first) + create(:repository, name: Faker::Name.unique.name, + created_by: @user, team: @teams.first) + + # unaccessable_inventories + create(:repository, name: Faker::Name.unique.name, + created_by: @user, team: @teams.second) + create(:repository, name: Faker::Name.unique.name, + created_by: @user, team: @teams.second) + + @valid_headers = + { 'Authorization': 'Bearer ' + generate_token(@user.id) } + end + + describe 'GET inventories, #index' do + it 'Response with correct inventories' do + hash_body = nil + get api_v1_team_inventories_path(team_id: @teams.first.id), + headers: @valid_headers + expect { hash_body = json }.not_to raise_exception + expect(hash_body[:data]).to match( + ActiveModelSerializers::SerializableResource + .new(@teams.first.repositories, + each_serializer: Api::V1::InventorySerializer) + .as_json[:data] + ) + end + + it 'When invalid request, user in not member of the team' do + hash_body = nil + get api_v1_team_inventories_path(team_id: @teams.second.id), + headers: @valid_headers + expect(response).to have_http_status(403) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + end + + describe 'GET inventory, #show' do + it 'When valid request, user is member of the team' do + hash_body = nil + get api_v1_team_inventory_path(team_id: @teams.first.id, + id: @teams.first.repositories.first.id), + headers: @valid_headers + expect { hash_body = json }.not_to raise_exception + expect(hash_body[:data]).to match( + ActiveModelSerializers::SerializableResource + .new(@teams.first.repositories.first, + serializer: Api::V1::InventorySerializer) + .as_json[:data] + ) + end + + it 'When invalid request, user in not member of the team' do + hash_body = nil + get api_v1_team_inventory_path(team_id: @teams.second.id, + id: @teams.second.repositories.first.id), + headers: @valid_headers + expect(response).to have_http_status(403) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + + it 'When invalid request, non existing inventory' do + hash_body = nil + get api_v1_team_inventory_path(team_id: @teams.first.id, id: 123), + headers: @valid_headers + expect(response).to have_http_status(404) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + + it 'When invalid request, repository from another team' do + hash_body = nil + get api_v1_team_inventory_path(team_id: @teams.first.id, + id: @teams.second.repositories.first.id), + headers: @valid_headers + expect(response).to have_http_status(404) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + end +end diff --git a/spec/requests/api/v1/inventory_items_controller_spec.rb b/spec/requests/api/v1/inventory_items_controller_spec.rb new file mode 100644 index 000000000..425eaa52f --- /dev/null +++ b/spec/requests/api/v1/inventory_items_controller_spec.rb @@ -0,0 +1,127 @@ +require 'rails_helper' + +RSpec.describe "Api::V1::InventoryItemsController", type: :request do + before :all do + @user = create(:user) + @teams = create_list(:team, 2, created_by: @user) + create(:user_team, user: @user, team: @teams.first, role: 2) + + # valid_inventory + @valid_inventory = create(:repository, name: Faker::Name.unique.name, + created_by: @user, team: @teams.first) + + # unaccessable_inventory + create(:repository, name: Faker::Name.unique.name, + created_by: @user, team: @teams.second) + + text_column = create(:repository_column, name: Faker::Name.unique.name, + repository: @valid_inventory, data_type: :RepositoryTextValue) + list_column = create(:repository_column, name: Faker::Name.unique.name, + repository: @valid_inventory, data_type: :RepositoryListValue) + list_item = + create(:repository_list_item, repository: @valid_inventory, + repository_column: list_column, data: Faker::Name.unique.name) + file_column = create(:repository_column, name: Faker::Name.unique.name, + repository: @valid_inventory, data_type: :RepositoryAssetValue) + asset = create(:asset) + + create_list(:repository_row, 100, repository: @valid_inventory) + + @valid_inventory.repository_rows.each do |row| + create(:repository_text_value, + data: Faker::Name.name, + repository_cell_attributes: + { repository_row: row, repository_column: text_column }) + create(:repository_list_value, repository_list_item: list_item, + repository_cell_attributes: + { repository_row: row, repository_column: list_column }) + create(:repository_asset_value, asset: asset, + repository_cell_attributes: + { repository_row: row, repository_column: file_column }) + end + + @valid_headers = + { 'Authorization': 'Bearer ' + generate_token(@user.id) } + end + + describe 'GET inventory_items, #index' do + it 'Response with correct inventory items, default per page' do + hash_body = nil + get api_v1_team_inventory_items_path( + team_id: @teams.first.id, + inventory_id: @teams.first.repositories.first.id + ), headers: @valid_headers + expect { hash_body = json }.not_to raise_exception + expect(hash_body[:data]).to match( + ActiveModelSerializers::SerializableResource + .new(@valid_inventory.repository_rows.limit(10), + each_serializer: Api::V1::InventoryItemSerializer, + include: :inventory_cells) + .as_json[:data] + ) + expect(hash_body[:included]).to match( + ActiveModelSerializers::SerializableResource + .new(@valid_inventory.repository_rows.limit(10), + each_serializer: Api::V1::InventoryItemSerializer, + include: :inventory_cells) + .as_json[:included] + ) + end + + it 'Response with correct inventory items, 30 per page' do + hash_body = nil + get api_v1_team_inventory_items_path( + team_id: @teams.first.id, + inventory_id: @teams.first.repositories.first.id + ), params: { page_size: 100 }, headers: @valid_headers + expect { hash_body = json }.not_to raise_exception + expect(hash_body[:data]).to match( + ActiveModelSerializers::SerializableResource + .new(@valid_inventory.repository_rows.limit(100), + each_serializer: Api::V1::InventoryItemSerializer, + include: :inventory_cells) + .as_json[:data] + ) + expect(hash_body[:included]).to match( + ActiveModelSerializers::SerializableResource + .new(@valid_inventory.repository_rows.limit(100), + each_serializer: Api::V1::InventoryItemSerializer, + include: :inventory_cells) + .as_json[:included] + ) + end + + it 'When invalid request, user in not member of the team' do + hash_body = nil + get api_v1_team_inventory_items_path( + team_id: @teams.second.id, + inventory_id: @teams.second.repositories.first.id + ), headers: @valid_headers + expect(response).to have_http_status(403) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + + it 'When invalid request, non existing inventory' do + hash_body = nil + get api_v1_team_inventory_items_path( + team_id: @teams.first.id, + inventory_id: 123 + ), headers: @valid_headers + expect(response).to have_http_status(404) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + + it 'When invalid request, repository from another team' do + hash_body = nil + get api_v1_team_inventory_items_path( + team_id: @teams.first.id, + inventory_id: @teams.second.repositories.first.id + ), headers: @valid_headers + expect(response).to have_http_status(404) + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match({}) + end + end +end From 4df9a4c9ca03c487b5acd1e544ace4381d2ec1f1 Mon Sep 17 00:00:00 2001 From: Oleksii Kriuchykhin Date: Tue, 7 Aug 2018 15:19:24 +0200 Subject: [PATCH 3/6] Fix code style warnings [SCI-2614][SCI-2616][SCI-2617] --- app/controllers/api/v1/base_controller.rb | 2 ++ app/controllers/api/v1/inventory_items_controller.rb | 2 ++ app/serializers/api/v1/inventory_cell_serializer.rb | 2 ++ app/serializers/api/v1/inventory_serializer.rb | 2 ++ app/serializers/api/v1/repository_list_value_serializer.rb | 2 ++ app/serializers/api/v1/repository_text_value_serializer.rb | 2 ++ app/serializers/api/v1/team_serializer.rb | 2 ++ config/initializers/active_model_serializer.rb | 2 ++ ...0806115201_change_primary_key_to_bigint_on_repositories.rb | 2 ++ spec/requests/api/v1/inventories_controller_spec.rb | 2 ++ spec/requests/api/v1/inventory_items_controller_spec.rb | 4 +++- 11 files changed, 23 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/v1/base_controller.rb b/app/controllers/api/v1/base_controller.rb index ff5eafd77..4c43813e9 100644 --- a/app/controllers/api/v1/base_controller.rb +++ b/app/controllers/api/v1/base_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Api module V1 class BaseController < ApiController diff --git a/app/controllers/api/v1/inventory_items_controller.rb b/app/controllers/api/v1/inventory_items_controller.rb index e695e6838..f22f1462f 100644 --- a/app/controllers/api/v1/inventory_items_controller.rb +++ b/app/controllers/api/v1/inventory_items_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Api module V1 class InventoryItemsController < BaseController diff --git a/app/serializers/api/v1/inventory_cell_serializer.rb b/app/serializers/api/v1/inventory_cell_serializer.rb index ea25ae20c..15c3d4e67 100644 --- a/app/serializers/api/v1/inventory_cell_serializer.rb +++ b/app/serializers/api/v1/inventory_cell_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Api module V1 class InventoryCellSerializer < ActiveModel::Serializer diff --git a/app/serializers/api/v1/inventory_serializer.rb b/app/serializers/api/v1/inventory_serializer.rb index d976bcd2e..de3186dc7 100644 --- a/app/serializers/api/v1/inventory_serializer.rb +++ b/app/serializers/api/v1/inventory_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Api module V1 class InventorySerializer < ActiveModel::Serializer diff --git a/app/serializers/api/v1/repository_list_value_serializer.rb b/app/serializers/api/v1/repository_list_value_serializer.rb index 7c7ac7a90..6807a34ff 100644 --- a/app/serializers/api/v1/repository_list_value_serializer.rb +++ b/app/serializers/api/v1/repository_list_value_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Api module V1 class RepositoryListValueSerializer < ActiveModel::Serializer diff --git a/app/serializers/api/v1/repository_text_value_serializer.rb b/app/serializers/api/v1/repository_text_value_serializer.rb index 85a6be185..ea1a51da0 100644 --- a/app/serializers/api/v1/repository_text_value_serializer.rb +++ b/app/serializers/api/v1/repository_text_value_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Api module V1 class RepositoryTextValueSerializer < ActiveModel::Serializer diff --git a/app/serializers/api/v1/team_serializer.rb b/app/serializers/api/v1/team_serializer.rb index 692b66538..ffe94acc0 100644 --- a/app/serializers/api/v1/team_serializer.rb +++ b/app/serializers/api/v1/team_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Api module V1 class TeamSerializer < ActiveModel::Serializer diff --git a/config/initializers/active_model_serializer.rb b/config/initializers/active_model_serializer.rb index 032c70089..692906d54 100644 --- a/config/initializers/active_model_serializer.rb +++ b/config/initializers/active_model_serializer.rb @@ -1,2 +1,4 @@ +# frozen_string_literal: true + ActiveModelSerializers.config.adapter = :json_api ActiveModelSerializers.config.key_transform = :unaltered diff --git a/db/migrate/20180806115201_change_primary_key_to_bigint_on_repositories.rb b/db/migrate/20180806115201_change_primary_key_to_bigint_on_repositories.rb index fb7fc0b55..23eba49f8 100644 --- a/db/migrate/20180806115201_change_primary_key_to_bigint_on_repositories.rb +++ b/db/migrate/20180806115201_change_primary_key_to_bigint_on_repositories.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ChangePrimaryKeyToBigintOnRepositories < ActiveRecord::Migration[5.1] def up change_column :repository_rows, :id, :bigint diff --git a/spec/requests/api/v1/inventories_controller_spec.rb b/spec/requests/api/v1/inventories_controller_spec.rb index 363661571..bfdbefcc2 100644 --- a/spec/requests/api/v1/inventories_controller_spec.rb +++ b/spec/requests/api/v1/inventories_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe "Api::V1::InventoriesController", type: :request do diff --git a/spec/requests/api/v1/inventory_items_controller_spec.rb b/spec/requests/api/v1/inventory_items_controller_spec.rb index 425eaa52f..379b15385 100644 --- a/spec/requests/api/v1/inventory_items_controller_spec.rb +++ b/spec/requests/api/v1/inventory_items_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe "Api::V1::InventoryItemsController", type: :request do +RSpec.describe 'Api::V1::InventoryItemsController', type: :request do before :all do @user = create(:user) @teams = create_list(:team, 2, created_by: @user) From 6c59e1e159d8b5c635f105f2875bda5662cb6b75 Mon Sep 17 00:00:00 2001 From: Oleksii Kriuchykhin Date: Tue, 7 Aug 2018 16:02:14 +0200 Subject: [PATCH 4/6] Fix failing tests [SCI-2614][SCI-2616][SCI-2617] --- app/models/repository_cell.rb | 8 ++++---- spec/rails_helper.rb | 8 -------- spec/requests/api/v1/inventory_items_controller_spec.rb | 2 +- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/app/models/repository_cell.rb b/app/models/repository_cell.rb index f86c291e2..ab2759573 100644 --- a/app/models/repository_cell.rb +++ b/app/models/repository_cell.rb @@ -8,25 +8,25 @@ class RepositoryCell < ActiveRecord::Base dependent: :destroy belongs_to :repository_text_value, (lambda do - joins(:repository_cell) + includes(:repository_cell) .where(repository_cells: { value_type: 'RepositoryTextValue' }) end), optional: true, foreign_key: :value_id belongs_to :repository_date_value, (lambda do - joins(:repository_cell) + includes(:repository_cell) .where(repository_cells: { value_type: 'RepositoryDateValue' }) end), optional: true, foreign_key: :value_id belongs_to :repository_list_value, (lambda do - joins(:repository_cell) + includes(:repository_cell) .where(repository_cells: { value_type: 'RepositoryListValue' }) end), optional: true, foreign_key: :value_id belongs_to :repository_asset_value, (lambda do - joins(:repository_cell) + includes(:repository_cell) .where(repository_cells: { value_type: 'RepositoryAssetValue' }) end), optional: true, foreign_key: :value_id diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 8d77cc69f..79e319489 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -71,14 +71,6 @@ RSpec.configure do |config| DatabaseCleaner.clean end - config.before(:all) do - DatabaseCleaner.start - end - - config.after(:all) do - DatabaseCleaner.clean - end - config.around(:each, type: :background_job) do |example| run_background_jobs_immediately do example.run diff --git a/spec/requests/api/v1/inventory_items_controller_spec.rb b/spec/requests/api/v1/inventory_items_controller_spec.rb index 379b15385..80e28fc80 100644 --- a/spec/requests/api/v1/inventory_items_controller_spec.rb +++ b/spec/requests/api/v1/inventory_items_controller_spec.rb @@ -70,7 +70,7 @@ RSpec.describe 'Api::V1::InventoryItemsController', type: :request do ) end - it 'Response with correct inventory items, 30 per page' do + it 'Response with correct inventory items, 100 per page' do hash_body = nil get api_v1_team_inventory_items_path( team_id: @teams.first.id, From 5efcacbf3d04c11a99993812779a1b66320e9bf2 Mon Sep 17 00:00:00 2001 From: Oleksii Kriuchykhin Date: Wed, 8 Aug 2018 17:15:08 +0200 Subject: [PATCH 5/6] Rename type for rows and cells serializers [SCI-2614][SCI-2616][SCI-2617] --- app/serializers/api/v1/inventory_cell_serializer.rb | 5 ++--- app/serializers/api/v1/inventory_item_serializer.rb | 1 + app/serializers/api/v1/repository_list_value_serializer.rb | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/serializers/api/v1/inventory_cell_serializer.rb b/app/serializers/api/v1/inventory_cell_serializer.rb index 15c3d4e67..ff478c9d9 100644 --- a/app/serializers/api/v1/inventory_cell_serializer.rb +++ b/app/serializers/api/v1/inventory_cell_serializer.rb @@ -3,10 +3,9 @@ module Api module V1 class InventoryCellSerializer < ActiveModel::Serializer - attribute :id + type :inventory_cells + attributes :id, :data_type, :data attribute :repository_column_id, key: :column_id - attribute :data_type - attribute :data def data_type type_id = RepositoryColumn diff --git a/app/serializers/api/v1/inventory_item_serializer.rb b/app/serializers/api/v1/inventory_item_serializer.rb index 733e87a32..05a1b3d90 100644 --- a/app/serializers/api/v1/inventory_item_serializer.rb +++ b/app/serializers/api/v1/inventory_item_serializer.rb @@ -3,6 +3,7 @@ module Api module V1 class InventoryItemSerializer < ActiveModel::Serializer + type :inventory_items attributes :id, :name has_many :repository_cells, key: :inventory_cells, serializer: InventoryCellSerializer, diff --git a/app/serializers/api/v1/repository_list_value_serializer.rb b/app/serializers/api/v1/repository_list_value_serializer.rb index 6807a34ff..6360b529d 100644 --- a/app/serializers/api/v1/repository_list_value_serializer.rb +++ b/app/serializers/api/v1/repository_list_value_serializer.rb @@ -4,7 +4,7 @@ module Api module V1 class RepositoryListValueSerializer < ActiveModel::Serializer attribute :formatted, key: :value - attribute :repository_list_item_id, key: :list_item_id + attribute :repository_list_item_id, key: :inventory_list_item_id end end end From 3f7590bb57651c3201ae7b501955e83eb2ebfd86 Mon Sep 17 00:00:00 2001 From: Oleksii Kriuchykhin Date: Fri, 10 Aug 2018 16:59:06 +0200 Subject: [PATCH 6/6] Rename type for inventories and add mimetype for JSON API [SCI-2614][SCI-2616][SCI-2617] --- app/serializers/api/v1/inventory_serializer.rb | 1 + config/initializers/mime_types.rb | 1 + 2 files changed, 2 insertions(+) diff --git a/app/serializers/api/v1/inventory_serializer.rb b/app/serializers/api/v1/inventory_serializer.rb index de3186dc7..dfe55f534 100644 --- a/app/serializers/api/v1/inventory_serializer.rb +++ b/app/serializers/api/v1/inventory_serializer.rb @@ -3,6 +3,7 @@ module Api module V1 class InventorySerializer < ActiveModel::Serializer + type :inventories attributes :id, :name end end diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb index dc1899682..72b582a0a 100644 --- a/config/initializers/mime_types.rb +++ b/config/initializers/mime_types.rb @@ -2,3 +2,4 @@ # Add new mime types for use in respond_to blocks: # Mime::Type.register "text/richtext", :rtf +Mime::Type.register 'application/vnd.api+json', :json