mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-09-20 14:45:56 +08:00
Mergre latest core-api [SCI-2515]
This commit is contained in:
commit
49e788a9ad
1
Gemfile
1
Gemfile
|
@ -54,7 +54,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'
|
||||
|
|
|
@ -115,6 +115,7 @@
|
|||
RepositoryItemEditForm.prototype.parseToFormObject = function(tableID, selectedRecord) {
|
||||
var formData = this.formData;
|
||||
var formDataObj = new FormData();
|
||||
var removeFileColumns = [];
|
||||
formDataObj.append('request_url', $(tableID).data('current-uri'));
|
||||
formDataObj.append('repository_row_id', $(selectedRecord).attr('id'));
|
||||
|
||||
|
@ -125,18 +126,25 @@
|
|||
} else {
|
||||
var colId = element.replace('colId-', '');
|
||||
var $el = $('#' + element);
|
||||
if($el.attr('type') === 'file') {
|
||||
// don't save anything if element is deleted
|
||||
if($el.attr('remove') === "true") {
|
||||
// don't save anything if element is not visible
|
||||
if($el.length == 0) {
|
||||
return true;
|
||||
}
|
||||
if($el.attr('type') === 'file') {
|
||||
// handle deleting of element
|
||||
if($el.attr('remove') === "true") {
|
||||
removeFileColumns.push(colId);
|
||||
formDataObj.append('repository_cells[' + colId + ']', null);
|
||||
} else {
|
||||
formDataObj.append('repository_cells[' + colId + ']',
|
||||
getFileValue($el));
|
||||
} else if(value.length > 0) {
|
||||
}
|
||||
} else if(value.length >= 0) {
|
||||
formDataObj.append('repository_cells[' + colId + ']', value);
|
||||
}
|
||||
}
|
||||
});
|
||||
formDataObj.append('remove_file_columns', JSON.stringify(removeFileColumns));
|
||||
return formDataObj;
|
||||
}
|
||||
/**
|
||||
|
|
|
@ -270,7 +270,7 @@
|
|||
function _uploadedAssetPreview(asset, i) {
|
||||
var html = '<div class="panel panel-default panel-step-attachment-new">';
|
||||
html += '<div class="panel-heading">';
|
||||
html += '<span class="fas fa-file"></span>';
|
||||
html += '<span class="fas fa-paperclip"></span>';
|
||||
html += '<%= I18n.t 'assets.drag_n_drop.file_label' %>';
|
||||
html += '<div class="pull-right">';
|
||||
html += '<a data-item-id="' + i + '" href="#">';
|
||||
|
@ -442,7 +442,7 @@
|
|||
function _uploadedAssetPreview(asset, i) {
|
||||
var html = '<div class="panel panel-default panel-result-attachment-new">';
|
||||
html += '<div class="panel-heading">';
|
||||
html += '<span class="fas fa-file"></span>';
|
||||
html += '<span class="fas fa-paperclip"></span>';
|
||||
html += '<%= I18n.t 'assets.drag_n_drop.file_label' %>';
|
||||
html += '<div class="pull-right">';
|
||||
html += '<a data-item-id="' + i + '" href="#">';
|
||||
|
|
|
@ -164,8 +164,10 @@
|
|||
}
|
||||
|
||||
function initializeModalsToggle() {
|
||||
$("[data-trigger='invite-users']").on('click', function() {
|
||||
$("[data-trigger='invite-users']").on('click', function(event) {
|
||||
var id = $(this).attr('data-modal-id');
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
$('[data-role=invite-users-modal][data-id=' + id + ']')
|
||||
.modal('show');
|
||||
});
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
//= require users/settings/teams/invite_users_modal
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ class ActivitiesController < ApplicationController
|
|||
activities = current_user.last_activities
|
||||
.page(page)
|
||||
.per(Constants::ACTIVITY_AND_NOTIF_SEARCH_LIMIT)
|
||||
unless activities.last_page?
|
||||
unless activities.blank? || activities.last_page?
|
||||
more_url = url_for(
|
||||
activities_url(
|
||||
format: :json,
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class BaseController < ApiController
|
||||
rescue_from ActionController::ParameterMissing do |e|
|
||||
logger.error e.message
|
||||
render json: {}, status: :bad_request
|
||||
render jsonapi: {}, status: :bad_request
|
||||
end
|
||||
|
||||
rescue_from ActiveRecord::RecordNotFound do |e|
|
||||
logger.error e.message
|
||||
render json: {}, status: :not_found
|
||||
render jsonapi: {}, status: :not_found
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
59
app/controllers/api/v1/connections_controller.rb
Normal file
59
app/controllers/api/v1/connections_controller.rb
Normal file
|
@ -0,0 +1,59 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class ConnectionsController < BaseController
|
||||
before_action :load_team
|
||||
before_action :load_project
|
||||
before_action :load_experiment
|
||||
before_action :load_connections
|
||||
before_action :load_connection, only: :show
|
||||
|
||||
def index
|
||||
@connections = @connections.page(params.dig(:page, :number))
|
||||
.per(params.dig(:page, :size))
|
||||
render jsonapi: @connections, each_serializer: ConnectionSerializer
|
||||
end
|
||||
|
||||
def show
|
||||
render jsonapi: @connection, serializer: ConnectionSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_team
|
||||
@team = Team.find(params.require(:team_id))
|
||||
render jsonapi: {}, status: :forbidden unless can_read_team?(@team)
|
||||
end
|
||||
|
||||
def load_project
|
||||
@project = @team.projects.find(params.require(:project_id))
|
||||
render jsonapi: {}, status: :forbidden unless can_read_project?(
|
||||
@project
|
||||
)
|
||||
end
|
||||
|
||||
def load_experiment
|
||||
@experiment = @project.experiments.find(params.require(:experiment_id))
|
||||
render jsonapi: {}, status: :forbidden unless can_read_experiment?(
|
||||
@experiment
|
||||
)
|
||||
end
|
||||
|
||||
def load_connections
|
||||
@connections = Connection.joins(
|
||||
'LEFT JOIN my_modules AS inputs ON input_id = inputs.id'
|
||||
).joins(
|
||||
'LEFT JOIN my_modules AS outputs ON output_id = outputs.id'
|
||||
).where(
|
||||
'inputs.experiment_id = ? OR outputs.experiment_id = ?',
|
||||
@experiment.id, @experiment.id
|
||||
)
|
||||
end
|
||||
|
||||
def load_connection
|
||||
@connection = @connections.find(params.require(:id))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
43
app/controllers/api/v1/experiments_controller.rb
Normal file
43
app/controllers/api/v1/experiments_controller.rb
Normal file
|
@ -0,0 +1,43 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class ExperimentsController < BaseController
|
||||
before_action :load_team
|
||||
before_action :load_project
|
||||
before_action :load_experiment, only: :show
|
||||
|
||||
def index
|
||||
experiments = @project.experiments
|
||||
.page(params.dig(:page, :number))
|
||||
.per(params.dig(:page, :size))
|
||||
render jsonapi: experiments, each_serializer: ExperimentSerializer
|
||||
end
|
||||
|
||||
def show
|
||||
render jsonapi: @experiment, serializer: ExperimentSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_team
|
||||
@team = Team.find(params.require(:team_id))
|
||||
render jsonapi: {}, status: :forbidden unless can_read_team?(@team)
|
||||
end
|
||||
|
||||
def load_project
|
||||
@project = @team.projects.find(params.require(:project_id))
|
||||
render jsonapi: {}, status: :forbidden unless can_read_project?(
|
||||
@project
|
||||
)
|
||||
end
|
||||
|
||||
def load_experiment
|
||||
@experiment = @project.experiments.find(params.require(:id))
|
||||
render jsonapi: {}, status: :forbidden unless can_read_experiment?(
|
||||
@experiment
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
77
app/controllers/api/v1/inventories_controller.rb
Normal file
77
app/controllers/api/v1/inventories_controller.rb
Normal file
|
@ -0,0 +1,77 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class InventoriesController < BaseController
|
||||
before_action :load_team
|
||||
before_action :load_inventory, only: %i(show update destroy)
|
||||
before_action :check_manage_permissions, only: %i(create update destroy)
|
||||
|
||||
def index
|
||||
inventories = @team.repositories
|
||||
.page(params.dig(:page, :number))
|
||||
.per(params.dig(:page, :size))
|
||||
render jsonapi: inventories, each_serializer: InventorySerializer
|
||||
end
|
||||
|
||||
def create
|
||||
inventory = @team.repositories.create!(inventory_params)
|
||||
render jsonapi: inventory,
|
||||
serializer: InventorySerializer,
|
||||
status: :created
|
||||
end
|
||||
|
||||
def show
|
||||
render jsonapi: @inventory, serializer: InventorySerializer
|
||||
end
|
||||
|
||||
def update
|
||||
@inventory.attributes = update_inventory_params
|
||||
if @inventory.changed? && @inventory.save!
|
||||
render jsonapi: @inventory, serializer: InventorySerializer
|
||||
else
|
||||
render body: nil
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@inventory.destroy!
|
||||
render body: nil
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_team
|
||||
@team = Team.find(params.require(:team_id))
|
||||
render jsonapi: {}, status: :forbidden unless can_read_team?(@team)
|
||||
end
|
||||
|
||||
def load_inventory
|
||||
@inventory = @team.repositories.find(params.require(:id))
|
||||
end
|
||||
|
||||
def check_manage_permissions
|
||||
unless can_manage_repository?(@inventory)
|
||||
render body: nil, status: :forbidden
|
||||
end
|
||||
end
|
||||
|
||||
def inventory_params
|
||||
unless params.require(:data).require(:type) == 'inventories'
|
||||
raise ActionController::BadRequest,
|
||||
'Wrong object type within parameters'
|
||||
end
|
||||
params.require(:data).require(:attributes)
|
||||
params.permit(data: { attributes: %i(name) })[:data]
|
||||
end
|
||||
|
||||
def update_inventory_params
|
||||
unless params.require(:data).require(:id).to_i == params[:id].to_i
|
||||
raise ActionController::BadRequest,
|
||||
'Object ID mismatch in URL and request body'
|
||||
end
|
||||
inventory_params[:attributes]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
89
app/controllers/api/v1/inventory_columns_controller.rb
Normal file
89
app/controllers/api/v1/inventory_columns_controller.rb
Normal file
|
@ -0,0 +1,89 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class InventoryColumnsController < BaseController
|
||||
before_action :load_team
|
||||
before_action :load_inventory
|
||||
before_action :load_inventory_column, only: %i(show update destroy)
|
||||
before_action :check_manage_permissions, only: %i(update destroy)
|
||||
|
||||
def index
|
||||
columns = @inventory.repository_columns
|
||||
.includes(:repository_list_items)
|
||||
.page(params.dig(:page, :number))
|
||||
.per(params.dig(:page, :size))
|
||||
render jsonapi: columns, each_serializer: InventoryColumnSerializer,
|
||||
include: :inventory_list_items
|
||||
end
|
||||
|
||||
def create
|
||||
inventory_column =
|
||||
@inventory.repository_columns.create!(inventory_column_params)
|
||||
render jsonapi: inventory_column,
|
||||
serializer: InventoryColumnSerializer,
|
||||
status: :created
|
||||
end
|
||||
|
||||
def show
|
||||
render jsonapi: @inventory_column, serializer: InventoryColumnSerializer
|
||||
end
|
||||
|
||||
def update
|
||||
@inventory_column.attributes = update_inventory_column_params
|
||||
if @inventory_column.changed? && @inventory_column.save!
|
||||
render jsonapi: @inventory_column,
|
||||
serializer: InventoryColumnSerializer
|
||||
else
|
||||
render body: nil
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@inventory_column.destroy!
|
||||
render body: nil
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_team
|
||||
@team = Team.find(params.require(:team_id))
|
||||
render jsonapi: {}, status: :forbidden unless can_read_team?(@team)
|
||||
end
|
||||
|
||||
def load_inventory
|
||||
@inventory = @team.repositories.find(params.require(:inventory_id))
|
||||
end
|
||||
|
||||
def load_inventory_column
|
||||
@inventory_column = @inventory.repository_columns
|
||||
.find(params.require(:id))
|
||||
end
|
||||
|
||||
def check_manage_permissions
|
||||
unless can_manage_repository_column?(@inventory_column)
|
||||
render body: nil, status: :forbidden
|
||||
end
|
||||
end
|
||||
|
||||
def inventory_column_params
|
||||
unless params.require(:data).require(:type) == 'inventory_columns'
|
||||
raise ActionController::BadRequest,
|
||||
'Wrong object type within parameters'
|
||||
end
|
||||
params.require(:data).require(:attributes)
|
||||
params
|
||||
.permit(data: { attributes: %i(name data_type) })[:data]
|
||||
.merge(created_by: @current_user)
|
||||
end
|
||||
|
||||
def update_inventory_column_params
|
||||
unless params.require(:data).require(:id).to_i == params[:id].to_i
|
||||
raise ActionController::BadRequest,
|
||||
'Object ID mismatch in URL and request body'
|
||||
end
|
||||
inventory_column_params[:attributes]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
139
app/controllers/api/v1/inventory_items_controller.rb
Normal file
139
app/controllers/api/v1/inventory_items_controller.rb
Normal file
|
@ -0,0 +1,139 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class InventoryItemsController < BaseController
|
||||
before_action :load_team
|
||||
before_action :load_inventory
|
||||
before_action :load_inventory_item, only: %i(show update destroy)
|
||||
before_action :check_manage_permissions, only: %i(create update destroy)
|
||||
|
||||
def index
|
||||
items =
|
||||
@inventory.repository_rows
|
||||
.includes(repository_cells: :repository_column)
|
||||
.includes(
|
||||
repository_cells: Extends::REPOSITORY_SEARCH_INCLUDES
|
||||
).page(params.dig(:page, :number))
|
||||
.per(params.dig(:page, :size))
|
||||
render jsonapi: items,
|
||||
each_serializer: InventoryItemSerializer,
|
||||
include: :inventory_cells
|
||||
end
|
||||
|
||||
def create
|
||||
attributes = inventory_item_params.merge(
|
||||
created_by: current_user,
|
||||
last_modified_by: current_user
|
||||
)
|
||||
if inventory_cells_params.present?
|
||||
inventory_cells_params
|
||||
.each { |p| p.require(:attributes).require(%i(column_id value)) }
|
||||
item = @inventory.repository_rows.new(attributes)
|
||||
item.transaction do
|
||||
item.save!
|
||||
inventory_cells_params.each do |cell_params|
|
||||
cell_attributes = cell_params[:attributes]
|
||||
column =
|
||||
@inventory.repository_columns.find(cell_attributes[:column_id])
|
||||
RepositoryCell.create_with_value!(
|
||||
item, column, cell_attributes[:value], current_user
|
||||
)
|
||||
end
|
||||
end
|
||||
else
|
||||
item = @inventory.repository_rows.create!(attributes)
|
||||
end
|
||||
render jsonapi: item,
|
||||
serializer: InventoryItemSerializer,
|
||||
include: :inventory_cells,
|
||||
status: :created
|
||||
end
|
||||
|
||||
def show
|
||||
render jsonapi: @inventory_item,
|
||||
serializer: InventoryItemSerializer,
|
||||
include: :inventory_cells
|
||||
end
|
||||
|
||||
def update
|
||||
item_changed = false
|
||||
if inventory_cells_params.present?
|
||||
inventory_cells_params.each do |p|
|
||||
p.require(%i(id attributes))
|
||||
p.require(:attributes).require(:value)
|
||||
end
|
||||
@inventory_item.transaction do
|
||||
inventory_cells_params.each do |cell_params|
|
||||
cell = @inventory_item.repository_cells.find(cell_params[:id])
|
||||
cell_value = cell_params.dig(:attributes, :value)
|
||||
next unless cell.value.data_changed?(cell_value)
|
||||
cell.value.update_data!(cell_value, current_user)
|
||||
item_changed = true
|
||||
end
|
||||
end
|
||||
end
|
||||
@inventory_item.attributes = update_inventory_item_params
|
||||
item_changed = true if @inventory_item.changed?
|
||||
if item_changed
|
||||
@inventory_item.last_modified_by = current_user
|
||||
@inventory_item.save!
|
||||
render jsonapi: @inventory_item,
|
||||
serializer: InventoryItemSerializer,
|
||||
include: :inventory_cells
|
||||
else
|
||||
render body: nil
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@inventory_item.destroy!
|
||||
render body: nil
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_team
|
||||
@team = Team.find(params.require(:team_id))
|
||||
render jsonapi: {}, status: :forbidden unless can_read_team?(@team)
|
||||
end
|
||||
|
||||
def load_inventory
|
||||
@inventory = @team.repositories.find(params.require(:inventory_id))
|
||||
end
|
||||
|
||||
def load_inventory_item
|
||||
@inventory_item = @inventory.repository_rows.find(params[:id].to_i)
|
||||
end
|
||||
|
||||
def check_manage_permissions
|
||||
unless can_manage_repository_rows?(@team)
|
||||
render body: nil, status: :forbidden
|
||||
end
|
||||
end
|
||||
|
||||
def inventory_item_params
|
||||
unless params.require(:data).require(:type) == 'inventory_items'
|
||||
raise ActionController::BadRequest,
|
||||
'Wrong object type within parameters'
|
||||
end
|
||||
params.require(:data).require(:attributes)
|
||||
params.permit(data: { attributes: %i(name uid) })[:data]
|
||||
end
|
||||
|
||||
def update_inventory_item_params
|
||||
unless params.require(:data).require(:id).to_i == params[:id].to_i
|
||||
raise ActionController::BadRequest,
|
||||
'Object ID mismatch in URL and request body'
|
||||
end
|
||||
inventory_item_params[:attributes]
|
||||
end
|
||||
|
||||
# Partially implement sideposting draft
|
||||
# https://github.com/json-api/json-api/pull/1197
|
||||
def inventory_cells_params
|
||||
params[:included]&.select { |el| el[:type] == 'inventory_cells' }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
52
app/controllers/api/v1/my_module_groups_controller.rb
Normal file
52
app/controllers/api/v1/my_module_groups_controller.rb
Normal file
|
@ -0,0 +1,52 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class MyModuleGroupsController < BaseController
|
||||
before_action :load_team
|
||||
before_action :load_project
|
||||
before_action :load_experiment
|
||||
before_action :load_task_group, only: :show
|
||||
|
||||
def index
|
||||
my_module_groups = @experiment.my_module_groups
|
||||
.page(params.dig(:page, :number))
|
||||
.per(params.dig(:page, :size))
|
||||
|
||||
render jsonapi: my_module_groups,
|
||||
each_serializer: MyModuleGroupSerializer
|
||||
end
|
||||
|
||||
def show
|
||||
render jsonapi: @my_module_group, serializer: MyModuleGroupSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_team
|
||||
@team = Team.find(params.require(:team_id))
|
||||
render jsonapi: {}, status: :forbidden unless can_read_team?(@team)
|
||||
end
|
||||
|
||||
def load_project
|
||||
@project = @team.projects.find(params.require(:project_id))
|
||||
render jsonapi: {}, status: :forbidden unless can_read_project?(
|
||||
@project
|
||||
)
|
||||
end
|
||||
|
||||
def load_experiment
|
||||
@experiment = @project.experiments.find(params.require(:experiment_id))
|
||||
render jsonapi: {}, status: :forbidden unless can_read_experiment?(
|
||||
@experiment
|
||||
)
|
||||
end
|
||||
|
||||
def load_task_group
|
||||
@my_module_group = @experiment.my_module_groups.find(
|
||||
params.require(:id)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
50
app/controllers/api/v1/my_modules_controller.rb
Normal file
50
app/controllers/api/v1/my_modules_controller.rb
Normal file
|
@ -0,0 +1,50 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class MyModulesController < BaseController
|
||||
before_action :load_team
|
||||
before_action :load_project
|
||||
before_action :load_experiment
|
||||
before_action :load_task, only: :show
|
||||
|
||||
def index
|
||||
tasks = @experiment.my_modules
|
||||
.page(params.dig(:page, :number))
|
||||
.per(params.dig(:page, :size))
|
||||
|
||||
render jsonapi: tasks, each_serializer: MyModuleSerializer
|
||||
end
|
||||
|
||||
def show
|
||||
render jsonapi: @my_module, serializer: MyModuleSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_team
|
||||
@team = Team.find(params.require(:team_id))
|
||||
render jsonapi: {}, status: :forbidden unless can_read_team?(@team)
|
||||
end
|
||||
|
||||
def load_project
|
||||
@project = @team.projects.find(params.require(:project_id))
|
||||
render jsonapi: {}, status: :forbidden unless can_read_project?(
|
||||
@project
|
||||
)
|
||||
end
|
||||
|
||||
def load_experiment
|
||||
@experiment = @project.experiments.find(params.require(:experiment_id))
|
||||
render jsonapi: {}, status: :forbidden unless can_read_experiment?(
|
||||
@experiment
|
||||
)
|
||||
end
|
||||
|
||||
def load_task
|
||||
@my_module = @experiment.my_modules.find(params.require(:id))
|
||||
render jsonapi: {}, status: :not_found if @my_module.nil?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,23 +1,26 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class TeamsController < BaseController
|
||||
before_action :load_team, only: :show
|
||||
|
||||
def index
|
||||
teams = current_user.teams.page(params[:page]).per(params[:page_size])
|
||||
render json: teams, each_serializer: TeamSerializer
|
||||
teams = current_user.teams
|
||||
.page(params.dig(:page, :number))
|
||||
.per(params.dig(:page, :size))
|
||||
render jsonapi: teams, each_serializer: TeamSerializer
|
||||
end
|
||||
|
||||
def show
|
||||
render json: @team, serializer: TeamSerializer
|
||||
render jsonapi: @team, serializer: TeamSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
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)
|
||||
render jsonapi: {}, status: :forbidden unless can_read_team?(@team)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
70
app/controllers/api/v1/user_identities_controller.rb
Normal file
70
app/controllers/api/v1/user_identities_controller.rb
Normal file
|
@ -0,0 +1,70 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class UserIdentitiesController < BaseController
|
||||
before_action :load_user
|
||||
before_action :load_user_identity, only: %i(show update destroy)
|
||||
|
||||
def index
|
||||
identities = @user.user_identities
|
||||
.page(params.dig(:page, :number))
|
||||
.per(params.dig(:page, :size))
|
||||
render jsonapi: identities, each_serializer: UserIdentitySerializer
|
||||
end
|
||||
|
||||
def create
|
||||
identity = @user.user_identities.create!(user_identity_params)
|
||||
render jsonapi: identity,
|
||||
serializer: UserIdentitySerializer,
|
||||
status: :created
|
||||
end
|
||||
|
||||
def show
|
||||
render jsonapi: @identity, serializer: UserIdentitySerializer
|
||||
end
|
||||
|
||||
def update
|
||||
@identity.attributes = update_user_identity_params
|
||||
if @identity.changed? && @identity.save!
|
||||
render jsonapi: @identity, serializer: UserIdentitySerializer
|
||||
else
|
||||
render body: nil
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@identity.destroy!
|
||||
render body: nil
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_user
|
||||
@user = current_user if current_user.id == params[:user_id].to_i
|
||||
return render body: nil, status: :forbidden unless @user
|
||||
end
|
||||
|
||||
def load_user_identity
|
||||
@identity = @user.user_identities.find(params[:id].to_i)
|
||||
end
|
||||
|
||||
def user_identity_params
|
||||
unless params.require(:data).require(:type) == 'user_identities'
|
||||
raise ActionController::BadRequest,
|
||||
'Wrong object type within parameters'
|
||||
end
|
||||
params.require(:data).require(:attributes)
|
||||
params.permit(data: { attributes: %i(provider uid) })[:data]
|
||||
end
|
||||
|
||||
def update_user_identity_params
|
||||
unless params.require(:data).require(:id).to_i == params[:id].to_i
|
||||
raise ActionController::BadRequest,
|
||||
'Object ID mismatch in URL and request body'
|
||||
end
|
||||
user_identity_params
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
22
app/controllers/api/v1/users_controller.rb
Normal file
22
app/controllers/api/v1/users_controller.rb
Normal file
|
@ -0,0 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class UsersController < BaseController
|
||||
before_action :load_user, only: :show
|
||||
|
||||
def show
|
||||
render jsonapi: @user, serializer: UserSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_user
|
||||
@user = User.joins(:user_teams)
|
||||
.where('user_teams.team': current_user.teams)
|
||||
.find_by_id(params[:id])
|
||||
render jsonapi: {}, status: :forbidden unless @user
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -134,7 +134,7 @@ class RepositoryRowsController < ApplicationController
|
|||
existing.delete
|
||||
end
|
||||
elsif existing.value_type == 'RepositoryAssetValue'
|
||||
next if value.blank?
|
||||
existing.value.destroy && next if remove_file_columns_params.include?(key)
|
||||
if existing.value.asset.update(file: value)
|
||||
existing.value.asset.created_by = current_user
|
||||
existing.value.asset.last_modified_by = current_user
|
||||
|
@ -145,6 +145,7 @@ class RepositoryRowsController < ApplicationController
|
|||
}
|
||||
end
|
||||
else
|
||||
existing.value.destroy && next if value == ''
|
||||
existing.value.data = value
|
||||
if existing.value.save
|
||||
record_annotation_notification(@record, existing)
|
||||
|
@ -156,17 +157,12 @@ class RepositoryRowsController < ApplicationController
|
|||
end
|
||||
end
|
||||
else
|
||||
next if value == ''
|
||||
# Looks like it is a new cell, so we need to create new value, cell
|
||||
# will be created automatically
|
||||
next if create_cell_value(@record, key, value, errors).nil?
|
||||
end
|
||||
end
|
||||
# Clean up empty cells, not present in updated record
|
||||
@record.repository_cells.each do |cell|
|
||||
next if cell.value_type == 'RepositoryListValue'
|
||||
cell.value.destroy unless cell_params
|
||||
.key?(cell.repository_column_id.to_s)
|
||||
end
|
||||
else
|
||||
@record.repository_cells.each { |c| c.value.destroy }
|
||||
end
|
||||
|
@ -369,6 +365,10 @@ class RepositoryRowsController < ApplicationController
|
|||
params.permit(repository_cells: {}).to_h[:repository_cells]
|
||||
end
|
||||
|
||||
def remove_file_columns_params
|
||||
JSON.parse(params.fetch(:remove_file_columns) { '[]' })
|
||||
end
|
||||
|
||||
def selected_params
|
||||
params.permit(selected_rows: []).to_h[:selected_rows]
|
||||
end
|
||||
|
|
|
@ -22,4 +22,32 @@ class RepositoryAssetValue < ApplicationRecord
|
|||
def data
|
||||
asset.file_file_name
|
||||
end
|
||||
|
||||
def data_changed?(_new_data)
|
||||
true
|
||||
end
|
||||
|
||||
def update_data!(new_data, user)
|
||||
file = Paperclip.io_adapters.for(new_data[:file_data])
|
||||
file.original_filename = new_data[:file_name]
|
||||
asset.file = file
|
||||
asset.last_modified_by = user
|
||||
self.last_modified_by = user
|
||||
asset.save! && save!
|
||||
end
|
||||
|
||||
def self.new_with_payload(payload, attributes)
|
||||
value = new(attributes)
|
||||
team = value.repository_cell.repository_column.repository.team
|
||||
file = Paperclip.io_adapters.for(payload[:file_data])
|
||||
file.original_filename = payload[:file_name]
|
||||
value.asset = Asset.create!(
|
||||
file: file,
|
||||
created_by: value.created_by,
|
||||
last_modified_by: value.created_by,
|
||||
team: team
|
||||
)
|
||||
value.asset.post_process_file(team)
|
||||
value
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,31 +8,51 @@ class RepositoryCell < ActiveRecord::Base
|
|||
dependent: :destroy
|
||||
belongs_to :repository_text_value,
|
||||
(lambda do
|
||||
where(repository_cells: { value_type: 'RepositoryTextValue' })
|
||||
includes(: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' })
|
||||
includes(: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' })
|
||||
includes(: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' })
|
||||
includes(:repository_cell)
|
||||
.where(repository_cells: { value_type: 'RepositoryAssetValue' })
|
||||
end),
|
||||
optional: true, foreign_key: :value_id
|
||||
|
||||
validates_inclusion_of :repository_column,
|
||||
in: (lambda do |cell|
|
||||
cell.repository_row.repository.repository_columns
|
||||
end)
|
||||
validates :repository_column, presence: true
|
||||
validate :repository_column_data_type
|
||||
validates :repository_row,
|
||||
uniqueness: { scope: :repository_column },
|
||||
unless: :importing
|
||||
|
||||
def self.create_with_value!(row, column, data, user)
|
||||
cell = new(repository_row: row, repository_column: column)
|
||||
cell.transaction do
|
||||
value_klass = column.data_type.constantize
|
||||
value = value_klass.new_with_payload(data, repository_cell: cell,
|
||||
created_by: user,
|
||||
last_modified_by: user)
|
||||
cell.value = value
|
||||
value.save!
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def repository_column_data_type
|
||||
|
|
|
@ -17,4 +17,20 @@ class RepositoryDateValue < ApplicationRecord
|
|||
def formatted
|
||||
data
|
||||
end
|
||||
|
||||
def data_changed?(new_data)
|
||||
new_data != data
|
||||
end
|
||||
|
||||
def update_data!(new_data, user)
|
||||
self.data = new_data
|
||||
self.last_modified_by = user
|
||||
save!
|
||||
end
|
||||
|
||||
def self.new_with_payload(payload, attributes)
|
||||
value = new(attributes)
|
||||
value.data = payload
|
||||
value
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
class RepositoryListValue < ApplicationRecord
|
||||
belongs_to :repository_list_item,
|
||||
optional: true
|
||||
belongs_to :repository_list_item
|
||||
belongs_to :created_by,
|
||||
foreign_key: :created_by_id,
|
||||
class_name: 'User'
|
||||
|
@ -11,6 +10,12 @@ class RepositoryListValue < ApplicationRecord
|
|||
accepts_nested_attributes_for :repository_cell
|
||||
|
||||
validates :repository_cell, presence: true
|
||||
validates_inclusion_of :repository_list_item,
|
||||
in: (lambda do |list_value|
|
||||
list_value.repository_cell
|
||||
.repository_column
|
||||
.repository_list_items
|
||||
end)
|
||||
|
||||
def formatted
|
||||
data.to_s
|
||||
|
@ -20,4 +25,23 @@ class RepositoryListValue < ApplicationRecord
|
|||
return nil unless repository_list_item
|
||||
repository_list_item.data
|
||||
end
|
||||
|
||||
def data_changed?(new_data)
|
||||
new_data.to_i != repository_list_item_id
|
||||
end
|
||||
|
||||
def update_data!(new_data, user)
|
||||
self.repository_list_item_id = new_data.to_i
|
||||
self.last_modified_by = user
|
||||
save!
|
||||
end
|
||||
|
||||
def self.new_with_payload(payload, attributes)
|
||||
value = new(attributes)
|
||||
value.repository_list_item = value.repository_cell
|
||||
.repository_column
|
||||
.repository_list_items
|
||||
.find(payload)
|
||||
value
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -18,4 +18,20 @@ class RepositoryTextValue < ApplicationRecord
|
|||
def formatted
|
||||
data
|
||||
end
|
||||
|
||||
def data_changed?(new_data)
|
||||
new_data != data
|
||||
end
|
||||
|
||||
def update_data!(new_data, user)
|
||||
self.data = new_data
|
||||
self.last_modified_by = user
|
||||
save!
|
||||
end
|
||||
|
||||
def self.new_with_payload(payload, attributes)
|
||||
value = new(attributes)
|
||||
value.data = payload
|
||||
value
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class UserIdentity < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
validates :provider, uniqueness: { scope: :user_id }
|
||||
validates :uid, uniqueness: { scope: :provider }
|
||||
validates :provider, presence: true, uniqueness: { scope: :user_id }
|
||||
validates :uid, presence: true, uniqueness: { scope: :provider }
|
||||
end
|
||||
|
|
19
app/serializers/api/v1/connection_serializer.rb
Normal file
19
app/serializers/api/v1/connection_serializer.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class ConnectionSerializer < ActiveModel::Serializer
|
||||
type :connections
|
||||
attributes :id, :input_id, :output_id
|
||||
has_one :input_task, serializer: MyModuleSerializer
|
||||
has_one :output_task, serializer: MyModuleSerializer
|
||||
def input_task
|
||||
MyModule.find(object.input_id)
|
||||
end
|
||||
|
||||
def output_task
|
||||
MyModule.find(object.output_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
10
app/serializers/api/v1/experiment_serializer.rb
Normal file
10
app/serializers/api/v1/experiment_serializer.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class ExperimentSerializer < ActiveModel::Serializer
|
||||
type :experiments
|
||||
attributes :id, :name, :description, :archived
|
||||
end
|
||||
end
|
||||
end
|
36
app/serializers/api/v1/inventory_cell_serializer.rb
Normal file
36
app/serializers/api/v1/inventory_cell_serializer.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class InventoryCellSerializer < ActiveModel::Serializer
|
||||
type :inventory_cells
|
||||
attributes :id, :value_type, :value
|
||||
attribute :repository_column_id, key: :column_id
|
||||
|
||||
def value_type
|
||||
type_id = RepositoryColumn
|
||||
.data_types[object.repository_column.data_type]
|
||||
I18n.t("api.v1.inventory_data_types.t#{type_id}")
|
||||
end
|
||||
|
||||
def value
|
||||
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_asset_value
|
||||
end
|
||||
ActiveModelSerializers::SerializableResource.new(
|
||||
value,
|
||||
namespace: Api::V1,
|
||||
adapter: :attribute
|
||||
).as_json
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
19
app/serializers/api/v1/inventory_column_serializer.rb
Normal file
19
app/serializers/api/v1/inventory_column_serializer.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class InventoryColumnSerializer < ActiveModel::Serializer
|
||||
type :inventory_columns
|
||||
attributes :name, :data_type
|
||||
has_many :repository_list_items, key: :inventory_list_items,
|
||||
serializer: InventoryListItemSerializer,
|
||||
class_name: 'RepositoryListItem'
|
||||
|
||||
def data_type
|
||||
type_id = RepositoryColumn
|
||||
.data_types[object.data_type]
|
||||
I18n.t("api.v1.inventory_data_types.t#{type_id}")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
13
app/serializers/api/v1/inventory_item_serializer.rb
Normal file
13
app/serializers/api/v1/inventory_item_serializer.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class InventoryItemSerializer < ActiveModel::Serializer
|
||||
type :inventory_items
|
||||
attributes :name
|
||||
has_many :repository_cells, key: :inventory_cells,
|
||||
serializer: InventoryCellSerializer,
|
||||
class_name: 'RepositoryCell'
|
||||
end
|
||||
end
|
||||
end
|
10
app/serializers/api/v1/inventory_list_item_serializer.rb
Normal file
10
app/serializers/api/v1/inventory_list_item_serializer.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class InventoryListItemSerializer < ActiveModel::Serializer
|
||||
type :inventory_list_items
|
||||
attribute :data
|
||||
end
|
||||
end
|
||||
end
|
10
app/serializers/api/v1/inventory_serializer.rb
Normal file
10
app/serializers/api/v1/inventory_serializer.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class InventorySerializer < ActiveModel::Serializer
|
||||
type :inventories
|
||||
attributes :id, :name
|
||||
end
|
||||
end
|
||||
end
|
11
app/serializers/api/v1/my_module_group_serializer.rb
Normal file
11
app/serializers/api/v1/my_module_group_serializer.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class MyModuleGroupSerializer < ActiveModel::Serializer
|
||||
type :task_groups
|
||||
attributes :id, :experiment_id
|
||||
belongs_to :experiment, serializer: ExperimentSerializer
|
||||
end
|
||||
end
|
||||
end
|
12
app/serializers/api/v1/my_module_serializer.rb
Normal file
12
app/serializers/api/v1/my_module_serializer.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class MyModuleSerializer < ActiveModel::Serializer
|
||||
type :tasks
|
||||
attributes :id, :name, :due_date, :description, :state
|
||||
attribute :my_module_group_id, key: :task_group_id
|
||||
belongs_to :experiment, serializer: ExperimentSerializer
|
||||
end
|
||||
end
|
||||
end
|
32
app/serializers/api/v1/repository_asset_value_serializer.rb
Normal file
32
app/serializers/api/v1/repository_asset_value_serializer.rb
Normal file
|
@ -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
|
10
app/serializers/api/v1/repository_list_value_serializer.rb
Normal file
10
app/serializers/api/v1/repository_list_value_serializer.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class RepositoryListValueSerializer < ActiveModel::Serializer
|
||||
attribute :repository_list_item_id, key: :inventory_list_item_id
|
||||
attribute :formatted, key: :inventory_list_item_name
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class RepositoryTextValueSerializer < ActiveModel::Serializer
|
||||
attribute :formatted, key: :text
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class TeamSerializer < ActiveModel::Serializer
|
||||
|
|
7
app/serializers/api/v1/user_identity_serializer.rb
Normal file
7
app/serializers/api/v1/user_identity_serializer.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
module Api
|
||||
module V1
|
||||
class UserIdentitySerializer < ActiveModel::Serializer
|
||||
attributes :provider, :uid
|
||||
end
|
||||
end
|
||||
end
|
13
app/serializers/api/v1/user_serializer.rb
Normal file
13
app/serializers/api/v1/user_serializer.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
module Api
|
||||
module V1
|
||||
class UserSerializer < ActiveModel::Serializer
|
||||
attributes :full_name, :initials, :email
|
||||
attribute :avatar_file_name,
|
||||
if: -> { object.avatar.present? } { object.avatar_file_name }
|
||||
attribute :avatar_file_size,
|
||||
if: -> { object.avatar.present? } { object.avatar.size }
|
||||
attribute :avatar_url,
|
||||
if: -> { object.avatar.present? } { object.avatar.url(:icon) }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -16,12 +16,14 @@ module Api
|
|||
attr_accessor :core_api_token_ttl
|
||||
attr_accessor :core_api_token_iss
|
||||
attr_accessor :azure_ad_apps
|
||||
attr_accessor :core_api_v1_preview
|
||||
|
||||
def initialize
|
||||
@core_api_sign_alg = 'HS256'
|
||||
@core_api_token_ttl = 30.minutes
|
||||
@core_api_token_iss = 'SciNote'
|
||||
@azure_ad_apps = {}
|
||||
@core_api_v1_preview = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
151
app/services/user_data_deletion.rb
Normal file
151
app/services/user_data_deletion.rb
Normal file
|
@ -0,0 +1,151 @@
|
|||
class UserDataDeletion
|
||||
def self.delete_team_data(team)
|
||||
ActiveRecord::Base.logger = Logger.new(STDOUT)
|
||||
Step.skip_callback(:destroy, :after, :cascade_after_destroy)
|
||||
team.transaction do
|
||||
# Destroy tiny_mce_assets
|
||||
if team.tiny_mce_assets.present?
|
||||
team.tiny_mce_assets.each do |tiny_mce_asset|
|
||||
paperclip_file_destroy(tiny_mce_asset) if tiny_mce_asset.image.exists?
|
||||
end
|
||||
end
|
||||
team.repositories.each do |repository|
|
||||
repository.repository_rows.find_each do |repository_row|
|
||||
# Destroy repository_cell assets
|
||||
repository_row
|
||||
.repository_cells
|
||||
.where(value_type: 'RepositoryAssetValue').each do |repository_cell|
|
||||
next unless repository_cell.value.asset.file.exists?
|
||||
paperclip_file_destroy(repository_cell.value.asset)
|
||||
end
|
||||
end
|
||||
repository.destroy
|
||||
end
|
||||
team.projects.each do |project|
|
||||
project.reports.destroy_all
|
||||
project.activities.destroy_all
|
||||
project.experiments.each do |experiment|
|
||||
experiment.my_modules.each do |my_module|
|
||||
# Destroy result assets
|
||||
my_module.results.each do |result|
|
||||
result.result_table.delete if result.result_table.present?
|
||||
result.table.delete if result.table.present?
|
||||
next unless result.asset && result.asset.file.exists?
|
||||
paperclip_file_destroy(result.asset)
|
||||
end
|
||||
my_module.activities.destroy_all
|
||||
my_module.inputs.destroy_all
|
||||
my_module.outputs.destroy_all
|
||||
my_module.results.destroy_all
|
||||
my_module.my_module_tags.destroy_all
|
||||
my_module.task_comments.destroy_all
|
||||
my_module.my_module_repository_rows.destroy_all
|
||||
my_module.user_my_modules.destroy_all
|
||||
my_module.report_elements.destroy_all
|
||||
my_module.sample_my_modules.destroy_all
|
||||
my_module.protocols.each { |p| p.update_attributes(parent_id: nil) }
|
||||
my_module.protocols.each do |protocol|
|
||||
destroy_protocol(protocol)
|
||||
end
|
||||
my_module.delete
|
||||
end
|
||||
# Destroy workflow image
|
||||
if experiment.workflowimg.exists?
|
||||
experiment.workflowimg.clear(:original)
|
||||
end
|
||||
experiment.activities.destroy_all
|
||||
experiment.report_elements.destroy_all
|
||||
experiment.my_module_groups.delete_all
|
||||
experiment.delete
|
||||
end
|
||||
project.user_projects.destroy_all
|
||||
project.tags.destroy_all
|
||||
project.project_comments.destroy_all
|
||||
project.report_elements.destroy_all
|
||||
|
||||
project.delete
|
||||
end
|
||||
team.protocols.each { |p| p.update_attributes(parent_id: nil) }
|
||||
team.protocols.where(my_module: nil).each do |protocol|
|
||||
destroy_protocol(protocol)
|
||||
end
|
||||
team.samples.destroy_all
|
||||
team.samples_tables.destroy_all
|
||||
team.sample_groups.destroy_all
|
||||
team.sample_types.destroy_all
|
||||
team.custom_fields.destroy_all
|
||||
team.protocol_keywords.destroy_all
|
||||
team.user_teams.delete_all
|
||||
User.where(current_team_id: team).each do |user|
|
||||
user.update(current_team_id: nil)
|
||||
end
|
||||
team.reports.destroy_all
|
||||
team.destroy!
|
||||
# raise ActiveRecord::Rollback
|
||||
end
|
||||
Step.set_callback(:destroy, :after, :cascade_after_destroy)
|
||||
end
|
||||
|
||||
def self.destroy_protocol(protocol)
|
||||
protocol.steps.each do |step|
|
||||
# Destroy step assets
|
||||
if step.assets.present?
|
||||
step.assets.each do |asset|
|
||||
next unless asset.file.present?
|
||||
paperclip_file_destroy(asset)
|
||||
end
|
||||
end
|
||||
# Destroy step
|
||||
step.tables.destroy_all
|
||||
step.step_tables.delete_all
|
||||
step.report_elements.destroy_all
|
||||
step.step_comments.destroy_all
|
||||
step.step_assets.destroy_all
|
||||
step.checklists.destroy_all
|
||||
step.assets.destroy_all
|
||||
step.tiny_mce_assets.destroy_all
|
||||
step.delete
|
||||
end
|
||||
# Destroy protocol
|
||||
protocol.protocol_protocol_keywords.destroy_all
|
||||
protocol.protocol_keywords.destroy_all
|
||||
protocol.delete
|
||||
end
|
||||
|
||||
def self.destroy_notifications(user)
|
||||
# Find all notifications where user is the only reference
|
||||
# on the notification, and destroy all such notifications
|
||||
# (user_notifications are destroyed when notification is
|
||||
# destroyed). We try to do this efficiently (hence in_groups_of).
|
||||
nids_all = user.notifications.pluck(:id)
|
||||
nids_all.in_groups_of(1000, false) do |nids|
|
||||
Notification
|
||||
.where(id: nids)
|
||||
.joins(:user_notifications)
|
||||
.group('notifications.id')
|
||||
.having('count(notification_id) <= 1')
|
||||
.destroy_all
|
||||
end
|
||||
# Now, simply destroy all user notification relations left
|
||||
user.user_notifications.destroy_all
|
||||
end
|
||||
|
||||
# Workaround for Paperclip preserve_files option, to delete files anyway;
|
||||
# if you call #clear with a list of styles to delete,
|
||||
# it'll call #queue_some_for_delete, which doesn't check :preserve_files.
|
||||
def self.paperclip_file_destroy(asset)
|
||||
if asset.class.name == 'TinyMceAsset'
|
||||
all_styles = asset.image.styles.keys.map do |key|
|
||||
asset.image.styles[key].name
|
||||
end << :original
|
||||
asset.image.clear(*all_styles)
|
||||
else
|
||||
all_styles = asset.file.styles.keys.map do |key|
|
||||
asset.file.styles[key].name
|
||||
end << :original
|
||||
asset.file.clear(*all_styles)
|
||||
end
|
||||
asset.save!
|
||||
asset.destroy!
|
||||
end
|
||||
end
|
|
@ -48,10 +48,9 @@ module RepositoryImportParser
|
|||
if @column_list_items_size >= Constants::REPOSITORY_LIST_ITEMS_PER_COLUMN
|
||||
return
|
||||
end
|
||||
item = RepositoryListItem.new(data: value,
|
||||
item = @column.repository_list_items.new(data: value,
|
||||
created_by: @user,
|
||||
last_modified_by: @user,
|
||||
repository_column: @column,
|
||||
repository: @repository)
|
||||
if item.save
|
||||
@column_list_items_size += 1
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
<% if result.asset.is_image? %>
|
||||
<span class="fas fa-image"></span>
|
||||
<% else %>
|
||||
<span class="fas fa-file"></span>
|
||||
<span class="fas fa-paperclip"></span>
|
||||
<% end %>
|
||||
<% elsif result.is_text %>
|
||||
<span class="fas fa-asterisk"></span>
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
<% if can_manage_protocol_in_module?(@protocol) %>
|
||||
<li>
|
||||
<a class="btn-open-file" href="#" data-action="load-from-file" data-import-url="<%= load_from_file_protocol_path(@protocol, format: :json) %>">
|
||||
<span class="fas fa-file"></span> <%= t("my_modules.protocols.buttons.load_protocol_from_file") %>
|
||||
<span class="fas fa-paperclip"></span> <%= t("my_modules.protocols.buttons.load_protocol_from_file") %>
|
||||
<input type="file" value="" accept=".eln" data-turbolinks="false">
|
||||
</a>
|
||||
</li>
|
||||
<% else %>
|
||||
<li class="disabled"><a href="#"><span class="fas fa-file"></span> <%= t("my_modules.protocols.buttons.load_protocol_from_file") %></a></li>
|
||||
<li class="disabled"><a href="#"><span class="fas fa-paperclip"></span> <%= t("my_modules.protocols.buttons.load_protocol_from_file") %></a></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a class="btn-link-alt btn-default-link btn-open-file" <%= can_create_protocols_in_repository?(@current_team) ? 'data-action="import"' : 'disabled="disabled"' %>>
|
||||
<span class="fas fa-file"></span>
|
||||
<span class="fas fa-paperclip"></span>
|
||||
<span class="hidden-xs"><%= t("protocols.index.import_alt") %></span>
|
||||
<input type="file" value="" accept=".eln" data-role="import-file-input"
|
||||
data-team-id="<%= @current_team.id %>"
|
||||
|
@ -70,8 +70,8 @@
|
|||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to "#modal-import-json-protocol", data: { toggle: 'modal', remote: true } do %>
|
||||
<span class="fas fa-file"></span>
|
||||
<%= link_to "#modal-import-json-protocol", data: { toggle: 'modal' } do %>
|
||||
<span class="fas fa-paperclip"></span>
|
||||
<span class="hidden-xs"><%= t("protocols.index.import_json") %></span>
|
||||
<% end %>
|
||||
</li>
|
||||
|
@ -85,7 +85,7 @@
|
|||
|
||||
<div class="btn-group" role="group">
|
||||
<a class="btn btn-default" data-action="archive" data-url="<%= archive_protocols_path %>">
|
||||
<span class="fas fa-briefcase"></span>
|
||||
<span class="fas fa-archive"></span>
|
||||
<span class="hidden-xs"> <%= t("protocols.index.archive_action") %></span>
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
||||
<li><a href="#" data-sort="desc"><%= t('projects.reports.new.nav_sort_desc') %></a></li>
|
||||
<li><a href="#" data-sort="asc"><%= t('projects.reports.new.nav_sort_asc') %></a></li>
|
||||
<li><a href="#" data-sort="desc" data-turbolinks="false"><%= t('projects.reports.new.nav_sort_desc') %></a></li>
|
||||
<li><a href="#" data-sort="asc" data-turbolinks="false"><%= t('projects.reports.new.nav_sort_asc') %></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
|||
<div class="form-group">
|
||||
<%= hidden_field_tag "html", "" %>
|
||||
<%= link_to "", class: "btn btn-default", remote: true, id: "get-report-pdf" do %>
|
||||
<span class="fas fa-file-download"></span>
|
||||
<span class="fas fa-upload"></span>
|
||||
<span class="hidden-xs"><%=t "projects.reports.new.nav_pdf" %></span>
|
||||
<% end %>
|
||||
</div>
|
||||
|
@ -30,6 +30,8 @@
|
|||
<button
|
||||
onclick="$('#savePDFtoInventory').modal('show')"
|
||||
class="btn btn-default">
|
||||
<span class="fas fa-save">
|
||||
</span>
|
||||
<%=t 'projects.reports.new.save_PDF_to_inventory'%>
|
||||
</button>
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@
|
|||
match_case: @search_case, utf8: '✓',
|
||||
search_id: @search_id}.to_query %>">
|
||||
<span class="badge pull-right"><%= @asset_search_count %></span>
|
||||
<span class="fas fa-file"></span>
|
||||
<span class="fas fa-paperclip"></span>
|
||||
<%= t'Assets' %>
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<% if wopi_file?(asset) %>
|
||||
<%= file_extension_icon(asset) %>
|
||||
<% else %>
|
||||
<span class="fas fa-file"></span>
|
||||
<span class="fas fa-paperclip"></span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%= render partial: "search/results/partials/asset_text.html.erb", locals: { asset: asset, query: search_query } %>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<% if result.asset.is_image? %>
|
||||
<span class="fas fa-image"></span>
|
||||
<% else %>
|
||||
<span class="fas fa-file"></span>
|
||||
<span class="fas fa-paperclip"></span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%= render partial: "search/results/partials/result_text.html.erb", locals: { result: result, query: search_query, target: nil } %>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
id="new-step-assets-tab"
|
||||
onClick="dragNdropAssetsInit('steps')">
|
||||
<a href="#new-step-assets" data-toggle="tab" data-no-turbolink="true">
|
||||
<span class="fas fa-file"></span>
|
||||
<span class="fas fa-paperclip"></span>
|
||||
<%= t("protocols.steps.new.tab_assets") %>
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div class="panel panel-default panel-step-attachment">
|
||||
<div class="panel-heading">
|
||||
<span class="fas fa-file"></span>
|
||||
<span class="fas fa-paperclip"></span>
|
||||
<%= t("protocols.steps.new.asset_panel_title") %>
|
||||
<div class="pull-right">
|
||||
<% unless ff.object.file.exists? && ff.object.locked? %>
|
||||
|
|
|
@ -93,7 +93,7 @@
|
|||
<div class="panel-body">
|
||||
<div class="col-xs-24 col-sm-12">
|
||||
<a href="#" class="btn btn-primary pull-right row" data-trigger="invite-users"
|
||||
data-modal-id="team-invite-users-modal" data-remote="true">
|
||||
data-modal-id="team-invite-users-modal">
|
||||
<span class="fas fa-plus"></span>
|
||||
<%= t("users.settings.teams.edit.add_user") %>
|
||||
</a>
|
||||
|
@ -137,4 +137,5 @@
|
|||
<%= render partial: 'users/settings/user_teams/destroy_user_team_modal.html.erb' %>
|
||||
<%= stylesheet_link_tag 'datatables' %>
|
||||
<%= javascript_include_tag 'users/settings/teams/show' %>
|
||||
<%= javascript_include_tag 'users/settings/teams/invite_users_modal' %>
|
||||
<span data-hook="team-bottom"></span>
|
||||
|
|
|
@ -1,2 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'active_model_serializers/register_jsonapi_renderer'
|
||||
|
||||
ActiveModelSerializers.config.adapter = :json_api
|
||||
ActiveModelSerializers.config.key_transform = :unaltered
|
||||
|
|
|
@ -9,6 +9,10 @@ Api.configure do |config|
|
|||
config.core_api_token_iss = ENV['CORE_API_TOKEN_ISS']
|
||||
end
|
||||
|
||||
config.core_api_v1_preview = true if ENV['CORE_API_V1_PREVIEW']
|
||||
|
||||
Paperclip::DataUriAdapter.register if ENV['CORE_API_V1_PREVIEW']
|
||||
|
||||
vars = ENV.select { |name, _| name =~ /^[[:alnum:]]*_AZURE_AD_APP_ID/ }
|
||||
vars.each do |name, value|
|
||||
app_name = name.sub('_AZURE_AD_APP_ID', '')
|
||||
|
|
|
@ -28,6 +28,8 @@ Rails.application.config.assets.precompile +=
|
|||
Rails.application.config.assets.precompile +=
|
||||
%w(users/settings/teams/add_user_modal.js)
|
||||
Rails.application.config.assets.precompile += %w(users/settings/teams/show.js)
|
||||
Rails.application.config.assets.precompile +=
|
||||
%w(users/settings/teams/invite_users_modal.js)
|
||||
Rails.application.config.assets.precompile += %w(my_modules/activities.js)
|
||||
Rails.application.config.assets.precompile += %w(my_modules/protocols.js)
|
||||
Rails.application.config.assets.precompile +=
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -542,8 +542,41 @@ Rails.application.routes.draw do
|
|||
namespace :api, defaults: { format: 'json' } do
|
||||
get 'health', to: 'api#health'
|
||||
get 'status', to: 'api#status'
|
||||
if Api.configuration.core_api_v1_preview
|
||||
namespace :v1 do
|
||||
resources :teams, only: %i(index show) do
|
||||
resources :inventories,
|
||||
only: %i(index create show update destroy) do
|
||||
resources :inventory_columns,
|
||||
only: %i(index create show update destroy),
|
||||
path: 'columns',
|
||||
as: :columns
|
||||
resources :inventory_items,
|
||||
only: %i(index create show update destroy),
|
||||
path: 'items',
|
||||
as: :items
|
||||
end
|
||||
resources :projects, only: %i(index show) do
|
||||
resources :experiments, only: %i(index show) do
|
||||
resources :my_modules,
|
||||
only: %i(index show),
|
||||
path: 'tasks',
|
||||
as: :tasks
|
||||
resources :my_module_groups,
|
||||
only: %i(index show),
|
||||
path: 'task_groups',
|
||||
as: :task_groups
|
||||
resources :connections,
|
||||
only: %i(index show),
|
||||
path: 'connections',
|
||||
as: :connections
|
||||
end
|
||||
end
|
||||
end
|
||||
resources :users, only: %i(show) do
|
||||
resources :user_identities,
|
||||
only: %i(index create show update destroy)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
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
|
16
db/schema.rb
16
db/schema.rb
|
@ -181,7 +181,7 @@ ActiveRecord::Schema.define(version: 20180813120338) 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"
|
||||
|
@ -420,11 +420,11 @@ ActiveRecord::Schema.define(version: 20180813120338) 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"
|
||||
|
@ -432,7 +432,7 @@ ActiveRecord::Schema.define(version: 20180813120338) 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"
|
||||
|
@ -442,7 +442,7 @@ ActiveRecord::Schema.define(version: 20180813120338) 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"
|
||||
|
@ -476,7 +476,7 @@ ActiveRecord::Schema.define(version: 20180813120338) 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
|
||||
|
@ -497,7 +497,7 @@ ActiveRecord::Schema.define(version: 20180813120338) 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"
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -96,4 +96,14 @@ namespace :data do
|
|||
)
|
||||
TeamImporter.new.import_from_dir(args[:dir_path])
|
||||
end
|
||||
|
||||
desc 'Delete team and all data inside the team'
|
||||
task :team_delete, [:team_id] => [:environment] do |_, args|
|
||||
Rails.logger.info(
|
||||
"Deleting team with ID:#{args[:team_id]} and all data inside the team"
|
||||
)
|
||||
team = Team.find_by_id(args[:team_id])
|
||||
raise StandardError, 'Can not load team' unless team
|
||||
UserDataDeletion.delete_team_data(team) if team
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,6 +2,7 @@ FactoryBot.define do
|
|||
factory :repository_row do
|
||||
name 'Custom row'
|
||||
created_by { User.first || association(:user) }
|
||||
repository { Repository.first || create(:repository) }
|
||||
last_modified_by { User.first || association(:user) }
|
||||
end
|
||||
end
|
||||
|
|
6
spec/factories/user_identeties.rb
Normal file
6
spec/factories/user_identeties.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
FactoryBot.define do
|
||||
factory :user_identity do
|
||||
uid Faker::Crypto.unique.sha1
|
||||
provider Faker::App.unique.name
|
||||
end
|
||||
end
|
|
@ -20,13 +20,13 @@ RSpec.describe RepositoryListValue, type: :model do
|
|||
|
||||
describe '#formatted' do
|
||||
let!(:repository) { create :repository }
|
||||
let!(:repository_column) { create :repository_column, name: 'My column' }
|
||||
let!(:repository_column) do
|
||||
create :repository_column, data_type: :RepositoryListValue
|
||||
create :repository_column, name: 'My column',
|
||||
data_type: :RepositoryListValue
|
||||
end
|
||||
let!(:repository_row) { create :repository_row, name: 'My row' }
|
||||
let!(:repository_list_value) do
|
||||
create :repository_list_value, repository_cell_attributes: {
|
||||
build :repository_list_value, repository_cell_attributes: {
|
||||
repository_column: repository_column,
|
||||
repository_row: repository_row
|
||||
}
|
||||
|
@ -38,49 +38,20 @@ RSpec.describe RepositoryListValue, type: :model do
|
|||
repository: repository,
|
||||
repository_column: repository_column
|
||||
repository_list_value.repository_list_item = list_item
|
||||
repository_list_value.save
|
||||
repository_list_value.save!
|
||||
expect(repository_list_value.reload.formatted).to eq 'my item'
|
||||
end
|
||||
|
||||
it 'retuns only the the item related to the list' do
|
||||
repository_row_two = create :repository_row, name: 'New row'
|
||||
repository_list_value_two =
|
||||
create :repository_list_value, repository_cell_attributes: {
|
||||
repository_column: repository_column,
|
||||
repository_row: repository_row_two
|
||||
}
|
||||
list_item = create :repository_list_item,
|
||||
data: 'new item',
|
||||
repository: repository,
|
||||
repository_column: repository_column
|
||||
repository_list_value.repository_list_item = list_item
|
||||
expect(repository_list_value.reload.formatted).to_not eq 'my item'
|
||||
expect(repository_list_value.formatted).to eq ''
|
||||
end
|
||||
|
||||
it 'returns an empty string if no item selected' do
|
||||
list_item = create :repository_list_item,
|
||||
data: 'my item',
|
||||
repository: repository,
|
||||
repository_column: repository_column
|
||||
expect(repository_list_value.reload.formatted).to eq ''
|
||||
end
|
||||
|
||||
it 'returns an empty string if item does not exists' do
|
||||
repository_list_value.repository_list_item = nil
|
||||
expect(repository_list_value.reload.formatted).to eq ''
|
||||
end
|
||||
end
|
||||
|
||||
describe '#data' do
|
||||
let!(:repository) { create :repository }
|
||||
let!(:repository_column) { create :repository_column, name: 'My column' }
|
||||
let!(:repository_column) do
|
||||
create :repository_column, data_type: :RepositoryListValue
|
||||
create :repository_column, name: 'My column',
|
||||
data_type: :RepositoryListValue
|
||||
end
|
||||
let!(:repository_row) { create :repository_row, name: 'My row' }
|
||||
let!(:repository_list_value) do
|
||||
create :repository_list_value, repository_cell_attributes: {
|
||||
build :repository_list_value, repository_cell_attributes: {
|
||||
repository_column: repository_column,
|
||||
repository_row: repository_row
|
||||
}
|
||||
|
@ -92,36 +63,24 @@ RSpec.describe RepositoryListValue, type: :model do
|
|||
repository: repository,
|
||||
repository_column: repository_column
|
||||
repository_list_value.repository_list_item = list_item
|
||||
repository_list_value.save
|
||||
repository_list_value.save!
|
||||
expect(repository_list_value.reload.data).to eq 'my item'
|
||||
end
|
||||
|
||||
it 'retuns only the the item related to the list' do
|
||||
repository_row_two = create :repository_row, name: 'New row'
|
||||
create :repository_list_value,
|
||||
repository_cell_attributes: {
|
||||
repository_column: repository_column,
|
||||
repository_row: repository_row_two
|
||||
}
|
||||
repository_column_two = create :repository_column, name: 'New column'
|
||||
list_item = create :repository_list_item,
|
||||
data: 'new item',
|
||||
repository: repository,
|
||||
repository_column: repository_column
|
||||
repository_list_value.repository_list_item = list_item
|
||||
expect(repository_list_value.reload.data).to_not eq 'my item'
|
||||
expect(repository_list_value.data).to be_nil
|
||||
end
|
||||
|
||||
it 'returns an empty string if no item selected' do
|
||||
create :repository_list_item, data: 'my item',
|
||||
repository: repository,
|
||||
repository_column: repository_column
|
||||
expect(repository_list_value.reload.data).to be_nil
|
||||
end
|
||||
|
||||
it 'returns an empty string if item does not exists' do
|
||||
repository_list_value.repository_list_item = nil
|
||||
expect(repository_list_value.reload.data).to be_nil
|
||||
repository_column: repository_column_two
|
||||
repository_list_value_two = build :repository_list_value,
|
||||
repository_cell_attributes: {
|
||||
repository_column: repository_column,
|
||||
repository_row: repository_row
|
||||
}
|
||||
repository_list_value_two.repository_list_item = list_item
|
||||
saved = repository_list_value_two.save
|
||||
expect(saved).to eq false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,6 +5,9 @@ require 'database_cleaner'
|
|||
require 'devise'
|
||||
require_relative 'support/controller_macros'
|
||||
ENV['RAILS_ENV'] = 'test'
|
||||
|
||||
ENV['CORE_API_V1_PREVIEW'] = 'true'
|
||||
|
||||
require File.expand_path('../../config/environment', __FILE__)
|
||||
# Prevent database truncation if the environment is production
|
||||
abort('The Rails environment is running in production mode!') if Rails.env.production?
|
||||
|
|
95
spec/requests/api/v1/inventories_controller_spec.rb
Normal file
95
spec/requests/api/v1/inventories_controller_spec.rb
Normal file
|
@ -0,0 +1,95 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
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
|
217
spec/requests/api/v1/inventory_columns_controller_spec.rb
Normal file
217
spec/requests/api/v1/inventory_columns_controller_spec.rb
Normal file
|
@ -0,0 +1,217 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Api::V1::InventoryColumnsController', 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)
|
||||
|
||||
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)
|
||||
create(:repository_list_item, repository: @valid_inventory,
|
||||
repository_column: list_column, data: Faker::Name.unique.name)
|
||||
create(:repository_column, name: Faker::Name.unique.name,
|
||||
repository: @valid_inventory, data_type: :RepositoryAssetValue)
|
||||
|
||||
@valid_headers =
|
||||
{ 'Authorization': 'Bearer ' + generate_token(@user.id) }
|
||||
end
|
||||
|
||||
describe 'GET inventory_columns, #index' do
|
||||
it 'Response with correct inventory items, default per page' do
|
||||
hash_body = nil
|
||||
get api_v1_team_inventory_columns_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_columns.limit(10),
|
||||
each_serializer: Api::V1::InventoryColumnSerializer,
|
||||
include: :inventory_columns)
|
||||
.as_json[:data]
|
||||
)
|
||||
expect(hash_body[:included]).to match(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(@valid_inventory.repository_columns.limit(10),
|
||||
each_serializer: Api::V1::InventoryColumnSerializer,
|
||||
include: :inventory_list_items)
|
||||
.as_json[:included]
|
||||
)
|
||||
end
|
||||
|
||||
it 'When invalid request, user in not member of the team' do
|
||||
hash_body = nil
|
||||
get api_v1_team_inventory_columns_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_columns_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_columns_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
|
||||
|
||||
describe 'POST inventory_column, #create' do
|
||||
before :all do
|
||||
@valid_headers['Content-Type'] = 'application/json'
|
||||
@request_body = { data:
|
||||
{ type: 'inventory_columns',
|
||||
attributes: {
|
||||
name: Faker::Name.unique.name,
|
||||
data_type:
|
||||
RepositoryColumn.data_types.values.first
|
||||
} } }
|
||||
end
|
||||
|
||||
it 'Response with correct inventory column' do
|
||||
hash_body = nil
|
||||
post api_v1_team_inventory_columns_path(
|
||||
team_id: @teams.first.id,
|
||||
inventory_id: @teams.first.repositories.first.id
|
||||
), params: @request_body.to_json, headers: @valid_headers
|
||||
expect(response).to have_http_status 201
|
||||
expect { hash_body = json }.not_to raise_exception
|
||||
expect(hash_body[:data]).to match(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(RepositoryColumn.last,
|
||||
serializer: Api::V1::InventoryColumnSerializer,
|
||||
include: :inventory_cells)
|
||||
.as_json[:data]
|
||||
)
|
||||
end
|
||||
|
||||
it 'When invalid request, user in not member of the team' do
|
||||
hash_body = nil
|
||||
post api_v1_team_inventory_columns_path(
|
||||
team_id: @teams.second.id,
|
||||
inventory_id: @teams.first.repositories.first.id
|
||||
), params: @request_body.to_json, 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
|
||||
post api_v1_team_inventory_columns_path(
|
||||
team_id: @teams.first.id,
|
||||
inventory_id: 123
|
||||
), params: @request_body.to_json, 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
|
||||
post api_v1_team_inventory_columns_path(
|
||||
team_id: @teams.first.id,
|
||||
inventory_id: @teams.second.repositories.first.id
|
||||
), params: @request_body.to_json, 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, incorrect type' do
|
||||
invalid_request_body = @request_body.deep_dup
|
||||
invalid_request_body[:data][:type] = 'repository_rows'
|
||||
hash_body = nil
|
||||
post api_v1_team_inventory_columns_path(
|
||||
team_id: @teams.first.id,
|
||||
inventory_id: @teams.first.repositories.first.id
|
||||
), params: invalid_request_body.to_json, headers: @valid_headers
|
||||
expect(response).to have_http_status(400)
|
||||
expect { hash_body = json }.to_not raise_exception
|
||||
expect(hash_body).to match({})
|
||||
end
|
||||
|
||||
it 'When invalid request, missing data param' do
|
||||
hash_body = nil
|
||||
post api_v1_team_inventory_columns_path(
|
||||
team_id: @teams.first.id,
|
||||
inventory_id: @teams.first.repositories.first.id
|
||||
), params: {}, headers: @valid_headers
|
||||
expect(response).to have_http_status(400)
|
||||
expect { hash_body = json }.to_not raise_exception
|
||||
expect(hash_body).to match({})
|
||||
end
|
||||
|
||||
it 'When invalid request, missing attributes param' do
|
||||
invalid_request_body = @request_body.deep_dup
|
||||
invalid_request_body[:data].delete(:attributes)
|
||||
hash_body = nil
|
||||
post api_v1_team_inventory_columns_path(
|
||||
team_id: @teams.first.id,
|
||||
inventory_id: @teams.first.repositories.first.id
|
||||
), params: invalid_request_body.to_json, headers: @valid_headers
|
||||
expect(response).to have_http_status(400)
|
||||
expect { hash_body = json }.to_not raise_exception
|
||||
expect(hash_body).to match({})
|
||||
end
|
||||
|
||||
it 'When invalid request, missing type param' do
|
||||
invalid_request_body = @request_body.deep_dup
|
||||
invalid_request_body[:data].delete(:type)
|
||||
hash_body = nil
|
||||
post api_v1_team_inventory_columns_path(
|
||||
team_id: @teams.first.id,
|
||||
inventory_id: @teams.first.repositories.first.id
|
||||
), params: invalid_request_body.to_json, headers: @valid_headers
|
||||
expect(response).to have_http_status(400)
|
||||
expect { hash_body = json }.to_not raise_exception
|
||||
expect(hash_body).to match({})
|
||||
end
|
||||
|
||||
it 'When invalid request, missing attributes values' do
|
||||
hash_body = nil
|
||||
%i(name data_type).each do |attr|
|
||||
invalid_request_body = @request_body.deep_dup
|
||||
invalid_request_body[:data][:attributes].delete(attr)
|
||||
post api_v1_team_inventory_columns_path(
|
||||
team_id: @teams.first.id,
|
||||
inventory_id: @teams.first.repositories.first.id
|
||||
), params: invalid_request_body.to_json, headers: @valid_headers
|
||||
expect(response).to have_http_status(400)
|
||||
expect { hash_body = json }.to_not raise_exception
|
||||
expect(hash_body).to match({})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
175
spec/requests/api/v1/inventory_items_controller_spec.rb
Normal file
175
spec/requests/api/v1/inventory_items_controller_spec.rb
Normal file
|
@ -0,0 +1,175 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
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, 100 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
|
||||
|
||||
describe 'DELETE inventory_items, #destroy' do
|
||||
it 'Destroys inventory item' do
|
||||
deleted_id = @teams.first.repositories.first.repository_rows.last.id
|
||||
delete api_v1_team_inventory_item_path(
|
||||
id: deleted_id,
|
||||
team_id: @teams.first.id,
|
||||
inventory_id: @teams.first.repositories.first.id
|
||||
), headers: @valid_headers
|
||||
expect(response).to have_http_status(200)
|
||||
expect(RepositoryRow.where(id: deleted_id)).to_not exist
|
||||
expect(RepositoryCell.where(repository_row: deleted_id).count).to equal 0
|
||||
end
|
||||
|
||||
it 'Invalid request, non existing inventory item' do
|
||||
deleted_id = RepositoryRow.last.id + 1
|
||||
delete api_v1_team_inventory_item_path(
|
||||
id: deleted_id,
|
||||
team_id: @teams.first.id,
|
||||
inventory_id: @teams.first.repositories.first.id
|
||||
), headers: @valid_headers
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
|
||||
it 'When invalid request, incorrect repository' do
|
||||
deleted_id = @teams.first.repositories.first.repository_rows.last.id
|
||||
delete api_v1_team_inventory_item_path(
|
||||
id: deleted_id,
|
||||
team_id: @teams.first.id,
|
||||
inventory_id: @teams.second.repositories.first.id
|
||||
), headers: @valid_headers
|
||||
expect(response).to have_http_status(404)
|
||||
expect(RepositoryRow.where(id: deleted_id)).to exist
|
||||
end
|
||||
|
||||
it 'When invalid request, repository from another team' do
|
||||
deleted_id = @teams.first.repositories.first.repository_rows.last.id
|
||||
delete api_v1_team_inventory_item_path(
|
||||
id: deleted_id,
|
||||
team_id: @teams.second.id,
|
||||
inventory_id: @teams.first.repositories.first.id
|
||||
), headers: @valid_headers
|
||||
expect(response).to have_http_status(403)
|
||||
expect(RepositoryRow.where(id: deleted_id)).to exist
|
||||
end
|
||||
end
|
||||
end
|
49
spec/requests/api/v1/users_controller_spec.rb
Normal file
49
spec/requests/api/v1/users_controller_spec.rb
Normal file
|
@ -0,0 +1,49 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Api::V1::UsersController', type: :request do
|
||||
before :all do
|
||||
@user1 = create(:user, email: Faker::Internet.unique.email)
|
||||
@user2 = create(:user, email: Faker::Internet.unique.email)
|
||||
@user3 = create(:user, email: Faker::Internet.unique.email)
|
||||
@team1 = create(:team, created_by: @user1)
|
||||
@team2 = create(:team, created_by: @user2)
|
||||
@team3 = create(:team, created_by: @user3)
|
||||
create(:user_team, user: @user1, team: @team1, role: 2)
|
||||
create(:user_team, user: @user2, team: @team1, role: 2)
|
||||
create(:user_team, user: @user2, team: @team2, role: 2)
|
||||
create(:user_team, user: @user3, team: @team3, role: 2)
|
||||
@valid_headers =
|
||||
{ 'Authorization': 'Bearer ' + generate_token(@user1.id) }
|
||||
end
|
||||
|
||||
describe 'GET user, #show' do
|
||||
it 'When valid request, requested user is member of the same teams' do
|
||||
hash_body = nil
|
||||
get api_v1_user_path(id: @user2.id), headers: @valid_headers
|
||||
expect { hash_body = json }.not_to raise_exception
|
||||
expect(hash_body[:data]).to match(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(@user2, serializer: Api::V1::UserSerializer)
|
||||
.as_json[:data]
|
||||
)
|
||||
end
|
||||
|
||||
it 'When invalid request, requested user is not member of the same teams' do
|
||||
hash_body = nil
|
||||
get api_v1_user_path(id: @user3.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 user' do
|
||||
hash_body = nil
|
||||
get api_v1_user_path(id: 123), 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
|
||||
end
|
113
spec/requests/api/v1/users_identeties_controller_spec.rb
Normal file
113
spec/requests/api/v1/users_identeties_controller_spec.rb
Normal file
|
@ -0,0 +1,113 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Api::V1::UsersIdentitiesController', type: :request do
|
||||
before :all do
|
||||
@user1 = create(:user, email: Faker::Internet.unique.email)
|
||||
@user2 = create(:user, email: Faker::Internet.unique.email)
|
||||
create(:user_identity, user: @user1,
|
||||
uid: Faker::Crypto.unique.sha1, provider: Faker::App.unique.name)
|
||||
@valid_headers =
|
||||
{ 'Authorization': 'Bearer ' + generate_token(@user1.id) }
|
||||
end
|
||||
|
||||
describe 'GET user_identities, #index' do
|
||||
it 'When valid request, requested identities for current user' do
|
||||
hash_body = nil
|
||||
get api_v1_user_user_identities_path(user_id: @user1.id),
|
||||
headers: @valid_headers
|
||||
expect { hash_body = json }.not_to raise_exception
|
||||
expect(hash_body[:data]).to match(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(@user1.user_identities,
|
||||
each_serializer: Api::V1::UserIdentitySerializer)
|
||||
.as_json[:data]
|
||||
)
|
||||
end
|
||||
|
||||
it 'When invalid request, requested user is not signed in user' do
|
||||
hash_body = nil
|
||||
get api_v1_user_user_identities_path(user_id: @user2.id),
|
||||
headers: @valid_headers
|
||||
expect(response).to have_http_status(403)
|
||||
expect(hash_body).to match(nil)
|
||||
end
|
||||
|
||||
it 'When invalid request, non existing user' do
|
||||
hash_body = nil
|
||||
get api_v1_user_user_identities_path(user_id: 123),
|
||||
headers: @valid_headers
|
||||
expect(response).to have_http_status(403)
|
||||
expect(hash_body).to match(nil)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST user_identities, #create' do
|
||||
it 'When valid request, create new identity for current user' do
|
||||
hash_body = nil
|
||||
post api_v1_user_user_identities_path(user_id: @user1.id),
|
||||
params: {
|
||||
data: { type: 'user_identities',
|
||||
attributes: { uid: Faker::Crypto.unique.sha1,
|
||||
provider: Faker::App.unique.name } }
|
||||
},
|
||||
headers: @valid_headers
|
||||
expect { hash_body = json }.not_to raise_exception
|
||||
expect(hash_body[:data]).to match(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(@user1.user_identities.order(:id).last,
|
||||
serializer: Api::V1::UserIdentitySerializer)
|
||||
.as_json[:data]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET user_identity, #show' do
|
||||
it 'When valid request, requested specific identity for current user' do
|
||||
hash_body = nil
|
||||
get api_v1_user_user_identity_path(
|
||||
user_id: @user1.id, id: @user1.user_identities.order(:id).last
|
||||
), headers: @valid_headers
|
||||
expect { hash_body = json }.not_to raise_exception
|
||||
expect(hash_body[:data]).to match(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(@user1.user_identities.order(:id).last,
|
||||
serializer: Api::V1::UserIdentitySerializer)
|
||||
.as_json[:data]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT user_identities, #update' do
|
||||
it 'When valid request, update identity for current user' do
|
||||
hash_body = nil
|
||||
put api_v1_user_user_identity_path(user_id: @user1.id,
|
||||
id: @user1.user_identities.order(:id).last),
|
||||
params: {
|
||||
data: { id: @user1.user_identities.order(:id).last.id,
|
||||
type: 'user_identities',
|
||||
attributes: { uid: Faker::Crypto.unique.sha1 } }
|
||||
},
|
||||
headers: @valid_headers
|
||||
expect { hash_body = json }.not_to raise_exception
|
||||
expect(hash_body[:data]).to match(
|
||||
ActiveModelSerializers::SerializableResource
|
||||
.new(@user1.user_identities.order(:id).last,
|
||||
serializer: Api::V1::UserIdentitySerializer)
|
||||
.as_json[:data]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DELETE user_identity, #destroy' do
|
||||
it 'When valid request, destroy specified identity for current user' do
|
||||
identity = @user1.user_identities.order(:id).last
|
||||
delete api_v1_user_user_identity_path(user_id: @user1.id, id: identity),
|
||||
headers: @valid_headers
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.body).to eq('')
|
||||
expect(UserIdentity.find_by_id(identity.id)).to eq(nil)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue