Merge pull request #2 from turniere/ticket/TURNIERE-71
Implement database schema, matching models and specs
This commit is contained in:
commit
feee3f9378
|
|
@ -1 +1,4 @@
|
|||
fail_on_violations: true
|
||||
|
||||
ruby:
|
||||
config_file: .rubocop.yml
|
||||
|
|
|
|||
13
.rubocop.yml
13
.rubocop.yml
|
|
@ -30,3 +30,16 @@ Metrics/AbcSize:
|
|||
Exclude:
|
||||
- "db/migrate/*"
|
||||
Max: 20
|
||||
|
||||
Metrics/BlockLength:
|
||||
ExcludedMethods:
|
||||
- "namespace"
|
||||
- "create_table"
|
||||
Exclude:
|
||||
- "config/**/*.rb"
|
||||
- "spec/**/*.rb"
|
||||
|
||||
# Disable documentation checks for now
|
||||
# should be done with yard instead
|
||||
Style/Documentation:
|
||||
Enabled: false
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Group < ApplicationRecord
|
||||
belongs_to :matches
|
||||
belongs_to :teams
|
||||
belongs_to :stage
|
||||
has_many :matches, dependent: :destroy
|
||||
has_many :group_scores, dependent: :destroy
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class GroupScore < ApplicationRecord
|
||||
belongs_to :team
|
||||
belongs_to :group
|
||||
end
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class GroupStage < ApplicationRecord
|
||||
end
|
||||
|
|
@ -1,4 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Match < ApplicationRecord
|
||||
belongs_to :stage
|
||||
belongs_to :group
|
||||
has_many :scores, dependent: :destroy
|
||||
|
||||
validates :scores, length: { maximum: 2 }
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class PlayoffStage < ApplicationRecord
|
||||
end
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Score < ApplicationRecord
|
||||
belongs_to :match
|
||||
belongs_to :team
|
||||
end
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Stage < ApplicationRecord
|
||||
belongs_to :tournament
|
||||
has_many :matches, dependent: :destroy
|
||||
has_many :groups, dependent: :destroy
|
||||
end
|
||||
|
|
@ -1,4 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Team < ApplicationRecord
|
||||
belongs_to :tournament
|
||||
has_many :group_scores, dependent: :destroy
|
||||
has_many :scores, dependent: :destroy
|
||||
|
||||
validates :name, presence: true
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'securerandom'
|
||||
|
||||
class Tournament < ApplicationRecord
|
||||
belongs_to :user
|
||||
has_many :teams, dependent: :destroy
|
||||
has_many :stages, dependent: :destroy
|
||||
|
||||
validates :name, presence: true
|
||||
validates :code, presence: true, uniqueness: true
|
||||
|
||||
alias_attribute :owner, :user
|
||||
|
||||
after_initialize do |tournament|
|
||||
tournament.code ||= SecureRandom.hex 3
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,4 +7,6 @@ class User < ApplicationRecord
|
|||
include DeviseTokenAuth::Concerns::User
|
||||
|
||||
validates :username, presence: true, uniqueness: true
|
||||
|
||||
has_many :tournaments, dependent: :destroy
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,62 +2,16 @@
|
|||
|
||||
class CreateSchema < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :groups do |t|
|
||||
t.string :name
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
create_table :group_stages do |t|
|
||||
t.integer :playoff_size
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
create_table :matches do |t|
|
||||
t.integer :score_team_1
|
||||
t.integer :score_team_2
|
||||
t.integer :state
|
||||
t.integer :position
|
||||
t.boolean :is_group_match
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
create_table :playoff_stages do |t|
|
||||
t.integer :level
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
create_table :teams do |t|
|
||||
t.string :name
|
||||
t.integer :group_score
|
||||
t.integer :group_points_scored
|
||||
t.integer :group_points_recieved
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
create_table :tournaments do |t|
|
||||
t.string :name
|
||||
t.string :code
|
||||
t.string :description
|
||||
t.boolean :public, default: true
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
create_table :users do |t|
|
||||
## Required
|
||||
t.string :provider, null: false, default: 'email'
|
||||
t.string :uid, null: false, default: ''
|
||||
t.string :provider, null: false, default: 'email', index: true
|
||||
t.string :uid, null: false, default: '', index: { unique: true }
|
||||
|
||||
## Database authenticatable
|
||||
t.string :encrypted_password, null: false, default: ''
|
||||
|
||||
## Recoverable
|
||||
t.string :reset_password_token
|
||||
t.string :reset_password_token, index: { unique: true }
|
||||
t.datetime :reset_password_sent_at
|
||||
t.boolean :allow_password_change, default: false
|
||||
|
||||
|
|
@ -72,7 +26,7 @@ class CreateSchema < ActiveRecord::Migration[5.2]
|
|||
t.string :last_sign_in_ip
|
||||
|
||||
## Confirmable
|
||||
t.string :confirmation_token
|
||||
t.string :confirmation_token, index: { unique: true }
|
||||
t.datetime :confirmed_at
|
||||
t.datetime :confirmation_sent_at
|
||||
t.string :unconfirmed_email # Only if using reconfirmable
|
||||
|
|
@ -83,8 +37,8 @@ class CreateSchema < ActiveRecord::Migration[5.2]
|
|||
# t.datetime :locked_at
|
||||
|
||||
## User Info
|
||||
t.string :username
|
||||
t.string :email
|
||||
t.string :username, index: { unique: true }
|
||||
t.string :email, index: { unique: true }
|
||||
|
||||
## Tokens
|
||||
t.text :tokens
|
||||
|
|
@ -92,11 +46,69 @@ class CreateSchema < ActiveRecord::Migration[5.2]
|
|||
t.timestamps
|
||||
end
|
||||
|
||||
add_index :users, :username, unique: true
|
||||
add_index :users, :email, unique: true
|
||||
add_index :users, %i[uid provider], unique: true
|
||||
add_index :users, :reset_password_token, unique: true
|
||||
add_index :users, :confirmation_token, unique: true
|
||||
# add_index :users, :unlock_token, unique: true
|
||||
create_table :tournaments do |t|
|
||||
t.string :name, null: false
|
||||
t.string :code, null: false, index: { unique: true }
|
||||
t.string :description
|
||||
t.boolean :public, default: true
|
||||
|
||||
# relation to owner
|
||||
t.belongs_to :user, index: true, null: false, foreign_key: { on_delete: :cascade }
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
create_table :stages do |t|
|
||||
t.integer :level
|
||||
|
||||
t.belongs_to :tournament, index: true, foreign_key: { on_delete: :cascade }, null: false
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
create_table :groups do |t|
|
||||
t.integer :number
|
||||
|
||||
t.belongs_to :stage, index: true, foreign_key: { on_delete: :cascade }, null: false
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
create_table :matches do |t|
|
||||
t.integer :state, default: 0
|
||||
|
||||
t.belongs_to :stage, index: true, foreign_key: { on_delete: :cascade }
|
||||
t.belongs_to :group, index: true, foreign_key: { on_delete: :cascade }
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
create_table :teams do |t|
|
||||
t.string :name
|
||||
|
||||
t.belongs_to :tournament, index: true, foreign_key: { on_delete: :cascade }
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
create_table :scores do |t|
|
||||
t.integer :score, default: 0
|
||||
|
||||
t.belongs_to :match, index: true, null: false, foreign_key: { on_delete: :cascade }
|
||||
t.belongs_to :team, index: true, null: false, foreign_key: { on_delete: :cascade }
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
create_table :group_scores do |t|
|
||||
t.integer :score, default: 0
|
||||
t.integer :points_scored, default: 0
|
||||
t.integer :points_received, default: 0
|
||||
|
||||
t.belongs_to :team, index: true, foreign_key: { on_delete: :cascade }, null: false
|
||||
t.belongs_to :group, index: true, foreign_key: { on_delete: :cascade }, null: false
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :group_score do
|
||||
team
|
||||
group
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :group do
|
||||
number { 0 }
|
||||
stage
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :match do
|
||||
stage
|
||||
group
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :score do
|
||||
score { 0 }
|
||||
match
|
||||
team
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :stage do
|
||||
tournament
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :team do
|
||||
name { Faker::Dog.name }
|
||||
tournament
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :tournament do
|
||||
name { Faker::Dog.name }
|
||||
description { Faker::Lorem.sentence }
|
||||
user
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :user do
|
||||
username { Faker::Internet.username }
|
||||
email { Faker::Internet.email }
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe GroupScore, type: :model do
|
||||
describe 'association' do
|
||||
it { should belong_to :team }
|
||||
it { should belong_to :group }
|
||||
end
|
||||
|
||||
it 'has a valid factory' do
|
||||
expect(build(:group_score)).to be_valid
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Group, type: :model do
|
||||
describe 'association' do
|
||||
it { should belong_to :stage }
|
||||
it { should have_many :matches }
|
||||
it { should have_many :group_scores }
|
||||
end
|
||||
|
||||
it 'has a valid factory' do
|
||||
expect(build(:group)).to be_valid
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Match, type: :model do
|
||||
context 'association' do
|
||||
it { should have_many :scores }
|
||||
it { should belong_to :stage }
|
||||
it { should belong_to :group }
|
||||
end
|
||||
|
||||
context 'scores' do
|
||||
before do
|
||||
@match = create(:match)
|
||||
@match.scores << build_pair(:score)
|
||||
end
|
||||
|
||||
it 'can only have two scores' do
|
||||
@match.scores << build(:score)
|
||||
expect(@match).to be_invalid
|
||||
end
|
||||
|
||||
it 'can access its scores' do
|
||||
@match.scores[0].score = 0
|
||||
@match.scores[1].score = 0
|
||||
end
|
||||
end
|
||||
|
||||
it 'has a valid factory' do
|
||||
expect(build(:match)).to be_valid
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Score, type: :model do
|
||||
describe 'association' do
|
||||
it { should belong_to :match }
|
||||
it { should belong_to :team }
|
||||
end
|
||||
|
||||
it 'has a valid factory' do
|
||||
expect(build(:score)).to be_valid
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Stage, type: :model do
|
||||
describe 'association' do
|
||||
it { should belong_to :tournament }
|
||||
it { should have_many :matches }
|
||||
it { should have_many :groups }
|
||||
end
|
||||
|
||||
it 'has a valid factory' do
|
||||
expect(build(:stage)).to be_valid
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Team, type: :model do
|
||||
describe 'validation' do
|
||||
it { should validate_presence_of :name }
|
||||
end
|
||||
|
||||
describe 'association' do
|
||||
it { should belong_to :tournament }
|
||||
it { should have_many :group_scores }
|
||||
it { should have_many :scores }
|
||||
end
|
||||
|
||||
it 'has a valid factory' do
|
||||
expect(build(:team)).to be_valid
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Tournament, type: :model do
|
||||
before do
|
||||
@tournament = create(:tournament)
|
||||
end
|
||||
|
||||
describe 'validation' do
|
||||
it { should validate_presence_of :name }
|
||||
it { should validate_presence_of :code }
|
||||
it { should validate_uniqueness_of :code }
|
||||
it { should_not validate_presence_of :description }
|
||||
it { should_not validate_presence_of :public }
|
||||
end
|
||||
|
||||
describe 'initialization' do
|
||||
it 'should have a code' do
|
||||
expect(@tournament.code.length).to be(6)
|
||||
end
|
||||
it 'should be public' do
|
||||
expect(@tournament.public).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'association' do
|
||||
it { should belong_to :user }
|
||||
it { should have_many :teams }
|
||||
it { should have_many :stages }
|
||||
end
|
||||
|
||||
it 'has valid factory' do
|
||||
expect(build(:tournament)).to be_valid
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe User, type: :model do
|
||||
describe 'association' do
|
||||
it { should have_many :tournaments }
|
||||
end
|
||||
|
||||
it 'has a valid factory' do
|
||||
expect(build(:user)).to be_valid
|
||||
end
|
||||
end
|
||||
Loading…
Reference in New Issue