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 fd856564eb..e724951a5a 100644 --- a/app/components/find/courses/about_schools_component/view.html.erb +++ b/app/components/find/courses/about_schools_component/view.html.erb @@ -49,19 +49,11 @@ <%= course.placements_heading %> +

<%= t(".work_with_schools") %>

+

- We work with the following schools to provide your school placements. + <%= govuk_link_to(t(".view_list_of_school_placements"), placements_url) %>

- - <% end %> diff --git a/app/components/find/courses/about_schools_component/view.rb b/app/components/find/courses/about_schools_component/view.rb index bb6c95512d..0eb86d659b 100644 --- a/app/components/find/courses/about_schools_component/view.rb +++ b/app/components/find/courses/about_schools_component/view.rb @@ -38,6 +38,21 @@ def show_scitt_guidance? course_information_config.show_placement_guidance?(:program_type) end + def placements_url + if course.has_unpublished_changes? || (course.is_published? && course.is_running?) + URI.join( + Settings.search_ui.base_url, + find_placements_path(course.provider_code, course.course_code) + ).to_s + else + placements_publish_provider_recruitment_cycle_course_path( + course.provider_code, + course.recruitment_cycle_year, + course.course_code + ) + end + end + private def course_information_config diff --git a/app/controllers/find/placements_controller.rb b/app/controllers/find/placements_controller.rb new file mode 100644 index 0000000000..6ef9176e74 --- /dev/null +++ b/app/controllers/find/placements_controller.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Find + class PlacementsController < ApplicationController + before_action -> { render_not_found if provider.nil? } + + def index + @course = provider.courses.includes( + :enrichments, + subjects: [:financial_incentive], + site_statuses: [:site] + ).find_by!(course_code: params[:course_code]&.upcase).decorate + + render_not_found unless @course.is_published? + end + end +end diff --git a/app/controllers/publish/courses/school_placements_controller.rb b/app/controllers/publish/courses/school_placements_controller.rb index dc1e291ba4..61af4c6a15 100644 --- a/app/controllers/publish/courses/school_placements_controller.rb +++ b/app/controllers/publish/courses/school_placements_controller.rb @@ -8,6 +8,10 @@ class SchoolPlacementsController < PublishController before_action :authorise_with_pundit + def index + @course = course + end + def edit @course_school_placements_form = CourseSchoolPlacementsForm.new(course_enrichment) @copied_fields = copy_content_check(::Courses::Copy::SCHOOL_PLACEMENTS_FIELDS) diff --git a/app/models/course.rb b/app/models/course.rb index 96fc7cbcac..ff3a051777 100644 --- a/app/models/course.rb +++ b/app/models/course.rb @@ -100,6 +100,7 @@ class Course < ApplicationRecord belongs_to :provider delegate :tda_active?, to: :provider, allow_nil: true + delegate :provider_name, :provider_code, to: :provider, allow_nil: true belongs_to :accrediting_provider, ->(c) { where(recruitment_cycle: c.recruitment_cycle) }, diff --git a/app/views/find/placements/index.html.erb b/app/views/find/placements/index.html.erb new file mode 100644 index 0000000000..41d7ef2642 --- /dev/null +++ b/app/views/find/placements/index.html.erb @@ -0,0 +1,21 @@ +<%= content_for :page_title do %> + <%= t( + "find.courses.placements.heading", + provider_name: @course.provider_name + ) %> +<% end %> +<% content_for :before_content do %> + <%= govuk_back_link( + href: search_ui_course_page_url( + provider_code: @course.provider_code, + course_code: @course.course_code + ), + text: t( + "find.courses.placements.back", + course_name: @course.name, + course_code: @course.course_code + ) + ) %> +<% end %> + +<%= render partial: "shared/courses/placements", locals: { course: @course } %> diff --git a/app/views/publish/courses/school_placements/index.html.erb b/app/views/publish/courses/school_placements/index.html.erb new file mode 100644 index 0000000000..0cc55d5b8f --- /dev/null +++ b/app/views/publish/courses/school_placements/index.html.erb @@ -0,0 +1,22 @@ +<%= content_for :page_title do %> + <%= t( + "publish.providers.courses.placements.heading", + provider_name: @course.provider_name + ) %> +<% end %> +<% content_for :before_content do %> + <%= govuk_back_link( + href: preview_publish_provider_recruitment_cycle_course_path( + @course.provider_code, + @course.recruitment_cycle_year, + @course.course_code + ), + text: t( + "publish.providers.courses.placements.back", + course_name: @course.name, + course_code: @course.course_code + ) + ) %> +<% end %> + +<%= render partial: "shared/courses/placements", locals: { course: @course } %> diff --git a/app/views/shared/courses/_placements.html.erb b/app/views/shared/courses/_placements.html.erb new file mode 100644 index 0000000000..7e14fc8d87 --- /dev/null +++ b/app/views/shared/courses/_placements.html.erb @@ -0,0 +1,21 @@ +

+ <%= t(".heading", provider_name: course.provider_name) %> +

+ +<%= govuk_warning_text(text: t(".warning")) %> + +

+ <%= t(".will_place_you", provider_name: course.provider_name) %> +

+ +

<%= t(".schools_to_be_placed") %>

+ + diff --git a/config/locales/en.yml b/config/locales/en.yml index 7b9cfea4b2..cd19855052 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,4 +1,11 @@ en: + shared: + courses: + placements: + heading: School placements at %{provider_name} + warning: You can’t pick which schools you will be in. + will_place_you: '%{provider_name} will place you in different schools you can travel to during your training.' + schools_to_be_placed: 'The schools you could be placed in are:' markdown_formatting: summary_text: Help formatting your text title: How to format your text @@ -389,6 +396,9 @@ en: publish: providers: courses: + placements: + heading: School placements at %{provider_name} + back: Back to %{course_name} (%{course_code}) description_content: course_information_heading: Course information about_course_label: About this course diff --git a/config/locales/find.yml b/config/locales/find.yml index 779a6ce4ce..ab17efd41d 100644 --- a/config/locales/find.yml +++ b/config/locales/find.yml @@ -70,6 +70,13 @@ en: primary_title: Primary courses with subject specialisms secondary_title: Which secondary subjects do you want to teach? courses: + about_schools_component: + view: + view_list_of_school_placements: View list of school placements + work_with_schools: We work with the following schools to provide your school placements. + placements: + heading: School placements at %{provider_name} + back: Back to %{course_name} (%{course_code}) show: back_to_search: Back to search results scholarships: diff --git a/config/routes/find.rb b/config/routes/find.rb index a87780343e..42c9c1ddbf 100644 --- a/config/routes/find.rb +++ b/config/routes/find.rb @@ -13,6 +13,7 @@ get '/privacy', to: 'pages#privacy', as: :privacy get '/terms-conditions', to: 'pages#terms', as: :terms get '/course/:provider_code/:course_code', to: 'courses#show', as: 'course' + get '/course/:provider_code/:course_code/placements', to: 'placements#index', as: :placements get '/course/:provider_code/:course_code/apply', to: 'courses#apply', as: :apply get '/results', to: 'results#index', as: 'results' get '/location-suggestions', to: 'location_suggestions#index' diff --git a/config/routes/publish.rb b/config/routes/publish.rb index 53ca283ae8..258ce4b18d 100644 --- a/config/routes/publish.rb +++ b/config/routes/publish.rb @@ -179,6 +179,7 @@ patch '/interview-process', on: :member, to: 'courses/interview_process#update' get '/school-placements', on: :member, to: 'courses/school_placements#edit' patch '/school-placements', on: :member, to: 'courses/school_placements#update' + get '/placements', on: :member, to: 'courses/school_placements#index', as: :placements # This feature is deprecated and will be removed after the beginning of # 2025 recruitment cycle. 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 df88c5fa78..21712caf1e 100644 --- a/spec/components/find/courses/about_schools_component/view_spec.rb +++ b/spec/components/find/courses/about_schools_component/view_spec.rb @@ -3,6 +3,8 @@ require 'rails_helper' describe Find::Courses::AboutSchoolsComponent::View, type: :component do + include Rails.application.routes.url_helpers + context 'valid program_type' do it 'renders the component' do %w[higher_education_programme scitt_programme].each do |program_type| @@ -172,4 +174,56 @@ 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)) + url = URI.join( + Settings.search_ui.base_url, + find_placements_path(course.provider_code, course.course_code) + ).to_s + + expect(result).to have_link( + 'View list of school placements', + href: url + ) + 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)) + 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/controllers/find/placements_controller_spec.rb b/spec/controllers/find/placements_controller_spec.rb new file mode 100644 index 0000000000..9352925d65 --- /dev/null +++ b/spec/controllers/find/placements_controller_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'rails_helper' + +module Find + describe PlacementsController do + before do + Timecop.travel(Find::CycleTimetable.mid_cycle) + end + + describe '#placements' do + context 'when provider is not pressent' do + it 'renders the not found page' do + get :index, params: { + provider_code: 'ABC', + course_code: '123' + } + + expect(response).to render_template('errors/not_found') + end + end + + context 'when course is not published' do + it 'renders the not found page' do + provider = create(:provider) + course = create(:course, provider:) + + get :index, params: { + provider_code: provider.provider_code, + course_code: course.course_code + } + + expect(response).to render_template('errors/not_found') + end + end + end + end +end diff --git a/spec/features/find/search/viewing_a_course_spec.rb b/spec/features/find/search/viewing_a_course_spec.rb index 5e5db760b7..4456eebf16 100644 --- a/spec/features/find/search/viewing_a_course_spec.rb +++ b/spec/features/find/search/viewing_a_course_spec.rb @@ -68,6 +68,13 @@ end end + scenario 'user views school placements' do + given_there_is_a_findable_course + when_i_visit_the_course_page + when_i_click('View list of school placements') + then_i_should_be_on_the_school_placements_page + end + private def given_there_is_a_findable_course @@ -280,9 +287,7 @@ def then_i_should_see_the_course_information expect(find_course_show_page.school_placements).to have_no_content('Suspended site with vacancies') - @course.site_statuses.new_or_running.map(&:site).uniq.each do |site| - expect(find_course_show_page).to have_content(smart_quotes(site.decorate.full_address)) - end + expect(find_course_show_page).to have_link('View list of school placements') expect(find_course_show_page).to have_course_advice @@ -345,4 +350,14 @@ def accrediting_provider provider_name: 'Accrediting Provider 1' ) end + + def when_i_click(button) + click_on(button) + end + + def then_i_should_be_on_the_school_placements_page + @course.site_statuses.new_or_running.map(&:site).uniq.each do |site| + expect(find_course_show_page).to have_content(smart_quotes(site.decorate.full_address)) + end + end end diff --git a/spec/features/publish/viewing_a_course_preview_spec.rb b/spec/features/publish/viewing_a_course_preview_spec.rb index 67a2d05e63..d58344597e 100644 --- a/spec/features/publish/viewing_a_course_preview_spec.rb +++ b/spec/features/publish/viewing_a_course_preview_spec.rb @@ -127,6 +127,13 @@ end end + scenario 'user views school placements' do + given_i_am_authenticated(user: user_with_fee_based_course) + when_i_visit_the_publish_course_preview_page + when_i_click('View list of school placements') + then_i_should_be_on_the_school_placements_page + end + private def then_i_see_custom_address @@ -272,7 +279,7 @@ def then_i_see_the_course_preview_details ) expect(publish_course_preview_page).to have_study_sites_table - expect(publish_course_preview_page).to have_school_placements_table + expect(publish_course_preview_page).to have_link('View list of school placements') expect(publish_course_preview_page).to have_course_advice @@ -475,4 +482,12 @@ def and_i_do_not_see_financial_support expect(publish_course_preview_page).not_to have_scholarship_amount expect(publish_course_preview_page).not_to have_bursary_amount end + + def when_i_click(button) + click_on(button) + end + + def then_i_should_be_on_the_school_placements_page + expect(publish_course_preview_page).to have_school_placements_table + end end diff --git a/spec/models/course_spec.rb b/spec/models/course_spec.rb index 3f2dc6c9d8..830c89d259 100644 --- a/spec/models/course_spec.rb +++ b/spec/models/course_spec.rb @@ -22,6 +22,9 @@ its(:to_s) { is_expected.to eq("Biology (#{course.provider.provider_code}/3X9F) [#{course.recruitment_cycle}]") } its(:modular) { is_expected.to eq('') } + it { is_expected.to delegate_method(:provider_name).to(:provider).allow_nil } + it { is_expected.to delegate_method(:provider_code).to(:provider).allow_nil } + describe '#campaign_name' do it 'assigns the campaign' do course.engineers_teach_physics!