From 2e05f0b07922f0dbc91e2f59c5b796f21f83672e Mon Sep 17 00:00:00 2001 From: Lori Bailey <44073106+elceebee@users.noreply.github.com> Date: Sat, 16 Dec 2023 12:18:18 +0000 Subject: [PATCH] Migrations for basic data models (user, school, provider) --- app/models/claims/school.rb | 20 +++++++ app/models/claims/user.rb | 20 +++++++ app/models/gias_school.rb | 2 + app/models/persona.rb | 16 +++--- app/models/placements/school.rb | 20 +++++++ app/models/placements/support_user.rb | 20 +++++++ app/models/placements/user.rb | 20 +++++++ app/models/provider.rb | 17 ++++++ app/models/school.rb | 25 +++++++++ app/models/user.rb | 25 ++++++--- config/initializers/persona.rb | 7 ++- db/migrate/20231214141009_create_schools.rb | 11 ++++ db/migrate/20231214142055_create_providers.rb | 9 ++++ ...0231216101427_add_support_user_to_users.rb | 5 ++ ...20231216101536_add_service_enum_to_user.rb | 6 +++ ...add_index_to_users_on_email_and_service.rb | 6 +++ db/schema.rb | 28 +++++++++- db/seeds.rb | 13 ++--- docs/data-model.md | 11 ++-- spec/factories/persona.rb | 2 + spec/factories/providers.rb | 18 +++++++ spec/factories/schools.rb | 30 +++++++++++ spec/factories/users.rb | 29 +++++++--- spec/models/claims/school_spec.rb | 30 +++++++++++ spec/models/claims/user_spec.rb | 31 +++++++++++ spec/models/persona_spec.rb | 16 +++--- spec/models/placements/schools_spec.rb | 13 +++++ spec/models/placements/support_user_spec.rb | 35 ++++++++++++ spec/models/placements/user_spec.rb | 31 +++++++++++ spec/models/provider_spec.rb | 23 ++++++++ spec/models/school_spec.rb | 53 +++++++++++++++++++ spec/models/user_spec.rb | 22 +++++--- 32 files changed, 561 insertions(+), 53 deletions(-) create mode 100644 app/models/claims/school.rb create mode 100644 app/models/claims/user.rb create mode 100644 app/models/placements/school.rb create mode 100644 app/models/placements/support_user.rb create mode 100644 app/models/placements/user.rb create mode 100644 app/models/provider.rb create mode 100644 app/models/school.rb create mode 100644 db/migrate/20231214141009_create_schools.rb create mode 100644 db/migrate/20231214142055_create_providers.rb create mode 100644 db/migrate/20231216101427_add_support_user_to_users.rb create mode 100644 db/migrate/20231216101536_add_service_enum_to_user.rb create mode 100644 db/migrate/20231216102842_add_index_to_users_on_email_and_service.rb create mode 100644 spec/factories/providers.rb create mode 100644 spec/factories/schools.rb create mode 100644 spec/models/claims/school_spec.rb create mode 100644 spec/models/claims/user_spec.rb create mode 100644 spec/models/placements/schools_spec.rb create mode 100644 spec/models/placements/support_user_spec.rb create mode 100644 spec/models/placements/user_spec.rb create mode 100644 spec/models/provider_spec.rb create mode 100644 spec/models/school_spec.rb diff --git a/app/models/claims/school.rb b/app/models/claims/school.rb new file mode 100644 index 000000000..5fe39a5c9 --- /dev/null +++ b/app/models/claims/school.rb @@ -0,0 +1,20 @@ +# == Schema Information +# +# Table name: schools +# +# id :uuid not null, primary key +# claims :boolean default(FALSE) +# placements :boolean default(FALSE) +# urn :string not null +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_schools_on_claims (claims) +# index_schools_on_placements (placements) +# index_schools_on_urn (urn) UNIQUE +# +class Claims::School < School + default_scope { claims } +end diff --git a/app/models/claims/user.rb b/app/models/claims/user.rb new file mode 100644 index 000000000..9d32d5a0a --- /dev/null +++ b/app/models/claims/user.rb @@ -0,0 +1,20 @@ +# == Schema Information +# +# Table name: users +# +# id :uuid not null, primary key +# email :string not null +# first_name :string not null +# last_name :string not null +# service :enum not null +# support_user :boolean default(FALSE) +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_users_on_service_and_email (service,email) UNIQUE +# +class Claims::User < User + default_scope { claims } +end diff --git a/app/models/gias_school.rb b/app/models/gias_school.rb index 2eabafad1..922e51e1a 100644 --- a/app/models/gias_school.rb +++ b/app/models/gias_school.rb @@ -21,6 +21,8 @@ # index_gias_schools_on_urn (urn) UNIQUE # class GiasSchool < ApplicationRecord + has_one :school, foreign_key: :urn, primary_key: :urn + validates :urn, presence: true validates :urn, uniqueness: { case_sensitive: false } validates :name, presence: true diff --git a/app/models/persona.rb b/app/models/persona.rb index 572b59cc1..cbfc08d24 100644 --- a/app/models/persona.rb +++ b/app/models/persona.rb @@ -2,16 +2,18 @@ # # Table name: users # -# id :uuid not null, primary key -# email :string not null -# first_name :string not null -# last_name :string not null -# created_at :datetime not null -# updated_at :datetime not null +# id :uuid not null, primary key +# email :string not null +# first_name :string not null +# last_name :string not null +# service :enum not null +# support_user :boolean default(FALSE) +# created_at :datetime not null +# updated_at :datetime not null # # Indexes # -# index_users_on_email (email) UNIQUE +# index_users_on_service_and_email (service,email) UNIQUE # class Persona < User default_scope { where(email: PERSONA_EMAILS) } diff --git a/app/models/placements/school.rb b/app/models/placements/school.rb new file mode 100644 index 000000000..f29d33c83 --- /dev/null +++ b/app/models/placements/school.rb @@ -0,0 +1,20 @@ +# == Schema Information +# +# Table name: schools +# +# id :uuid not null, primary key +# claims :boolean default(FALSE) +# placements :boolean default(FALSE) +# urn :string not null +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_schools_on_claims (claims) +# index_schools_on_placements (placements) +# index_schools_on_urn (urn) UNIQUE +# +class Placements::School < School + default_scope { placements } +end diff --git a/app/models/placements/support_user.rb b/app/models/placements/support_user.rb new file mode 100644 index 000000000..e142fad90 --- /dev/null +++ b/app/models/placements/support_user.rb @@ -0,0 +1,20 @@ +# == Schema Information +# +# Table name: users +# +# id :uuid not null, primary key +# email :string not null +# first_name :string not null +# last_name :string not null +# service :enum not null +# support_user :boolean default(FALSE) +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_users_on_service_and_email (service,email) UNIQUE +# +class Placements::SupportUser < Placements::User + default_scope { support_users } +end diff --git a/app/models/placements/user.rb b/app/models/placements/user.rb new file mode 100644 index 000000000..fc3853dba --- /dev/null +++ b/app/models/placements/user.rb @@ -0,0 +1,20 @@ +# == Schema Information +# +# Table name: users +# +# id :uuid not null, primary key +# email :string not null +# first_name :string not null +# last_name :string not null +# service :enum not null +# support_user :boolean default(FALSE) +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_users_on_service_and_email (service,email) UNIQUE +# +class Placements::User < User + default_scope { placements } +end diff --git a/app/models/provider.rb b/app/models/provider.rb new file mode 100644 index 000000000..04dc0294e --- /dev/null +++ b/app/models/provider.rb @@ -0,0 +1,17 @@ +# == Schema Information +# +# Table name: providers +# +# id :uuid not null, primary key +# provider_code :string not null +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_providers_on_provider_code (provider_code) UNIQUE +# +class Provider < ApplicationRecord + validates :provider_code, presence: true + validates :provider_code, uniqueness: { case_sensitive: false } +end diff --git a/app/models/school.rb b/app/models/school.rb new file mode 100644 index 000000000..ba55941bb --- /dev/null +++ b/app/models/school.rb @@ -0,0 +1,25 @@ +# == Schema Information +# +# Table name: schools +# +# id :uuid not null, primary key +# claims :boolean default(FALSE) +# placements :boolean default(FALSE) +# urn :string not null +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_schools_on_claims (claims) +# index_schools_on_placements (placements) +# index_schools_on_urn (urn) UNIQUE +# +class School < ApplicationRecord + has_one :gias_school, foreign_key: :urn, primary_key: :urn + validates :urn, presence: true + validates :urn, uniqueness: { case_sensitive: false } + + scope :placements, -> { where placements: true } + scope :claims, -> { where claims: true } +end diff --git a/app/models/user.rb b/app/models/user.rb index 95b8e7cc7..c6e90b221 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -2,20 +2,29 @@ # # Table name: users # -# id :uuid not null, primary key -# email :string not null -# first_name :string not null -# last_name :string not null -# created_at :datetime not null -# updated_at :datetime not null +# id :uuid not null, primary key +# email :string not null +# first_name :string not null +# last_name :string not null +# service :enum not null +# support_user :boolean default(FALSE) +# created_at :datetime not null +# updated_at :datetime not null # # Indexes # -# index_users_on_email (email) UNIQUE +# index_users_on_service_and_email (service,email) UNIQUE # class User < ApplicationRecord + enum :service, + { no_service: "no_service", claims: "claims", placements: "placements" }, + validate: true + validates :first_name, presence: true validates :last_name, presence: true validates :email, presence: true - validates :email, uniqueness: { case_sensitive: false } + validates :service, presence: true + validates :email, uniqueness: { scope: :service, case_sensitive: false } + + scope :support_users, -> { where(support_user: true) } end diff --git a/config/initializers/persona.rb b/config/initializers/persona.rb index 3caf221cc..c60e4af2e 100644 --- a/config/initializers/persona.rb +++ b/config/initializers/persona.rb @@ -9,7 +9,12 @@ email: "patricia@example.com" }, { first_name: "Mary", last_name: "Lawson", email: "mary@example.com" }, - { first_name: "Colin", last_name: "Chapman", email: "colin@example.com" } + { + first_name: "Colin", + last_name: "Chapman", + email: "colin@example.com", + support_user: true + } ].push((DEVELOPER_PERSONA if defined?(DEVELOPER_PERSONA))).compact.freeze PERSONA_EMAILS = PERSONAS.map { |persona| persona[:email] } diff --git a/db/migrate/20231214141009_create_schools.rb b/db/migrate/20231214141009_create_schools.rb new file mode 100644 index 000000000..5311b0932 --- /dev/null +++ b/db/migrate/20231214141009_create_schools.rb @@ -0,0 +1,11 @@ +class CreateSchools < ActiveRecord::Migration[7.1] + def change + create_table :schools, id: :uuid do |t| + t.string :urn, null: false, index: { unique: true } + t.boolean :placements, default: false, index: true + t.boolean :claims, default: false, index: true + + t.timestamps + end + end +end diff --git a/db/migrate/20231214142055_create_providers.rb b/db/migrate/20231214142055_create_providers.rb new file mode 100644 index 000000000..76ec208ec --- /dev/null +++ b/db/migrate/20231214142055_create_providers.rb @@ -0,0 +1,9 @@ +class CreateProviders < ActiveRecord::Migration[7.1] + def change + create_table :providers, id: :uuid do |t| + t.string :provider_code, null: false, index: { unique: true } + + t.timestamps + end + end +end diff --git a/db/migrate/20231216101427_add_support_user_to_users.rb b/db/migrate/20231216101427_add_support_user_to_users.rb new file mode 100644 index 000000000..4f4860ac9 --- /dev/null +++ b/db/migrate/20231216101427_add_support_user_to_users.rb @@ -0,0 +1,5 @@ +class AddSupportUserToUsers < ActiveRecord::Migration[7.1] + def change + add_column :users, :support_user, :boolean, default: false + end +end diff --git a/db/migrate/20231216101536_add_service_enum_to_user.rb b/db/migrate/20231216101536_add_service_enum_to_user.rb new file mode 100644 index 000000000..16fa9ed85 --- /dev/null +++ b/db/migrate/20231216101536_add_service_enum_to_user.rb @@ -0,0 +1,6 @@ +class AddServiceEnumToUser < ActiveRecord::Migration[7.1] + def change + create_enum :service, %w[claims placements] + add_column :users, :service, :enum, enum_type: "service", null: false # rubocop:disable Rails/NotNullColumn + end +end diff --git a/db/migrate/20231216102842_add_index_to_users_on_email_and_service.rb b/db/migrate/20231216102842_add_index_to_users_on_email_and_service.rb new file mode 100644 index 000000000..8b7fbbd57 --- /dev/null +++ b/db/migrate/20231216102842_add_index_to_users_on_email_and_service.rb @@ -0,0 +1,6 @@ +class AddIndexToUsersOnEmailAndService < ActiveRecord::Migration[7.1] + def change + remove_index :users, :email + add_index :users, %i[service email], unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 0ee8ff476..1d78e0600 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,10 +10,14 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2023_12_13_110952) do +ActiveRecord::Schema[7.1].define(version: 2023_12_16_102842) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" + # Custom types defined in this database. + # Note that some types may not work with other database engines. Be careful if changing database. + create_enum "service", ["claims", "placements"] + create_table "flipflop_features", force: :cascade do |t| t.string "key", null: false t.boolean "enabled", default: false, null: false @@ -37,13 +41,33 @@ t.index ["urn"], name: "index_gias_schools_on_urn", unique: true end + create_table "providers", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.string "provider_code", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["provider_code"], name: "index_providers_on_provider_code", unique: true + end + + create_table "schools", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.string "urn", null: false + t.boolean "placements", default: false + t.boolean "claims", default: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["claims"], name: "index_schools_on_claims" + t.index ["placements"], name: "index_schools_on_placements" + t.index ["urn"], name: "index_schools_on_urn", unique: true + end + create_table "users", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.string "first_name", null: false t.string "last_name", null: false t.string "email", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.index ["email"], name: "index_users_on_email", unique: true + t.boolean "support_user", default: false + t.enum "service", null: false, enum_type: "service" + t.index ["service", "email"], name: "index_users_on_service_and_email", unique: true end end diff --git a/db/seeds.rb b/db/seeds.rb index 0c7e8f59d..866bc4b31 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -4,14 +4,11 @@ # Persona Creation (Dummy User Creation) Rails.logger.debug "Creating Personas" -# For each persona... -PERSONAS.each do |persona_attributes| - # Create the persona - Persona.find_or_create_by!( - first_name: persona_attributes[:first_name], - last_name: persona_attributes[:last_name], - email: persona_attributes[:email] - ) +# Create the same personas for each service +%w[claims placements].each do |service| + PERSONAS.each do |persona_attributes| + Persona.find_or_create_by!(**persona_attributes, service:) + end end Rails.logger.debug "Personas successfully created!" diff --git a/docs/data-model.md b/docs/data-model.md index e17aebf90..b3e980cc4 100644 --- a/docs/data-model.md +++ b/docs/data-model.md @@ -116,11 +116,11 @@ The `placements_enabled` and `claims_enabled` boolean attributes will indicate w For example: -| urn | name | placements_enabled | claims_enabled | -| --- | --- | --- | --- | -| 100000 | School A | 1 | 0 | -| 100001 | School B | 0 | 1 | -| 100002 | School C | 1 | 1 | +| urn | name | placements_enabled | claims_enabled | +| ------ | -------- | ------------------ | -------------- | +| 100000 | School A | 1 | 0 | +| 100001 | School B | 0 | 1 | +| 100002 | School C | 1 | 1 | - School A has only been onboarded into the School Placements service. - School B has only been onboarded into the Track & Pay service. @@ -153,6 +153,7 @@ Since the services will be on different hostnames, they will automatically have Users are scoped by `service`, which will be either `"placements"` or `"claims"`. We can consider Users to have the unique composite index: + - `[service, email]` ### Memberships diff --git a/spec/factories/persona.rb b/spec/factories/persona.rb index 6b5369e3a..8fb2e834b 100644 --- a/spec/factories/persona.rb +++ b/spec/factories/persona.rb @@ -2,6 +2,7 @@ factory :persona do email { "anne_wilson@example.org" } first_name { "Persona" } + service { "claims" } sequence(:last_name) trait :anne do @@ -25,6 +26,7 @@ email { "colin@example.com" } first_name { "Colin" } last_name { "Chapman" } + support_user { true } end end end diff --git a/spec/factories/providers.rb b/spec/factories/providers.rb new file mode 100644 index 000000000..fac57e7d6 --- /dev/null +++ b/spec/factories/providers.rb @@ -0,0 +1,18 @@ +# == Schema Information +# +# Table name: providers +# +# id :uuid not null, primary key +# provider_code :string not null +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_providers_on_provider_code (provider_code) UNIQUE +# +FactoryBot.define do + factory :provider do + provider_code { SecureRandom.hex(5) } + end +end diff --git a/spec/factories/schools.rb b/spec/factories/schools.rb new file mode 100644 index 000000000..617fc638f --- /dev/null +++ b/spec/factories/schools.rb @@ -0,0 +1,30 @@ +# == Schema Information +# +# Table name: schools +# +# id :uuid not null, primary key +# claims :boolean default(FALSE) +# placements :boolean default(FALSE) +# urn :string not null +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_schools_on_claims (claims) +# index_schools_on_placements (placements) +# index_schools_on_urn (urn) UNIQUE +# +FactoryBot.define do + factory :school do + sequence(:urn) { _1 } + + trait :claims do + claims { true } + end + + trait :placements do + placements { true } + end + end +end diff --git a/spec/factories/users.rb b/spec/factories/users.rb index 1e347a55d..4ab5b0e27 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -2,21 +2,36 @@ # # Table name: users # -# id :uuid not null, primary key -# email :string not null -# first_name :string not null -# last_name :string not null -# created_at :datetime not null -# updated_at :datetime not null +# id :uuid not null, primary key +# email :string not null +# first_name :string not null +# last_name :string not null +# service :enum not null +# support_user :boolean default(FALSE) +# created_at :datetime not null +# updated_at :datetime not null # # Indexes # -# index_users_on_email (email) UNIQUE +# index_users_on_service_and_email (service,email) UNIQUE # FactoryBot.define do factory :user do sequence(:email) { |n| "user#{n}@example.com" } first_name { "User" } + service { %w[placements claims].sample } sequence(:last_name) + + trait :support do + support_user { true } + end + end + + factory :claims_user, class: "Claims::User", parent: :user do + service { "claims" } + end + + factory :placements_user, class: "Placements::User", parent: :user do + service { "placements" } end end diff --git a/spec/models/claims/school_spec.rb b/spec/models/claims/school_spec.rb new file mode 100644 index 000000000..873f36cc7 --- /dev/null +++ b/spec/models/claims/school_spec.rb @@ -0,0 +1,30 @@ +# == Schema Information +# +# Table name: schools +# +# id :uuid not null, primary key +# claims :boolean default(FALSE) +# placements :boolean default(FALSE) +# urn :string not null +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_schools_on_claims (claims) +# index_schools_on_placements (placements) +# index_schools_on_urn (urn) UNIQUE +# +require "rails_helper" + +RSpec.describe Claims::School do + describe "default scope" do + let!(:school_with_claims) { create(:school, :claims) } + let!(:school_without_claims) { create(:school) } + + it "is scoped to schools using the claims service" do + school = described_class.find(school_with_claims.id) + expect(described_class.all).to contain_exactly(school) + end + end +end diff --git a/spec/models/claims/user_spec.rb b/spec/models/claims/user_spec.rb new file mode 100644 index 000000000..3cd1379b7 --- /dev/null +++ b/spec/models/claims/user_spec.rb @@ -0,0 +1,31 @@ +# == Schema Information +# +# Table name: users +# +# id :uuid not null, primary key +# email :string not null +# first_name :string not null +# last_name :string not null +# service :enum not null +# support_user :boolean default(FALSE) +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_users_on_service_and_email (service,email) UNIQUE +# +require "rails_helper" + +RSpec.describe Claims::User do + describe "default scope" do + let(:email) { "same_email@email.co.uk" } + let!(:user_with_claims_service) { create(:claims_user, email:) } + let!(:user_with_placements_service) { create(:placements_user, email:) } + + it "is scoped to users of the claims service" do + user = described_class.find(user_with_claims_service.id) + expect(described_class.all).to contain_exactly(user) + end + end +end diff --git a/spec/models/persona_spec.rb b/spec/models/persona_spec.rb index 9a74a7310..4ba8f45e3 100644 --- a/spec/models/persona_spec.rb +++ b/spec/models/persona_spec.rb @@ -2,16 +2,18 @@ # # Table name: users # -# id :uuid not null, primary key -# email :string not null -# first_name :string not null -# last_name :string not null -# created_at :datetime not null -# updated_at :datetime not null +# id :uuid not null, primary key +# email :string not null +# first_name :string not null +# last_name :string not null +# service :enum not null +# support_user :boolean default(FALSE) +# created_at :datetime not null +# updated_at :datetime not null # # Indexes # -# index_users_on_email (email) UNIQUE +# index_users_on_service_and_email (service,email) UNIQUE # RSpec.describe Persona, type: :model do describe "validations" do diff --git a/spec/models/placements/schools_spec.rb b/spec/models/placements/schools_spec.rb new file mode 100644 index 000000000..a4c13a825 --- /dev/null +++ b/spec/models/placements/schools_spec.rb @@ -0,0 +1,13 @@ +require "rails_helper" + +RSpec.describe Placements::School do + describe "default scope" do + let!(:school_with_placements) { create(:school, :placements) } + let!(:school_without_placements) { create(:school) } + + it "is scoped to schools using the placement service" do + school = described_class.find(school_with_placements.id) + expect(described_class.all).to contain_exactly(school) + end + end +end diff --git a/spec/models/placements/support_user_spec.rb b/spec/models/placements/support_user_spec.rb new file mode 100644 index 000000000..4e1b0ed35 --- /dev/null +++ b/spec/models/placements/support_user_spec.rb @@ -0,0 +1,35 @@ +# == Schema Information +# +# Table name: users +# +# id :uuid not null, primary key +# email :string not null +# first_name :string not null +# last_name :string not null +# service :enum not null +# support_user :boolean default(FALSE) +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_users_on_service_and_email (service,email) UNIQUE +# +require "rails_helper" + +RSpec.describe Placements::SupportUser do + describe "default scope" do + let(:email) { "same_email@email.co.uk" } + let!(:support_user_with_placements_service) do + create(:placements_user, :support, email:) + end + let!(:support_user_with_claims_service) do + create(:claims_user, :support, email:) + end + + it "is scoped to placement support users" do + user = described_class.find(support_user_with_placements_service.id) + expect(described_class.all).to contain_exactly(user) + end + end +end diff --git a/spec/models/placements/user_spec.rb b/spec/models/placements/user_spec.rb new file mode 100644 index 000000000..fa1aa8878 --- /dev/null +++ b/spec/models/placements/user_spec.rb @@ -0,0 +1,31 @@ +# == Schema Information +# +# Table name: users +# +# id :uuid not null, primary key +# email :string not null +# first_name :string not null +# last_name :string not null +# service :enum not null +# support_user :boolean default(FALSE) +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_users_on_service_and_email (service,email) UNIQUE +# +require "rails_helper" + +RSpec.describe Placements::User do + describe "default scope" do + let(:email) { "same_email@email.co.uk" } + let!(:user_with_placements_service) { create(:placements_user, email:) } + let!(:user_with_claims_service) { create(:claims_user, email:) } + + it "is scoped to placement service users" do + user = described_class.find(user_with_placements_service.id) + expect(described_class.all).to contain_exactly(user) + end + end +end diff --git a/spec/models/provider_spec.rb b/spec/models/provider_spec.rb new file mode 100644 index 000000000..d576195e4 --- /dev/null +++ b/spec/models/provider_spec.rb @@ -0,0 +1,23 @@ +# == Schema Information +# +# Table name: providers +# +# id :uuid not null, primary key +# provider_code :string not null +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_providers_on_provider_code (provider_code) UNIQUE +# +require "rails_helper" + +RSpec.describe Provider, type: :model do + context "validations" do + subject { create(:provider) } + + it { is_expected.to validate_presence_of(:provider_code) } + it { is_expected.to validate_uniqueness_of(:provider_code).case_insensitive } + end +end diff --git a/spec/models/school_spec.rb b/spec/models/school_spec.rb new file mode 100644 index 000000000..bb162eaea --- /dev/null +++ b/spec/models/school_spec.rb @@ -0,0 +1,53 @@ +# == Schema Information +# +# Table name: schools +# +# id :uuid not null, primary key +# claims :boolean default(FALSE) +# placements :boolean default(FALSE) +# urn :string not null +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_schools_on_claims (claims) +# index_schools_on_placements (placements) +# index_schools_on_urn (urn) UNIQUE +# +require "rails_helper" + +RSpec.describe School, type: :model do + context "associations" do + it do + should have_one(:gias_school).with_foreign_key(:urn).with_primary_key( + :urn + ) + end + end + + context "validations" do + subject { create(:school) } + + it { is_expected.to validate_presence_of(:urn) } + it { is_expected.to validate_uniqueness_of(:urn).case_insensitive } + end + + context "scopes" do + describe "services" do + let!(:placements_on) { create(:school, placements: true) } + let!(:claims_on) { create(:school, claims: true) } + describe "#placements" do + it "only returns schools in the placements service" do + expect(described_class.placements).to contain_exactly(placements_on) + end + end + + describe "#claims" do + it "only returns schools in the claims service" do + expect(described_class.claims).to contain_exactly(claims_on) + end + end + end + end +end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 4e39376c2..d0933156c 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -2,16 +2,18 @@ # # Table name: users # -# id :uuid not null, primary key -# email :string not null -# first_name :string not null -# last_name :string not null -# created_at :datetime not null -# updated_at :datetime not null +# id :uuid not null, primary key +# email :string not null +# first_name :string not null +# last_name :string not null +# service :enum not null +# support_user :boolean default(FALSE) +# created_at :datetime not null +# updated_at :datetime not null # # Indexes # -# index_users_on_email (email) UNIQUE +# index_users_on_service_and_email (service,email) UNIQUE # require "rails_helper" @@ -20,7 +22,11 @@ describe "validations" do it { is_expected.to validate_presence_of(:email) } - it { is_expected.to validate_uniqueness_of(:email).case_insensitive } + it do + is_expected.to validate_uniqueness_of(:email).scoped_to( + :service + ).case_insensitive + end it { is_expected.to validate_presence_of(:first_name) } it { is_expected.to validate_presence_of(:last_name) } end