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
|
fail_on_violations: true
|
||||||
|
|
||||||
|
ruby:
|
||||||
|
config_file: .rubocop.yml
|
||||||
|
|
|
||||||
13
.rubocop.yml
13
.rubocop.yml
|
|
@ -30,3 +30,16 @@ Metrics/AbcSize:
|
||||||
Exclude:
|
Exclude:
|
||||||
- "db/migrate/*"
|
- "db/migrate/*"
|
||||||
Max: 20
|
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
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Group < ApplicationRecord
|
class Group < ApplicationRecord
|
||||||
belongs_to :matches
|
belongs_to :stage
|
||||||
belongs_to :teams
|
has_many :matches, dependent: :destroy
|
||||||
|
has_many :group_scores, dependent: :destroy
|
||||||
end
|
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
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Match < ApplicationRecord
|
class Match < ApplicationRecord
|
||||||
|
belongs_to :stage
|
||||||
|
belongs_to :group
|
||||||
|
has_many :scores, dependent: :destroy
|
||||||
|
|
||||||
|
validates :scores, length: { maximum: 2 }
|
||||||
end
|
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
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Team < ApplicationRecord
|
class Team < ApplicationRecord
|
||||||
|
belongs_to :tournament
|
||||||
|
has_many :group_scores, dependent: :destroy
|
||||||
|
has_many :scores, dependent: :destroy
|
||||||
|
|
||||||
|
validates :name, presence: true
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,18 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'securerandom'
|
||||||
|
|
||||||
class Tournament < ApplicationRecord
|
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
|
end
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,6 @@ class User < ApplicationRecord
|
||||||
include DeviseTokenAuth::Concerns::User
|
include DeviseTokenAuth::Concerns::User
|
||||||
|
|
||||||
validates :username, presence: true, uniqueness: true
|
validates :username, presence: true, uniqueness: true
|
||||||
|
|
||||||
|
has_many :tournaments, dependent: :destroy
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -2,62 +2,16 @@
|
||||||
|
|
||||||
class CreateSchema < ActiveRecord::Migration[5.2]
|
class CreateSchema < ActiveRecord::Migration[5.2]
|
||||||
def change
|
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|
|
create_table :users do |t|
|
||||||
## Required
|
## Required
|
||||||
t.string :provider, null: false, default: 'email'
|
t.string :provider, null: false, default: 'email', index: true
|
||||||
t.string :uid, null: false, default: ''
|
t.string :uid, null: false, default: '', index: { unique: true }
|
||||||
|
|
||||||
## Database authenticatable
|
## Database authenticatable
|
||||||
t.string :encrypted_password, null: false, default: ''
|
t.string :encrypted_password, null: false, default: ''
|
||||||
|
|
||||||
## Recoverable
|
## Recoverable
|
||||||
t.string :reset_password_token
|
t.string :reset_password_token, index: { unique: true }
|
||||||
t.datetime :reset_password_sent_at
|
t.datetime :reset_password_sent_at
|
||||||
t.boolean :allow_password_change, default: false
|
t.boolean :allow_password_change, default: false
|
||||||
|
|
||||||
|
|
@ -72,7 +26,7 @@ class CreateSchema < ActiveRecord::Migration[5.2]
|
||||||
t.string :last_sign_in_ip
|
t.string :last_sign_in_ip
|
||||||
|
|
||||||
## Confirmable
|
## Confirmable
|
||||||
t.string :confirmation_token
|
t.string :confirmation_token, index: { unique: true }
|
||||||
t.datetime :confirmed_at
|
t.datetime :confirmed_at
|
||||||
t.datetime :confirmation_sent_at
|
t.datetime :confirmation_sent_at
|
||||||
t.string :unconfirmed_email # Only if using reconfirmable
|
t.string :unconfirmed_email # Only if using reconfirmable
|
||||||
|
|
@ -83,8 +37,8 @@ class CreateSchema < ActiveRecord::Migration[5.2]
|
||||||
# t.datetime :locked_at
|
# t.datetime :locked_at
|
||||||
|
|
||||||
## User Info
|
## User Info
|
||||||
t.string :username
|
t.string :username, index: { unique: true }
|
||||||
t.string :email
|
t.string :email, index: { unique: true }
|
||||||
|
|
||||||
## Tokens
|
## Tokens
|
||||||
t.text :tokens
|
t.text :tokens
|
||||||
|
|
@ -92,11 +46,69 @@ class CreateSchema < ActiveRecord::Migration[5.2]
|
||||||
t.timestamps
|
t.timestamps
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index :users, :username, unique: true
|
create_table :tournaments do |t|
|
||||||
add_index :users, :email, unique: true
|
t.string :name, null: false
|
||||||
add_index :users, %i[uid provider], unique: true
|
t.string :code, null: false, index: { unique: true }
|
||||||
add_index :users, :reset_password_token, unique: true
|
t.string :description
|
||||||
add_index :users, :confirmation_token, unique: true
|
t.boolean :public, default: true
|
||||||
# add_index :users, :unlock_token, unique: 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
|
||||||
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