Skip to content

Commit

Permalink
Organisation index per service
Browse files Browse the repository at this point in the history
We want an organisation index for each service.
This index page will be shown to the user after he sigin in as a
persona only if the user has multiple organisations.

An organisation can be a school or a provider, the Membership
polymorphic table handles this.

The Placements service will show both schools and providers, the claims
only schools.
  • Loading branch information
CatalinVoineag committed Dec 22, 2023
1 parent a485bee commit 19fd4a6
Show file tree
Hide file tree
Showing 24 changed files with 371 additions and 11 deletions.
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ group :test do
gem "rails-controller-testing"
gem "selenium-webdriver"
gem "shoulda-matchers"
# launch browser when inspecting capybara specs
gem "launchy"
end

group :test, :development do
Expand Down
3 changes: 3 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ GEM
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
language_server-protocol (3.17.0.3)
launchy (2.5.2)
addressable (~> 2.8)
loofah (2.22.0)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
Expand Down Expand Up @@ -525,6 +527,7 @@ DEPENDENCIES
govuk-components (~> 5.0.0)
govuk_design_system_formbuilder (~> 5.0.0)
jsbundling-rails
launchy
mail-notify
omniauth
omniauth-rails_csrf_protection
Expand Down
10 changes: 7 additions & 3 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,13 @@ def current_user
end

def after_sign_in_path
return support_root_path if current_user.support_user?

root_path
if current_user.support_user?
support_root_path
elsif current_user.memberships.many?
organisation_index_path
else
root_path
end
end

def after_sign_out_path
Expand Down
5 changes: 5 additions & 0 deletions app/controllers/claims/organisations_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class Claims::OrganisationsController < ApplicationController
def index
@schools = current_user.schools
end
end
6 changes: 6 additions & 0 deletions app/controllers/placements/organisations_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class Placements::OrganisationsController < ApplicationController
def index
@schools = current_user.schools
@providers = current_user.providers
end
end
11 changes: 9 additions & 2 deletions app/helpers/routes_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@ module RoutesHelper
def root_path
{
claims: claims_root_path,
placements: placements_root_path
placements: placements_root_path,
}.fetch current_service
end

def support_root_path
{
claims: root_path, # TODO: claims support path in another PR
placements: placements_support_root_path
placements: placements_support_root_path,
}.fetch current_service
end

def organisation_index_path
{
claims: claims_organisations_path,
placements: placements_organisations_path,
}.fetch current_service
end
end
24 changes: 24 additions & 0 deletions app/models/membership.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# == Schema Information
#
# Table name: memberships
#
# id :uuid not null, primary key
# organisation_type :string not null
# created_at :datetime not null
# updated_at :datetime not null
# organisation_id :uuid not null
# user_id :uuid not null
#
# Indexes
#
# index_memberships_on_organisation (organisation_type,organisation_id)
# index_memberships_on_user_id (user_id)
#
# Foreign Keys
#
# fk_rails_... (user_id => users.id)
#
class Membership < ApplicationRecord
belongs_to :user
belongs_to :organisation, polymorphic: true
end
2 changes: 2 additions & 0 deletions app/models/provider.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
# index_providers_on_provider_code (provider_code) UNIQUE
#
class Provider < ApplicationRecord
has_many :memberships, as: :organisation

validates :provider_code, presence: true
validates :provider_code, uniqueness: { case_sensitive: false }
end
2 changes: 2 additions & 0 deletions app/models/school.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#
class School < ApplicationRecord
belongs_to :gias_school, foreign_key: :urn, primary_key: :urn
has_many :memberships, as: :organisation

validates :urn, presence: true
validates :urn, uniqueness: { case_sensitive: false }

Expand Down
10 changes: 10 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@
# index_users_on_service_and_email (service,email) UNIQUE
#
class User < ApplicationRecord
has_many :memberships
has_many :schools,
through: :memberships,
source: :organisation,
source_type: "School"
has_many :providers,
through: :memberships,
source: :organisation,
source_type: "Provider"

enum :service,
{ no_service: "no_service", claims: "claims", placements: "placements" },
validate: true
Expand Down
15 changes: 15 additions & 0 deletions app/views/claims/organisations/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<h1 class="govuk-heading-xl"><%= t("organisations") %></h1>

<% if @schools.any? %>
<ul class="govuk-list">
<% @schools.each do |school| %>
<li>
<%= govuk_link_to school.name, request.env["PATH_INFO"], no_visited_state: true %>
</li>
<% end %>
</ul>
<% end %>
</div>
</div>
27 changes: 27 additions & 0 deletions app/views/placements/organisations/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<h1 class="govuk-heading-xl"><%= t("organisations") %></h1>

<% if @schools.any? %>
<h2 class="govuk-heading-l"><%= t("schools") %></h2>
<ul class="govuk-list">
<% @schools.each do |school| %>
<li>
<%= govuk_link_to school.name, request.env["PATH_INFO"], no_visited_state: true %>
</li>
<% end %>
</ul>
<% end %>

<% if @providers.any? %>
<h2 class="govuk-heading-l"><%= t("providers") %></h2>
<ul class="govuk-list">
<% @providers.each do |provider| %>
<li>
<%= govuk_link_to provider.provider_code, request.env["PATH_INFO"], no_visited_state: true %>
</li>
<% end %>
</ul>
<% end %>
</div>
</div>
2 changes: 2 additions & 0 deletions config/routes/claims.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
scope module: :claims, as: :claims, constraints: { host: ENV["CLAIMS_HOST"] } do
root to: "pages#index"

resources :organisations, only: [:index]
end
2 changes: 2 additions & 0 deletions config/routes/placements.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@
root to: redirect("/support/organisations")
resources :organisations, only: :index
end

resources :organisations, only: [:index]
end
10 changes: 10 additions & 0 deletions db/migrate/20231220143008_create_memberships.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class CreateMemberships < ActiveRecord::Migration[7.1]
def change
create_table :memberships, id: :uuid do |t|
t.references :user, null: false, foreign_key: true, type: :uuid
t.references :organisation, polymorphic: true, null: false, type: :uuid

t.timestamps
end
end
end
13 changes: 12 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.1].define(version: 2023_12_16_102842) do
ActiveRecord::Schema[7.1].define(version: 2023_12_20_143008) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

Expand Down Expand Up @@ -41,6 +41,16 @@
t.index ["urn"], name: "index_gias_schools_on_urn", unique: true
end

create_table "memberships", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.uuid "user_id", null: false
t.string "organisation_type", null: false
t.uuid "organisation_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["organisation_type", "organisation_id"], name: "index_memberships_on_organisation"
t.index ["user_id"], name: "index_memberships_on_user_id"
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
Expand Down Expand Up @@ -70,4 +80,5 @@
t.index ["service", "email"], name: "index_users_on_service_and_email", unique: true
end

add_foreign_key "memberships", "users"
end
37 changes: 34 additions & 3 deletions db/seeds.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# This file should contain all the record creation needed to seed the database with its default values.
# The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup).
#
SCHOOLS = [
{ claims: true },
{ placements: true },
{ claims: true, placements: true },
{ claims: true, placements: true },
].freeze

# Persona Creation (Dummy User Creation)
Rails.logger.debug "Creating Personas"

Expand All @@ -12,3 +16,30 @@
end

Rails.logger.debug "Personas successfully created!"

Rake::Task["gias_update"].invoke unless GiasSchool.any?
gias_scools = GiasSchool.last(SCHOOLS.count)

SCHOOLS.each.with_index do |school_attributes, index|
school = School.find_or_initialize_by(**school_attributes)
school.urn = gias_scools[index].urn

school.save!
end

User
.where(first_name: %w[Anne Patricia])
.each do |user|
school = School.public_send(user.service).first
user.memberships.find_or_create_by!(organisation: school)
end

User
.where(first_name: %w[Mary Colin])
.each do |user|
schools = School.where("#{user.service}": true)

schools.each do |school|
user.memberships.find_or_create_by!(organisation: school)
end
end
26 changes: 26 additions & 0 deletions spec/factories/memberships.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# == Schema Information
#
# Table name: memberships
#
# id :uuid not null, primary key
# organisation_type :string not null
# created_at :datetime not null
# updated_at :datetime not null
# organisation_id :uuid not null
# user_id :uuid not null
#
# Indexes
#
# index_memberships_on_organisation (organisation_type,organisation_id)
# index_memberships_on_user_id (user_id)
#
# Foreign Keys
#
# fk_rails_... (user_id => users.id)
#
FactoryBot.define do
factory :membership do
association :user
association :organisation, factory: :school
end
end
32 changes: 32 additions & 0 deletions spec/models/membership_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# == Schema Information
#
# Table name: memberships
#
# id :uuid not null, primary key
# organisation_type :string not null
# created_at :datetime not null
# updated_at :datetime not null
# organisation_id :uuid not null
# user_id :uuid not null
#
# Indexes
#
# index_memberships_on_organisation (organisation_type,organisation_id)
# index_memberships_on_user_id (user_id)
#
# Foreign Keys
#
# fk_rails_... (user_id => users.id)
#
require "rails_helper"

RSpec.describe Membership, type: :model do
subject { create(:membership) }

context "associations" do
it do
should belong_to(:user)
should belong_to(:organisation)
end
end
end
4 changes: 4 additions & 0 deletions spec/models/provider_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
require "rails_helper"

RSpec.describe Provider, type: :model do
context "associations" do
it { should have_many(:memberships) }
end

context "validations" do
subject { create(:provider) }

Expand Down
7 changes: 6 additions & 1 deletion spec/models/school_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@
context "associations" do
it do
should belong_to(:gias_school).with_foreign_key(:urn).with_primary_key(
:urn
:urn,
)
should have_many(:memberships)
end
end

Expand All @@ -33,6 +34,10 @@
it { is_expected.to validate_uniqueness_of(:urn).case_insensitive }
end

context "delegations" do
it { should delegate_method(:name).to(:gias_school) }
end

context "scopes" do
describe "services" do
let!(:placements_on) { create(:school, placements: true) }
Expand Down
10 changes: 9 additions & 1 deletion spec/models/user_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,19 @@
RSpec.describe User, type: :model do
subject { create(:user) }

context "associations" do
it do
should have_many(:memberships)
should have_many(:schools).through(:memberships).source(:organisation)
should have_many(:providers).through(:memberships).source(:organisation)
end
end

describe "validations" do
it { is_expected.to validate_presence_of(:email) }
it do
is_expected.to validate_uniqueness_of(:email).scoped_to(
:service
:service,
).case_insensitive
end
it { is_expected.to validate_presence_of(:first_name) }
Expand Down
Loading

0 comments on commit 19fd4a6

Please sign in to comment.