Add factories and validation tests for repositories and related models

Repositories, cells, columns, values (date, text, asset, list), rows, items
This commit is contained in:
Urban Rotnik 2019-05-07 13:47:50 +02:00
parent a7558d83be
commit 3adf2bb736
27 changed files with 292 additions and 220 deletions

View file

@ -6,7 +6,7 @@ class Report < ApplicationRecord
validates :name,
length: { minimum: Constants::NAME_MIN_LENGTH,
maximum: Constants::NAME_MAX_LENGTH },
uniqueness: { scope: [:user, :project], case_sensitive: false }
uniqueness: { scope: %i(user_id project_id), case_sensitive: false }
validates :description, length: { maximum: Constants::TEXT_MAX_LENGTH }
validates :project, presence: true
validates :user, presence: true

View file

@ -7,10 +7,7 @@ class Repository < ApplicationRecord
attribute :discarded_by_id, :integer
belongs_to :team, optional: true
belongs_to :created_by,
foreign_key: :created_by_id,
class_name: 'User',
optional: true
belongs_to :created_by, foreign_key: :created_by_id, class_name: 'User'
has_many :repository_columns, dependent: :destroy
has_many :repository_rows, dependent: :destroy
has_many :repository_table_states,
@ -21,7 +18,7 @@ class Repository < ApplicationRecord
auto_strip_attributes :name, nullify: false
validates :name,
presence: true,
uniqueness: { scope: :team, case_sensitive: false },
uniqueness: { scope: :team_id, case_sensitive: false },
length: { maximum: Constants::NAME_MAX_LENGTH }
validates :team, presence: true
validates :created_by, presence: true

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
class RepositoryCell < ActiveRecord::Base
attr_accessor :importing
@ -57,7 +59,7 @@ class RepositoryCell < ActiveRecord::Base
private
def repository_column_data_type
if value_type != repository_column.data_type
if !repository_column || value_type != repository_column.data_type
errors.add(:value_type, 'must match column data type')
end
end

View file

@ -1,9 +1,8 @@
# frozen_string_literal: true
class RepositoryColumn < ApplicationRecord
belongs_to :repository, optional: true
belongs_to :created_by,
foreign_key: :created_by_id,
class_name: 'User',
optional: true
belongs_to :repository
belongs_to :created_by, foreign_key: :created_by_id, class_name: 'User'
has_many :repository_cells, dependent: :destroy
has_many :repository_rows, through: :repository_cells
has_many :repository_list_items, dependent: :destroy
@ -14,7 +13,7 @@ class RepositoryColumn < ApplicationRecord
validates :name,
presence: true,
length: { maximum: Constants::NAME_MAX_LENGTH },
uniqueness: { scope: :repository, case_sensitive: true }
uniqueness: { scope: :repository_id, case_sensitive: true }
validates :created_by, presence: true
validates :repository, presence: true
validates :data_type, presence: true

View file

@ -1,18 +1,13 @@
# frozen_string_literal: true
class RepositoryDateValue < ApplicationRecord
belongs_to :created_by,
foreign_key: :created_by_id,
class_name: 'User',
optional: true
belongs_to :last_modified_by,
foreign_key: :last_modified_by_id,
class_name: 'User',
optional: true
belongs_to :created_by, foreign_key: :created_by_id, class_name: 'User'
belongs_to :last_modified_by, foreign_key: :last_modified_by_id, class_name: 'User'
has_one :repository_cell, as: :value, dependent: :destroy
accepts_nested_attributes_for :repository_cell
validates :repository_cell, presence: true
validates :data,
presence: true
validates :data, presence: true
def formatted
data

View file

@ -1,15 +1,13 @@
# frozen_string_literal: true
class RepositoryListItem < ApplicationRecord
has_many :repository_list_values, inverse_of: :repository_list_item
belongs_to :repository, inverse_of: :repository_list_items
belongs_to :repository_column, inverse_of: :repository_list_items
belongs_to :created_by,
foreign_key: :created_by_id,
class_name: 'User'
belongs_to :last_modified_by,
foreign_key: :last_modified_by_id,
class_name: 'User'
belongs_to :created_by, foreign_key: :created_by_id, class_name: 'User'
belongs_to :last_modified_by, foreign_key: :last_modified_by_id, class_name: 'User'
validates :data,
presence: true,
uniqueness: { scope: :repository_column, case_sensitive: false },
uniqueness: { scope: :repository_column_id, case_sensitive: false },
length: { maximum: Constants::TEXT_MAX_LENGTH }
end

View file

@ -1,15 +1,11 @@
# frozen_string_literal: true
class RepositoryRow < ApplicationRecord
include SearchableModel
belongs_to :repository, optional: true
belongs_to :created_by,
foreign_key: :created_by_id,
class_name: 'User',
optional: true
belongs_to :last_modified_by,
foreign_key: :last_modified_by_id,
class_name: 'User',
optional: true
belongs_to :created_by, foreign_key: :created_by_id, class_name: 'User'
belongs_to :last_modified_by, foreign_key: :last_modified_by_id, class_name: 'User'
has_many :repository_cells, -> { order(:id) }, dependent: :destroy
has_many :repository_columns, through: :repository_cells
has_many :my_module_repository_rows,

View file

@ -1,12 +1,8 @@
# frozen_string_literal: true
class RepositoryTextValue < ApplicationRecord
belongs_to :created_by,
foreign_key: :created_by_id,
class_name: 'User',
optional: true
belongs_to :last_modified_by,
foreign_key: :last_modified_by_id,
class_name: 'User',
optional: true
belongs_to :created_by, foreign_key: :created_by_id, class_name: 'User'
belongs_to :last_modified_by, foreign_key: :last_modified_by_id, class_name: 'User'
has_one :repository_cell, as: :value, dependent: :destroy, inverse_of: :value
accepts_nested_attributes_for :repository_cell

View file

@ -2,8 +2,6 @@
FactoryBot.define do
factory :asset do
association :created_by, factory: :project_user
team
file_file_name 'sample_file.txt'
file_content_type 'text/plain'
file_file_size 69

View file

@ -1,6 +1,12 @@
# frozen_string_literal: true
FactoryBot.define do
factory :repository_asset_value do
created_by { User.first || create(:user) }
last_modified_by { User.first || create(:user) }
asset
after(:build) do |repository_asset_value|
repository_asset_value.repository_cell ||= build(:repository_cell,
:asset_value,
repository_asset_value: repository_asset_value)
end
end
end

View file

@ -3,7 +3,33 @@
FactoryBot.define do
factory :repository_cell do
repository_row
repository_column
value 'RepositoryTextValue'
trait :text_value do
repository_column { create :repository_column, :text_type, repository: repository_row.repository }
after(:build) do |repository_cell|
repository_cell.value ||= build(:repository_text_value, repository_cell: repository_cell)
end
end
trait :date_value do
repository_column { create :repository_column, :date_type, repository: repository_row.repository }
after(:build) do |repository_cell|
repository_cell.value ||= build(:repository_date_value, repository_cell: repository_cell)
end
end
trait :list_value do
repository_column { create :repository_column, :list_type, repository: repository_row.repository }
after(:build) do |repository_cell|
repository_cell.value ||= build(:repository_list_value, repository_cell: repository_cell)
end
end
trait :asset_value do
repository_column { create :repository_column, :asset_type, repository: repository_row.repository }
after(:build) do |repository_cell|
repository_cell.value ||= build(:repository_asset_value, repository_cell: repository_cell)
end
end
end
end

View file

@ -6,5 +6,21 @@ FactoryBot.define do
created_by { create :user }
repository
data_type :RepositoryTextValue
trait :text_type do
data_type :RepositoryTextValue
end
trait :date_type do
data_type :RepositoryDateValue
end
trait :list_type do
data_type :RepositoryListValue
end
trait :asset_type do
data_type :RepositoryAssetValue
end
end
end

View file

@ -0,0 +1,14 @@
# frozen_string_literal: true
FactoryBot.define do
factory :repository_date_value do
created_by { create :user }
last_modified_by { created_by }
data { Time.now }
after(:build) do |repository_date_value|
repository_date_value.repository_cell ||= build(:repository_cell,
:date_value,
repository_date_value: repository_date_value)
end
end
end

View file

@ -1,8 +1,11 @@
# frozen_string_literal: true
FactoryBot.define do
factory :repository_list_item do
data { Faker::Name.unique.name }
repository { Repository.first || create(:repository) }
created_by { User.first || association(:project_user) }
last_modified_by { User.first || association(:project_user) }
data { Faker::Lorem.paragraph }
repository
repository_column { create :repository_column, :list_type, repository: repository }
created_by { create :user }
last_modified_by { created_by }
end
end

View file

@ -1,6 +1,17 @@
# frozen_string_literal: true
FactoryBot.define do
factory :repository_list_value do
created_by { User.first || association(:project_user) }
last_modified_by { User.first || association(:project_user) }
created_by { create :user }
last_modified_by { created_by }
repository_list_item
after(:build) do |repository_list_value|
repository_list_value.repository_cell ||= build(:repository_cell,
:list_value,
repository_list_value: repository_list_value)
repository_list_value.repository_cell.repository_column.repository_list_items =
[repository_list_value.repository_list_item]
end
end
end

View file

@ -1,6 +0,0 @@
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

@ -0,0 +1,14 @@
# frozen_string_literal: true
FactoryBot.define do
factory :repository_text_value do
created_by { create :user }
last_modified_by { created_by }
data { Faker::Lorem.paragraph }
after(:build) do |repository_text_value|
repository_text_value.repository_cell ||= build(:repository_cell,
:text_value,
repository_text_value: repository_text_value)
end
end
end

View file

@ -1,6 +1,14 @@
# frozen_string_literal: true
require 'rails_helper'
describe Report, type: :model do
let(:report) { build :report }
it 'is valid' do
expect(report).to be_valid
end
it 'should be of class Report' do
expect(subject.class).to eq Report
end
@ -25,7 +33,7 @@ describe Report, type: :model do
it { should have_many :report_elements }
end
describe 'Should be a valid object' do
describe 'Validations' do
it { should validate_presence_of :project }
it { should validate_presence_of :user }
it do
@ -38,14 +46,8 @@ describe Report, type: :model do
.is_at_most(Constants::NAME_MAX_LENGTH)
end
it 'should have uniq name scoped to user, project' do
r = create :report, name: 'Same Name'
new_report = build :report,
name: 'Same Name',
user: r.user,
project: r.project
expect(new_report).to_not be_valid
it do
expect(report).to validate_uniqueness_of(:name).scoped_to(:user_id, :project_id).case_insensitive
end
end
end

View file

@ -1,6 +1,14 @@
# frozen_string_literal: true
require 'rails_helper'
describe RepositoryAssetValue, type: :model do
let(:repository_asset_value) { build :repository_asset_value }
it 'is valid' do
expect(repository_asset_value).to be_valid
end
it 'should be of class RepositoryAssetValue' do
expect(subject.class).to eq RepositoryAssetValue
end
@ -21,28 +29,16 @@ describe RepositoryAssetValue, type: :model do
it { should accept_nested_attributes_for(:repository_cell) }
end
describe 'Should be a valid object' do
describe 'Validations' do
it { should validate_presence_of :repository_cell }
it { should validate_presence_of :asset }
end
describe '#data' do
let!(:repository) { create :repository }
let!(:repository_row) { create :repository_row, repository: repository }
let!(:repository_column) do
create :repository_column,
data_type: :RepositoryAssetValue,
repository: repository
end
it 'returns the asset' do
asset = create :asset, file_file_name: 'my file'
repository_asset_value = create :repository_asset_value,
asset: asset,
repository_cell_attributes: {
repository_column: repository_column,
repository_row: repository_row
}
repository_asset_value = create :repository_asset_value, asset: asset
expect(repository_asset_value.reload.formatted).to eq 'my file'
end
end

View file

@ -1,6 +1,38 @@
# frozen_string_literal: true
require 'rails_helper'
describe RepositoryCell, type: :model do
let(:repository_cell) { build :repository_cell }
let(:repository_cell_t) { build :repository_cell, :text_value }
let(:repository_cell_d) { build :repository_cell, :date_value }
let(:repository_cell_l) { build :repository_cell, :list_value }
let(:repository_cell_a) { build :repository_cell, :asset_value }
context 'when do not have value' do
it 'is not valid' do
expect(repository_cell).not_to be_valid
end
end
context 'when have value' do
it 'is valid for text value' do
expect(repository_cell_t).to be_valid
end
it 'is valid for data value' do
expect(repository_cell_d).to be_valid
end
it 'is valid for list value' do
expect(repository_cell_l).to be_valid
end
it 'is valid for asset value' do
expect(repository_cell_a).to be_valid
end
end
it 'should be of class RepositoryCell' do
expect(subject.class).to eq RepositoryCell
end

View file

@ -1,6 +1,14 @@
# frozen_string_literal: true
require 'rails_helper'
describe RepositoryColumn, type: :model do
let(:repository_column) { build :repository_column }
it 'is valid' do
expect(repository_column).to be_valid
end
it 'should be of class RepositoryColumn' do
expect(subject.class).to eq RepositoryColumn
end
@ -22,19 +30,23 @@ describe RepositoryColumn, type: :model do
it { should have_many :repository_list_items }
end
describe 'Should be a valid object' do
it { should validate_presence_of :name }
it { should validate_presence_of :created_by }
it { should validate_presence_of :repository }
it { should validate_presence_of :data_type }
it do
should validate_length_of(:name).is_at_most(Constants::NAME_MAX_LENGTH)
describe 'Validations' do
describe '#name' do
it { is_expected.to validate_presence_of :name }
it { is_expected.to(validate_length_of(:name).is_at_most(Constants::NAME_MAX_LENGTH)) }
it { expect(repository_column).to validate_uniqueness_of(:name).scoped_to(:repository_id) }
end
it 'have uniq name scoped to repository' do
r = create :repository_column, name: 'Repo One'
ct = build :repository_column, name: 'Repo One', repository: r.repository
expect(ct).to_not be_valid
describe '#created_by' do
it { is_expected.to validate_presence_of :created_by }
end
describe '#repository' do
it { is_expected.to validate_presence_of :repository }
end
describe '#data_type' do
it { is_expected.to validate_presence_of :data_type }
end
end
end

View file

@ -1,6 +1,14 @@
# frozen_string_literal: true
require 'rails_helper'
describe RepositoryDateValue, type: :model do
let(:repository_date_value) { build :repository_date_value }
it 'is valid' do
expect(repository_date_value).to be_valid
end
it 'should be of class RepositoryDateValue' do
expect(subject.class).to eq RepositoryDateValue
end
@ -19,7 +27,7 @@ describe RepositoryDateValue, type: :model do
it { should have_one :repository_cell }
end
describe 'Should be a valid object' do
describe 'Validations' do
it { should validate_presence_of :repository_cell }
it { should validate_presence_of :data }
end

View file

@ -1,6 +1,14 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe RepositoryListItem, type: :model do
let(:repository_list_item) { build :repository_list_item }
it 'is valid' do
expect(repository_list_item).to be_valid
end
it 'should be of class RepositoryListItem' do
expect(subject.class).to eq RepositoryListItem
end
@ -22,46 +30,13 @@ RSpec.describe RepositoryListItem, type: :model do
end
describe 'Validations' do
let!(:user) { create :user }
let!(:repository_one) { create :repository }
it { should validate_presence_of(:data) }
it do
should validate_length_of(:data).is_at_most(Constants::TEXT_MAX_LENGTH)
end
context 'has a uniq data scoped on repository column' do
let!(:repository_column) do
create :repository_column, name: 'My column', repository: repository_one
end
let!(:repository_two) { create :repository, name: 'New repo' }
let!(:repository_column_two) do
create :repository_column, name: 'My column', repository: repository_two
end
let!(:repository_list_item) do
create :repository_list_item,
data: 'Test',
repository: repository_one,
repository_column: repository_column
end
it 'creates a repository list item in same repository' do
new_item = build :repository_list_item,
data: 'Test',
repository: repository_one,
repository_column: repository_column
expect(new_item).to_not be_valid
expect(
new_item.errors.full_messages.first
).to eq 'Data has already been taken'
end
it 'create a repository list item in other repository' do
new_item = build :repository_list_item,
data: 'Test',
repository: repository_two,
repository_column: repository_column_two
expect(new_item).to be_valid
end
describe '#data' do
it { is_expected.to validate_presence_of(:data) }
it { is_expected.to validate_length_of(:data).is_at_most(Constants::TEXT_MAX_LENGTH) }
it {
expect(repository_list_item).to validate_uniqueness_of(:data)
.scoped_to(:repository_column_id).case_insensitive
}
end
end
end

View file

@ -1,6 +1,14 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe RepositoryListValue, type: :model do
let(:repository_list_value) { build :repository_list_value }
it 'is valid' do
expect(repository_list_value).to be_valid
end
it 'should be of class RepositoryListValue' do
expect(subject.class).to eq RepositoryListValue
end
@ -19,76 +27,29 @@ RSpec.describe RepositoryListValue, type: :model do
end
describe '#formatted' do
let!(:repository) { create :repository }
let!(:repository_column) do
create :repository_column,
name: 'My column',
data_type: :RepositoryListValue,
repository: repository
end
let!(:repository_row) do
create :repository_row, name: 'My row', repository: repository
end
let!(:repository_list_value) do
build :repository_list_value, repository_cell_attributes: {
repository_column: repository_column,
repository_row: repository_row
}
end
let(:list_item) { create :repository_list_item, data: 'my item' }
it 'returns the formatted 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!
repository_list_value = create :repository_list_value, repository_list_item: list_item
expect(repository_list_value.reload.formatted).to eq 'my item'
end
end
describe '#data' do
let!(:repository) { create :repository }
let!(:repository_column) do
create :repository_column,
name: 'My column',
data_type: :RepositoryListValue,
repository: repository
end
let!(:repository_row) do
create :repository_row, name: 'My row', repository: repository
end
let!(:repository_list_value) do
build :repository_list_value, repository_cell_attributes: {
repository_column: repository_column,
repository_row: repository_row
}
end
let(:list_item) { create :repository_list_item, data: 'my item' }
let(:repository_list_value) { create :repository_list_value, repository_list_item: list_item }
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_column_two = create :repository_column, name: 'New column'
list_item = create :repository_list_item,
data: 'new item',
repository: repository,
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
# Not sure if this test make sense, because validation will fail before hit this function. Updated in SCI-3183
it 'retuns only the item related to the list' do
repository_list_value.repository_list_item = nil
repository_list_value.save(validate: false)
expect(repository_list_value.reload.data).to be_nil
end
end
end

View file

@ -1,6 +1,14 @@
# frozen_string_literal: true
require 'rails_helper'
describe RepositoryRow, type: :model do
let(:repository_row) { build :repository_row }
it 'is valid' do
expect(repository_row).to be_valid
end
it 'should be of class RepositoryRow' do
expect(subject.class).to eq RepositoryRow
end
@ -24,11 +32,14 @@ describe RepositoryRow, type: :model do
it { should have_many :my_modules }
end
describe 'Should be a valid object' do
it { should validate_presence_of :name }
it { should validate_presence_of :created_by }
it do
should validate_length_of(:name).is_at_most(Constants::NAME_MAX_LENGTH)
describe 'Validations' do
describe '#name' do
it { is_expected.to validate_presence_of :name }
it { is_expected.to(validate_length_of(:name).is_at_most(Constants::NAME_MAX_LENGTH)) }
end
describe '#created_by' do
it { is_expected.to validate_presence_of :created_by }
end
end
end

View file

@ -1,6 +1,14 @@
# frozen_string_literal: true
require 'rails_helper'
describe Repository, type: :model do
let(:repository) { build :repository }
it 'is valid' do
expect(repository).to be_valid
end
it 'should be of class Repository' do
expect(subject.class).to eq Repository
end
@ -22,24 +30,18 @@ describe Repository, type: :model do
it { should have_many(:repository_list_items).dependent(:destroy) }
end
describe 'Should be a valid object' do
it { should validate_presence_of :team }
it { should validate_presence_of :created_by }
it do
should validate_length_of(:name).is_at_most(Constants::NAME_MAX_LENGTH)
end
let(:team) { create :team }
it 'should have uniq name scoped to team' do
create :repository, name: 'Repository One', team: team
repo = build :repository, name: 'Repository One', team: team
expect(repo).to_not be_valid
describe 'Validations' do
describe '#created_by' do
it { is_expected.to validate_presence_of :created_by }
end
it 'should have uniq name scoped to team calse insensitive' do
create :repository, name: 'Repository One', team: team
repo = build :repository, name: 'REPOSITORY ONE', team: team
expect(repo).to_not be_valid
describe '#name' do
it { is_expected.to validate_length_of(:name).is_at_most(Constants::NAME_MAX_LENGTH) }
it { expect(repository).to validate_uniqueness_of(:name).scoped_to(:team_id).case_insensitive }
end
describe '#team' do
it { is_expected.to validate_presence_of :team }
end
end

View file

@ -1,6 +1,14 @@
# frozen_string_literal: true
require 'rails_helper'
describe RepositoryTextValue, type: :model do
let(:repository_text_value) { build :repository_text_value }
it 'is valid' do
expect(repository_text_value).to be_valid
end
it 'should be of class RepositoryTextValue' do
expect(subject.class).to eq RepositoryTextValue
end
@ -19,7 +27,7 @@ describe RepositoryTextValue, type: :model do
it { should have_one :repository_cell }
end
describe 'Should be a valid object' do
describe 'Validations' do
it { should validate_presence_of :repository_cell }
it { should validate_presence_of :data }
it do