Merge pull request #1014 from ZmagoD/zd_SCI_2025

Fix custom repositories export so it supports "list of values" custom column types [fixes SCI-2025]
This commit is contained in:
Zmago Devetak 2018-03-13 15:20:46 +01:00 committed by GitHub
commit f778415321
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 228 additions and 67 deletions

View file

@ -261,7 +261,7 @@ class RepositoriesController < ApplicationController
def export_repository
if params[:row_ids] && params[:header_ids]
generate_zip
RepositoryZipExport.generate_zip(params, @repository, current_user)
else
flash[:alert] = t('zip_export.export_error')
end
@ -333,66 +333,4 @@ class RepositoriesController < ApplicationController
end
end
end
def generate_zip
# Fetch rows in the same order as in the currently viewed datatable
ordered_row_ids = params[:row_ids]
id_row_map = RepositoryRow.where(id: ordered_row_ids,
repository: @repository)
.index_by(&:id)
ordered_rows = ordered_row_ids.collect { |id| id_row_map[id.to_i] }
zip = ZipExport.create(user: current_user)
zip.generate_exportable_zip(
current_user,
to_csv(ordered_rows, params[:header_ids]),
:repositories
)
end
def to_csv(rows, column_ids)
require 'csv'
# Parse column names
csv_header = []
column_ids.each do |c_id|
csv_header << case c_id.to_i
when -1, -2
next
when -3
I18n.t('repositories.table.row_name')
when -4
I18n.t('repositories.table.added_by')
when -5
I18n.t('repositories.table.added_on')
else
column = RepositoryColumn.find_by_id(c_id)
column ? column.name : nil
end
end
CSV.generate do |csv|
csv << csv_header
rows.each do |row|
csv_row = []
column_ids.each do |c_id|
csv_row << case c_id.to_i
when -1, -2
next
when -3
row.name
when -4
row.created_by.full_name
when -5
I18n.l(row.created_at, format: :full)
else
cell = row.repository_cells
.find_by(repository_column_id: c_id)
cell ? cell.value.formatted : nil
end
end
csv << csv_row
end
end
end
end

View file

@ -13,7 +13,11 @@ class RepositoryListValue < ApplicationRecord
validates :repository_cell, presence: true
def formatted
return '' unless repository_list_item
data.to_s
end
def data
return nil unless repository_list_item
repository_list_item.data
end
end

View file

@ -0,0 +1,62 @@
require 'csv'
module RepositoryZipExport
def self.generate_zip(params, repository, current_user)
# Fetch rows in the same order as in the currently viewed datatable
ordered_row_ids = params[:row_ids]
id_row_map = RepositoryRow.where(id: ordered_row_ids,
repository: repository)
.index_by(&:id)
ordered_rows = ordered_row_ids.collect { |id| id_row_map[id.to_i] }
zip = ZipExport.create(user: current_user)
zip.generate_exportable_zip(
current_user,
to_csv(ordered_rows, params[:header_ids]),
:repositories
)
end
def self.to_csv(rows, column_ids)
# Parse column names
csv_header = []
column_ids.each do |c_id|
csv_header << case c_id.to_i
when -1, -2
next
when -3
I18n.t('repositories.table.row_name')
when -4
I18n.t('repositories.table.added_by')
when -5
I18n.t('repositories.table.added_on')
else
column = RepositoryColumn.find_by_id(c_id)
column ? column.name : nil
end
end
CSV.generate do |csv|
csv << csv_header
rows.each do |row|
csv_row = []
column_ids.each do |c_id|
csv_row << case c_id.to_i
when -1, -2
next
when -3
row.name
when -4
row.created_by.full_name
when -5
I18n.l(row.created_at, format: :full)
else
cell = row.repository_cells
.find_by(repository_column_id: c_id)
cell ? cell.value.formatted : nil
end
end
csv << csv_row
end
end
end
end

View file

@ -0,0 +1,6 @@
FactoryBot.define do
factory :repository_text_value do
created_by { User.first || association(:project_user) }
last_modified_by { User.first || association(:project_user) }
end
end

View file

@ -6,7 +6,6 @@ describe 'samples_to_repository_migration:run' do
let!(:team) { create :team, created_by: user }
let!(:user_team) { create :user_team, user: user, team: team }
let!(:my_module) { create :my_module }
let!(:samples_table) { create :samples_table, user: user, team: team }
let(:sample_types_names) { %w(type_one type_two type_three) }
let(:sample_group_names) { %w(group_one group_two group_three) }

View file

@ -18,7 +18,7 @@ RSpec.describe RepositoryListValue, type: :model do
it { should accept_nested_attributes_for(:repository_cell) }
end
describe '#data' do
describe '#formatted' do
let!(:repository) { create :repository }
let!(:repository_column) { create :repository_column, name: 'My column' }
let!(:repository_column) do
@ -32,7 +32,7 @@ RSpec.describe RepositoryListValue, type: :model do
}
end
it 'returns the data of a selected item' do
it 'returns the formatted data of a selected item' do
list_item = create :repository_list_item,
data: 'my item',
repository: repository,
@ -71,4 +71,58 @@ RSpec.describe RepositoryListValue, type: :model do
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
end
let!(:repository_row) { create :repository_row, name: 'My row' }
let!(:repository_list_value) do
create :repository_list_value, repository_cell_attributes: {
repository_column: repository_column,
repository_row: repository_row
}
end
it 'returns the data of a selected item' do
list_item = create :repository_list_item,
data: 'my item',
repository: repository,
repository_column: repository_column
repository_list_value.repository_list_item = list_item
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'
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.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
list_item = create :repository_list_item,
data: 'my item',
repository: repository,
repository_column: repository_column
expect(repository_list_value.reload.data).to eq 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 eq nil
end
end
end

View file

@ -58,6 +58,14 @@ RSpec.configure do |config|
config.after(:each) do
DatabaseCleaner.clean
end
config.around(:each, type: :background_job) do |example|
run_background_jobs_immediately do
example.run
end
end
config.include BackgroundJobs
# RSpec Rails can automatically mix in different behaviours to your tests
# based on their file location, for example enabling you to call `get` and
# `post` in specs under `spec/controllers`.

View file

@ -0,0 +1,82 @@
require 'rails_helper'
require 'zip'
describe RepositoryZipExport, type: :background_job do
let(:user) { create :user }
let(:team) { create :team, created_by: user }
let(:user_team) { create :user_team, user: user, team: team }
let(:repository) { create :repository, team: team, created_by: user }
let!(:sample_group_column) do
create :repository_column, repository: repository,
created_by: user,
name: 'Sample group',
data_type: 'RepositoryListValue'
end
let!(:repository_list_item) do
create :repository_list_item, data: 'item one',
repository: repository,
repository_column: sample_group_column
end
let!(:custom_column) do
create :repository_column, repository: repository,
created_by: user,
name: 'Custom items',
data_type: 'RepositoryTextValue'
end
before do
@row_ids = []
10.times do |index|
row = create :repository_row, name: "row #{index}",
repository: repository,
created_by: user,
last_modified_by: user
create :repository_list_value, repository_list_item: repository_list_item,
repository_cell_attributes: {
repository_row: row,
repository_column: sample_group_column
}
create :repository_text_value, data: 'custum column value',
repository_cell_attributes: {
repository_row: row,
repository_column: custom_column
}
@row_ids << row.id.to_s
end
end
describe '#generate_zip/2' do
let(:params) do
{ header_ids: ['-1',
'-2',
sample_group_column.id.to_s,
custom_column.id.to_s,
'-3',
'-5',
'-4'],
row_ids: @row_ids }
end
it 'generates a new zip export object' do
RepositoryZipExport.generate_zip(params, repository, user)
expect(ZipExport.count).to eq 1
end
it 'generates a zip with csv file with exported rows' do
RepositoryZipExport.generate_zip(params, repository, user)
zip = ZipExport.first.zip_file_file_name
.gsub('export-', '')
.gsub('.zip', '')
csv_path = Rails.root.join('tmp', "temp-zip-#{zip}", 'export.csv').to_s
index = 0
CSV.foreach(csv_path, headers: true) do |row|
row_hash = row.to_h
expect(row_hash.fetch('Sample group')).to eq 'item one'
expect(row_hash.fetch('Custom items')).to eq 'custum column value'
expect(row_hash.fetch('Name')).to eq "row #{index}"
index += 1
end
end
end
end

View file

@ -0,0 +1,8 @@
module BackgroundJobs
def run_background_jobs_immediately
delay_jobs = Delayed::Worker.delay_jobs
Delayed::Worker.delay_jobs = false
yield
Delayed::Worker.delay_jobs = delay_jobs
end
end