diff --git a/app/components/find/courses/about_schools_component/view.html.erb b/app/components/find/courses/about_schools_component/view.html.erb
index e4810ef13f..08a4d52a5d 100644
--- a/app/components/find/courses/about_schools_component/view.html.erb
+++ b/app/components/find/courses/about_schools_component/view.html.erb
@@ -16,6 +16,18 @@
<% end %>
<% end %>
+ <% if course.fee_based? %>
+
+ You’ll be placed in schools for most of your course to get classroom experience. You will also spend time at a location where you will study.
+
+ <% else %>
+
+ You will spend most of your time in one school which will employ you. You will also spend some time in another school and at a location where you will study.
+
+ <% end %>
+
+ <%= render Find::Courses::TrainingLocations::View.new(course:, preview: preview?(params)) %>
+
<% if course.published_how_school_placements_work.present? %>
<%= markdown(course.published_how_school_placements_work) %>
<% elsif course.how_school_placements_work.present? %>
@@ -43,17 +55,5 @@
<% end %>
<% end %>
-
- <% if course.site_statuses.map(&:site).uniq.any? %>
-
- <%= course.placements_heading %>
-
-
- <%= t(".work_with_schools") %>
-
-
- <%= govuk_link_to(t(".view_list_of_school_placements"), placements_url) %>
-
- <% end %>
diff --git a/app/components/find/courses/contents_component/view.html.erb b/app/components/find/courses/contents_component/view.html.erb
index f145c89ede..686e3490da 100644
--- a/app/components/find/courses/contents_component/view.html.erb
+++ b/app/components/find/courses/contents_component/view.html.erb
@@ -8,7 +8,7 @@
<% end %>
<%= govuk_link_to t(".fees_and_financial_support"), "#section-financial-support" %>
<% if how_school_placements_work.present? || program_type == "higher_education_programme" || program_type == "scitt_programme" || preview? %>
- <%= govuk_link_to t(".how_school_placements_work"), "#training-locations" %>
+ <%= govuk_link_to t(".where_you_will_train"), "#training-locations" %>
<% end %>
<% if interview_process.present? %>
<%= govuk_link_to t(".interview_process"), "#section-interviews" %>
diff --git a/app/components/find/courses/training_locations/view.html.erb b/app/components/find/courses/training_locations/view.html.erb
new file mode 100644
index 0000000000..3924865665
--- /dev/null
+++ b/app/components/find/courses/training_locations/view.html.erb
@@ -0,0 +1,26 @@
+<%= govuk_summary_list(actions: false) do |summary_list| %>
+ <%= summary_list.with_row do |row| %>
+ <%= row.with_key { top_heading } %>
+ <%= row.with_value do %>
+ <%= potential_placements_text %>
+ <%= govuk_link_to(t("view_list_of_school_placements"), placements_url) %>
+ Locations can change and are not guaranteed
+ <% end %>
+ <% end %>
+ <%= summary_list.with_row do |row| %>
+ <%= row.with_key { bottom_heading } %>
+ <%= row.with_value do %>
+ <%= potential_study_sites_text %>
+
+ <% end %>
+ <% end %>
+<% end %>
diff --git a/app/components/find/courses/training_locations/view.rb b/app/components/find/courses/training_locations/view.rb
new file mode 100644
index 0000000000..d8e997a36b
--- /dev/null
+++ b/app/components/find/courses/training_locations/view.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module Find
+ module Courses
+ module TrainingLocations
+ class View < ViewComponent::Base
+ include PublishHelper
+ include PreviewHelper
+
+ attr_reader :course, :preview
+
+ def initialize(course:, preview: false)
+ @course = course
+ @preview = preview
+ super
+ end
+
+ def placements_url
+ if preview
+ placements_publish_provider_recruitment_cycle_course_path(
+ course.provider_code,
+ course.recruitment_cycle_year,
+ course.course_code
+ )
+ else
+ find_placements_path(course.provider_code, course.course_code)
+ end
+ end
+
+ def potential_placements_text
+ if course.fee_based?
+ pluralize(course.sites.size, 'potential placement location')
+ else
+ pluralize(course.sites.size, 'potential employing school')
+ end
+ end
+
+ def potential_study_sites_text
+ return 'Not listed yet' if course.study_sites.none?
+
+ if course.study_sites.one?
+ '1 study site'
+ else
+ "#{course.study_sites.size} potential study sites"
+ end
+ end
+
+ def top_heading
+ course.fee_based? ? 'Placement schools' : 'Employing schools'
+ end
+
+ def bottom_heading
+ 'Where you will study'
+ end
+ end
+ end
+ end
+end
diff --git a/config/locales/en/components/find/training_locations.yml b/config/locales/en/components/find/training_locations.yml
new file mode 100644
index 0000000000..499ac3aba1
--- /dev/null
+++ b/config/locales/en/components/find/training_locations.yml
@@ -0,0 +1,2 @@
+en:
+ view_list_of_school_placements: View list of school placements
\ No newline at end of file
diff --git a/config/locales/find.yml b/config/locales/find.yml
index db8dbc2bce..cf7fceca23 100644
--- a/config/locales/find.yml
+++ b/config/locales/find.yml
@@ -108,7 +108,7 @@ en:
contents_component:
view:
course_details: Course details
- how_school_placements_work: How school placements work
+ where_you_will_train: Where you will train
training_with_disabilities: Training with disabilities
fees_and_financial_support: Fees and financial support
salary: Salary
@@ -176,8 +176,7 @@ en:
contact: Contact %{provider_name}
about_schools_component:
view:
- heading: How school placements work
- view_list_of_school_placements: View list of school placements
+ heading: Where you will train
work_with_schools: We work with the following schools to provide your school placements.
placements:
heading: School placements at %{provider_name}
diff --git a/spec/components/find/courses/about_schools_component/view_preview.rb b/spec/components/find/courses/about_schools_component/view_preview.rb
index 06a95a3aaf..b085268b2c 100644
--- a/spec/components/find/courses/about_schools_component/view_preview.rb
+++ b/spec/components/find/courses/about_schools_component/view_preview.rb
@@ -4,11 +4,21 @@ module Find
module Courses
module AboutSchoolsComponent
class ViewPreview < ViewComponent::Preview
- def hei_minimum
+ def hei_minimum_without_salary
course = Course.new(course_code: 'FIND',
provider: Provider.new(provider_code: 'DFE', recruitment_cycle: RecruitmentCycle.current),
program_type: 'higher_education_programme',
- level: 'further_education').decorate
+ level: 'further_education',
+ funding: 'fee').decorate
+ render Find::Courses::AboutSchoolsComponent::View.new(course)
+ end
+
+ def hei_minimum_with_salary
+ course = Course.new(course_code: 'FIND',
+ provider: Provider.new(provider_code: 'DFE', recruitment_cycle: RecruitmentCycle.current),
+ program_type: 'higher_education_programme',
+ level: 'further_education',
+ funding: 'salary').decorate
render Find::Courses::AboutSchoolsComponent::View.new(course)
end
@@ -38,6 +48,7 @@ def mock_scitt_course
placements_heading: 'How placements work',
program_type: 'scitt_programme',
study_sites: [fake_study_site],
+ sites: [fake_study_site],
site_statuses: [SiteStatus.new(id: 2_245_455, course_id: 12_983_436, publish: 'published', site_id: 11_228_658, status: 'running', vac_status: 'part_time_vacancies'), SiteStatus.new(id: 22_454_556, course_id: 12_983_436, publish: 'published', site_id: 11_228_659, status: 'running', vac_status: 'part_time_vacancies')])
end
@@ -45,10 +56,12 @@ def mock_hei_course
FakeCourse.new(provider: Provider.new(provider_code: 'DFE'),
provider_code: '1BJ',
course_code: 'ZZZZ',
+ is_fee_based: true,
published_how_school_placements_work: 'you will go on placement and learn more',
placements_heading: 'How placements work',
program_type: 'higher_education_programme',
study_sites: [fake_study_site],
+ sites: [fake_study_site],
site_statuses: [SiteStatus.new(id: 2_245_455, course_id: 12_983_436, publish: 'published', site_id: 11_228_658, status: 'running', vac_status: 'part_time_vacancies'), SiteStatus.new(id: 22_454_556, course_id: 12_983_436, publish: 'published', site_id: 11_228_659, status: 'running', vac_status: 'part_time_vacancies')])
end
@@ -58,7 +71,7 @@ def fake_study_site
class FakeCourse
include ActiveModel::Model
- attr_accessor(:provider, :provider_code, :course_code, :published_how_school_placements_work, :placements_heading, :program_type, :study_sites, :site_statuses)
+ attr_accessor(:provider, :provider_code, :course_code, :published_how_school_placements_work, :placements_heading, :program_type, :study_sites, :site_statuses, :is_fee_based, :sites)
def higher_education_programme?
true
@@ -67,6 +80,10 @@ def higher_education_programme?
def preview_site_statuses
site_statuses.sort_by { |status| status.site.location_name }
end
+
+ def fee_based?
+ is_fee_based
+ end
end
end
end
diff --git a/spec/components/find/courses/about_schools_component/view_spec.rb b/spec/components/find/courses/about_schools_component/view_spec.rb
index ba2d69fd34..6371ac8a39 100644
--- a/spec/components/find/courses/about_schools_component/view_spec.rb
+++ b/spec/components/find/courses/about_schools_component/view_spec.rb
@@ -15,7 +15,7 @@
result = render_inline(described_class.new(course))
- expect(result.text).to include('How school placements work')
+ expect(result.text).to include('Where you will train')
end
end
end
@@ -31,31 +31,36 @@
end
end
- context 'course with site' do
- it 'renders the school placement heading' do
- provider = build(:provider)
+ context 'salaried course' do
+ it 'renders the correct content' do
course = build(:course,
- provider:,
- site_statuses: [
- build(:site_status, site: build(:site))
- ]).decorate
+ funding: 'salary').decorate
result = render_inline(described_class.new(course))
- expect(result.text).to include(course.placements_heading)
+ expect(result.text).to include('You will spend most of your time in one school which will employ you. You will also spend some time in another school and at a location where you will study.')
end
end
- context 'course with no site' do
- it 'does not render the school placement heading' do
- provider = build(:provider)
+ context 'apprenticeship course' do
+ it 'renders the correct content' do
course = build(:course,
- site_statuses: [],
- provider:).decorate
+ funding: 'apprenticeship').decorate
result = render_inline(described_class.new(course))
- expect(result.text).not_to include(course.placements_heading)
+ expect(result.text).to include('You will spend most of your time in one school which will employ you. You will also spend some time in another school and at a location where you will study.')
+ end
+ end
+
+ context 'fee paying course' do
+ it 'renders the correct content' do
+ course = build(:course,
+ funding: 'fee').decorate
+
+ result = render_inline(described_class.new(course))
+
+ expect(result.text).to include('You’ll be placed in schools for most of your course to get classroom experience. You will also spend time at a location where you will study.')
end
end
@@ -174,52 +179,4 @@
end
end
end
-
- describe '#placements_url' do
- context 'when course is published' do
- it 'returns the find url' do
- provider = build(:provider)
- course = build(
- :course,
- :published,
- provider:,
- site_statuses: [
- build(:site_status, :findable, site: build(:site))
- ]
- ).decorate
-
- result = render_inline(described_class.new(course))
-
- expect(result).to have_link(
- 'View list of school placements',
- href: find_placements_path(course.provider_code, course.course_code)
- )
- end
- end
-
- context 'when course is not published' do
- it 'returns the publish url' do
- provider = create(:provider)
- course = create(
- :course,
- provider:,
- site_statuses: [
- create(:site_status, :findable, site: create(:site))
- ]
- ).decorate
-
- result = render_inline(described_class.new(course, preview: true))
- url = placements_publish_provider_recruitment_cycle_course_path(
- course.provider_code,
- course.recruitment_cycle_year,
- course.course_code
- )
-
- expect(result).to have_link(
- 'View list of school placements',
- href: url
- )
- end
- end
- end
end
diff --git a/spec/components/find/courses/contents_component/view_spec.rb b/spec/components/find/courses/contents_component/view_spec.rb
index 244ee55baf..4deef9e9ba 100644
--- a/spec/components/find/courses/contents_component/view_spec.rb
+++ b/spec/components/find/courses/contents_component/view_spec.rb
@@ -15,7 +15,7 @@
result = render_inline(described_class.new(course))
- expect(result.text).to include('How school placements work')
+ expect(result.text).to include('Where you will train')
end
end
@@ -31,7 +31,7 @@
result = render_inline(described_class.new(course))
- expect(result.text).to include('How school placements work')
+ expect(result.text).to include('Where you will train')
end
end
@@ -46,7 +46,7 @@
result = render_inline(described_class.new(course))
- expect(result.text).not_to include('How school placements work')
+ expect(result.text).not_to include('Where you will train')
end
end
diff --git a/spec/components/find/courses/training_locations/view_preview.rb b/spec/components/find/courses/training_locations/view_preview.rb
new file mode 100644
index 0000000000..55184591db
--- /dev/null
+++ b/spec/components/find/courses/training_locations/view_preview.rb
@@ -0,0 +1,79 @@
+# frozen_string_literal: true
+
+module Find
+ module Courses
+ module TrainingLocations
+ class ViewPreview < ViewComponent::Preview
+ def no_study_sites_and_one_placement_fee_paying
+ course = Course.new(course_code: 'FIND',
+ sites: [Site.new],
+ funding: 'fee',
+ provider: Provider.new(provider_code: 'DFE', recruitment_cycle: RecruitmentCycle.current)).decorate
+ render Find::Courses::TrainingLocations::View.new(course:)
+ end
+
+ def one_study_site_and_one_placement_fee_paying
+ course = Course.new(course_code: 'FIND',
+ sites: [Site.new],
+ funding: 'fee',
+ study_sites: [Site.new],
+ provider: Provider.new(provider_code: 'DFE', recruitment_cycle: RecruitmentCycle.current)).decorate
+ render Find::Courses::TrainingLocations::View.new(course:)
+ end
+
+ def two_study_sites_and_one_placement_fee_paying
+ course = Course.new(course_code: 'FIND',
+ sites: [Site.new],
+ funding: 'fee',
+ study_sites: [Site.new, Site.new],
+ provider: Provider.new(provider_code: 'DFE', recruitment_cycle: RecruitmentCycle.current)).decorate
+ render Find::Courses::TrainingLocations::View.new(course:)
+ end
+
+ def two_study_sites_and_two_placements_fee_paying
+ course = Course.new(course_code: 'FIND',
+ sites: [Site.new, Site.new],
+ funding: 'fee',
+ study_sites: [Site.new, Site.new],
+ provider: Provider.new(provider_code: 'DFE', recruitment_cycle: RecruitmentCycle.current)).decorate
+ render Find::Courses::TrainingLocations::View.new(course:)
+ end
+
+ def no_study_sites_and_one_placement_salaried
+ course = Course.new(course_code: 'FIND',
+ funding: 'salary',
+ sites: [Site.new],
+ provider: Provider.new(provider_code: 'DFE', recruitment_cycle: RecruitmentCycle.current)).decorate
+ render Find::Courses::TrainingLocations::View.new(course:)
+ end
+
+ def one_study_site_and_one_placement_salaried
+ course = Course.new(course_code: 'FIND',
+ sites: [Site.new],
+ funding: 'salary',
+ study_sites: [Site.new],
+ provider: Provider.new(provider_code: 'DFE', recruitment_cycle: RecruitmentCycle.current)).decorate
+ render Find::Courses::TrainingLocations::View.new(course:)
+ end
+
+ def two_study_sites_and_one_placement_salaried
+ course = Course.new(course_code: 'FIND',
+ sites: [Site.new],
+ funding: 'salary',
+ study_sites: [Site.new, Site.new],
+ provider: Provider.new(provider_code: 'DFE', recruitment_cycle: RecruitmentCycle.current)).decorate
+ render Find::Courses::TrainingLocations::View.new(course:)
+ end
+
+ def two_study_sites_and_two_placements_salaried
+ course = Course.new(course_code: 'FIND',
+ sites: [Site.new, Site.new],
+ funding: 'salary',
+ study_sites: [Site.new, Site.new],
+ provider: Provider.new(provider_code: 'DFE', recruitment_cycle: RecruitmentCycle.current)).decorate
+ render Find::Courses::TrainingLocations::View.new(course:)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/components/find/courses/training_locations/view_spec.rb b/spec/components/find/courses/training_locations/view_spec.rb
new file mode 100644
index 0000000000..77680c1ef8
--- /dev/null
+++ b/spec/components/find/courses/training_locations/view_spec.rb
@@ -0,0 +1,139 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe Find::Courses::TrainingLocations::View, type: :component do
+ include Rails.application.routes.url_helpers
+
+ subject { render_inline(described_class.new(course:, preview:)) }
+
+ let(:preview) { false }
+ let(:component) { described_class.new(course:, preview:) }
+
+ describe '#render' do
+ let(:study_site) { course.study_sites.first.decorate }
+
+ context 'for fee-paying courses' do
+ let(:course) { create(:course, :with_full_time_sites, funding: 'fee', study_sites: [build(:site, :study_site)]) }
+
+ it "renders the 'Placement schools' heading" do
+ expect(subject).to have_css('.govuk-summary-list__key', text: 'Placement schools')
+ end
+
+ it 'renders the link to school placements' do
+ expect(subject).to have_link('View list of school placements')
+ end
+
+ it 'renders the hint about placements not being guaranteed' do
+ expect(subject).to have_css('.govuk-hint', text: 'Locations can change and are not guaranteed')
+ end
+ end
+
+ context 'for salaried courses' do
+ let(:course) { create(:course, :with_full_time_sites, funding: 'salary', study_sites: [build(:site, :study_site)]) }
+
+ it "renders the 'Employing schools' heading" do
+ expect(subject).to have_css('.govuk-summary-list__key', text: 'Employing schools')
+ end
+
+ it 'renders the link to employing schools' do
+ expect(subject).to have_link('View list of school placements')
+ end
+
+ it 'renders the hint about placements not being guaranteed' do
+ expect(subject).to have_css('.govuk-hint', text: 'Locations can change and are not guaranteed')
+ end
+
+ it "renders 'Where you will study' for study sites" do
+ expect(subject).to have_css('.govuk-summary-list__key', text: 'Where you will study')
+ end
+
+ it 'renders the study site names and addresses' do
+ expect(subject).to have_css('.govuk-hint strong', text: study_site.location_name)
+ expect(subject).to have_css('.govuk-hint', text: study_site.full_address)
+ end
+ end
+ end
+
+ describe '#placements_url' do
+ let(:course) { create(:course) }
+
+ context 'when preview is true' do
+ let(:preview) { true }
+
+ it 'renders a link to the publish path' do
+ expect(subject).to have_link(
+ 'View list of school placements',
+ href: placements_publish_provider_recruitment_cycle_course_path(
+ course.provider_code,
+ course.recruitment_cycle_year,
+ course.course_code
+ )
+ )
+ end
+ end
+
+ context 'when preview is false' do
+ let(:preview) { false }
+
+ it 'renders a link to the find path' do
+ expect(subject).to have_link('View list of school placements',
+ href: find_placements_path(course.provider_code, course.course_code))
+ end
+ end
+ end
+
+ describe '#potential_placements_text' do
+ context 'for fee-paying courses' do
+ let(:course) { create(:course, :with_full_time_sites, funding: 'fee', study_sites: [build(:site, :study_site)]) }
+
+ it 'returns the correct text for one potential placement location' do
+ expect(component.potential_placements_text).to eq('1 potential placement location')
+ end
+ end
+
+ context 'for salaried courses' do
+ let(:course) { create(:course, :with_full_time_sites, funding: 'salary', study_sites: [build(:site, :study_site)]) }
+
+ it 'returns the correct text for one potential employing school' do
+ expect(component.potential_placements_text).to eq('1 potential employing school')
+ end
+ end
+
+ context 'with multiple placements' do
+ let(:course) { create(:course, funding: 'fee', sites: [create(:site), create(:site), create(:site)]) }
+
+ it 'returns the correct text for multiple placements' do
+ expect(component.potential_placements_text).to eq('3 potential placement locations')
+ end
+ end
+ end
+
+ describe '#potential_study_sites_text' do
+ let(:course) { create(:course, :with_full_time_sites) }
+
+ context 'when there is one study site' do
+ let(:course) { create(:course, :with_full_time_sites, study_sites: [build(:site, :study_site)]) }
+
+ it 'returns the correct text for one study site' do
+ expect(component.potential_study_sites_text).to eq('1 study site')
+ end
+ end
+
+ context 'when there are multiple study sites' do
+ let(:course) { create(:course, :with_full_time_sites, study_sites: [build(:site, :study_site), build(:site, :study_site)]) }
+
+ it 'returns the correct text for multiple study sites' do
+ expect(component.potential_study_sites_text).to eq('2 potential study sites')
+ end
+ end
+
+ context 'when there are no study sites' do
+ let(:course) { create(:course, :with_full_time_sites, study_sites: []) }
+
+ it 'returns the correct text for no study sites' do
+ expect(component.potential_study_sites_text).to eq('Not listed yet')
+ end
+ end
+ end
+end