Skip to content

Commit 26e694c

Browse files
Merge pull request #2374 from NCCE/3000-strapi-component---course-cards-to-redirect
Adding replaced_by logic to course cards
2 parents de25948 + 0483a85 commit 26e694c

File tree

9 files changed

+159
-42
lines changed

9 files changed

+159
-42
lines changed

app/components/cms/card_wrapper_component/card_wrapper_component.html.erb

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
<% end %>
99
<div class="cms-card-wrapper__grid" style="<%= cards_per_row %>">
1010
<% @cards_block.each do |card| %>
11-
<div class="cms-card-wrapper__card">
12-
<%= render card.render %>
13-
</div>
11+
<% if card.render.render? %>
12+
<div class="cms-card-wrapper__card">
13+
<%= render card.render %>
14+
</div>
15+
<% end %>
1416
<% end %>
1517
</div>
1618
<% end %>

app/components/cms/course_card_component.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ class Cms::CourseCardComponent < ViewComponent::Base
66
to: :helpers
77

88
def initialize(title:, banner_text:, course:, description:, image:)
9-
@title = title
109
@banner_text = banner_text
1110
@course = course
11+
@title = title.presence || @course&.title
1212
@description = description
1313
@image = image
1414
end

app/components/cms/course_card_component/course_card_component.html.erb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111

1212
<%= link_to @title, course_path(id: @course.activity_code, name: @course.title.parameterize), class: 'govuk-!-font-weight-bold govuk-body ncce-link' %>
1313
<div class="courses-cms-card__details">
14-
<p class="govuk-body">
15-
<%= render @description.render %>
16-
</p>
14+
<div class="courses-cms-card__details-content">
15+
<%= render @description.render if @description %>
16+
</div>
1717
<div class="courses-cms-card__icons">
1818
<div>
1919
<span class="govuk-body-s <%= course_meta_icon_class(@course) %> courses-cms-card__type">

app/components/cms/course_card_component/course_card_component.scss

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11

22
.courses-cms-card {
3+
display: flex;
4+
flex-direction: column;
5+
flex: 1 1 auto;
36

47
&__image-wrapper {
58
margin-bottom: 12px;
@@ -36,11 +39,18 @@
3639
display: flex;
3740
flex-direction: column;
3841
justify-content: space-between;
42+
43+
flex: 1 1 auto;
44+
45+
&-content {
46+
flex: 1 1 auto;
47+
}
3948
}
4049

4150
&__icons {
4251
height: 22px;
4352
padding: 10px;
53+
margin-top: 1rem;
4454
display: flex;
4555
flex-direction: row;
4656
justify-content: space-between;

app/services/cms/dynamic_components/course_card.rb

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,24 @@ def initialize(title:, banner_text:, course_code:, description:, image:)
88
@banner_text = banner_text
99
@description = description
1010
@image = image
11-
@course = begin
12-
Achiever::Course::Template.find_by_activity_code(course_code)
13-
rescue ActiveRecord::RecordNotFound
14-
nil
11+
12+
activity = Activity.find_by(stem_activity_code: course_code)
13+
@course = if activity
14+
if activity.replaced_by
15+
Sentry.capture_message("Course card has been found with a now replaced course (#{course_code} -> #{activity.replaced_by.stem_activity_code}) - get comms to update Strapi to new course instance")
16+
get_achiever_course(activity.replaced_by)
17+
elsif activity
18+
get_achiever_course(activity)
19+
end
1520
end
1621
end
1722

23+
def get_achiever_course(activity)
24+
Achiever::Course::Template.find_by_activity_code(activity.stem_activity_code)
25+
rescue ActiveRecord::RecordNotFound
26+
nil
27+
end
28+
1829
def render
1930
Cms::CourseCardComponent.new(title:, banner_text:, course:, description:, image:)
2031
end

app/views/achievement_mailer/completed_course.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<p class='govuk-body'>Hello <%= @user.first_name %>,</p>
33

44
<p class='govuk-body'>Thanks for engaging with the KS3 and GCSE Computer Science subject knowledge certificate. You're making great progress towards achieving your subject knowledge certificate.</p>
5-
<p class='govuk-body'>Once you have completed your next course, you will have reached ten hours of CPD and become <b>eligible to take the test and achieve your qualification.</b></p>
5+
<p class='govuk-body'>Once you have completed your next course, you will have reached ten hours of CPD and become <strong>eligible to take the test and achieve your qualification.</strong></p>
66
<h3 class="govuk-heading-s">Next steps</h3>
77
<p class='govuk-body'>Choose from any of our computer science subject knowledge courses.</p>
88
<%= link_to 'Browse all courses', courses_url(certificate: 'subject-knowledge', emailTrigger: 'CSA4'), class: 'govuk-button button' %>

config/routes.rb

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@
22
Healthcheck.routes(self)
33
root to: "cms#home", action: :home
44

5-
# April 2025 Route Redirect
6-
7-
get "/computing-clusters", to: redirect("/")
8-
95
resources :achievements, only: %i[create destroy update] do
106
collection do
117
post :submit
@@ -151,6 +147,7 @@
151147

152148
# April 2025 Redirects
153149

150+
get "/computing-clusters", to: redirect("/")
154151
get "/hubs", to: redirect("/")
155152
get "/bursary", to: redirect("/")
156153
get "/funding", to: redirect("/")

spec/components/cms/course_card_component_spec.rb

Lines changed: 69 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,85 @@
33
require "rails_helper"
44

55
RSpec.describe Cms::CourseCardComponent, type: :component do
6+
let(:course) { Achiever::Course::Template.all.first }
67
before do
78
stub_course_templates
89
stub_duration_units
9-
@course = Achiever::Course::Template.all.first
10-
render_inline(described_class.new(
11-
title: "Learn how to teach computing",
12-
banner_text: "Banner text",
13-
course: @course,
14-
description: Cms::Mocks::RichBlocks.as_model,
15-
image: Cms::Mocks::Image.as_model
16-
))
1710
end
1811

19-
it "renders the banner text and makes it uppercase" do
20-
expect(page).to have_css(".courses-cms-card__banner", text: "BANNER TEXT")
12+
context "given title" do
13+
before do
14+
render_inline(described_class.new(
15+
title: "Learn how to teach computing",
16+
banner_text: "Banner text",
17+
course: course,
18+
description: Cms::Mocks::RichBlocks.as_model,
19+
image: Cms::Mocks::Image.as_model
20+
))
21+
end
22+
23+
it "renders the banner text and makes it uppercase" do
24+
expect(page).to have_css(".courses-cms-card__banner", text: "BANNER TEXT")
25+
end
26+
27+
it "renders title as link" do
28+
expect(page).to have_link("Learn how to teach computing", href: "/courses/#{course.activity_code}/#{course.title.parameterize}")
29+
end
30+
31+
it "renders description" do
32+
expect(page).to have_css(".cms-rich-text-block-component")
33+
end
34+
35+
it "renders image" do
36+
expect(page).to have_css(".cms-image")
37+
end
2138
end
2239

23-
it "renders title as link" do
24-
expect(page).to have_link("Learn how to teach computing", href: "/courses/#{@course.activity_code}/#{@course.title.parameterize}")
40+
context "without title" do
41+
before do
42+
render_inline(described_class.new(
43+
title: nil,
44+
banner_text: "Banner text",
45+
course:,
46+
description: Cms::Mocks::RichBlocks.as_model,
47+
image: Cms::Mocks::Image.as_model
48+
))
49+
end
50+
51+
it "renders title as link" do
52+
expect(page).to have_link(course.title, href: "/courses/#{course.activity_code}/#{course.title.parameterize}")
53+
end
2554
end
2655

27-
it "renders description" do
28-
expect(page).to have_css(".cms-rich-text-block-component")
56+
context "when course is nil" do
57+
before do
58+
render_inline(described_class.new(
59+
title: nil,
60+
banner_text: "Banner text",
61+
course: nil,
62+
description: Cms::Mocks::RichBlocks.as_model,
63+
image: Cms::Mocks::Image.as_model
64+
))
65+
end
66+
67+
it "doesnt render" do
68+
expect(page).not_to have_css(".courses-cms-card")
69+
end
2970
end
3071

31-
it "renders image" do
32-
expect(page).to have_css(".cms-image")
72+
context "when description is nil" do
73+
before do
74+
render_inline(described_class.new(
75+
title: nil,
76+
banner_text: "Banner text",
77+
course:,
78+
description: nil,
79+
image: Cms::Mocks::Image.as_model
80+
))
81+
end
82+
83+
it "does render" do
84+
expect(page).to have_css(".courses-cms-card")
85+
end
3386
end
3487
end
Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,83 @@
11
require "rails_helper"
22

33
RSpec.describe Cms::DynamicComponents::CourseCard do
4+
let!(:activity) { Activity.find_by(stem_activity_code: "CP228") || create(:activity, stem_activity_code: "CP228") }
5+
let!(:new_activity) { Activity.find_by(stem_activity_code: "CP229") || create(:activity, stem_activity_code: "CP229") }
6+
let!(:replaced_activity) { create(:activity, stem_activity_code: "RP228", replaced_by: new_activity) }
47
let(:valid_course_card) { Cms::Mocks::DynamicComponents::CourseCard.generate_data(course_code: "CP228") }
8+
let(:replaced_course_card) { Cms::Mocks::DynamicComponents::CourseCard.generate_data(course_code: "RP228") }
59
let(:invalid_course_card) { Cms::Mocks::DynamicComponents::CourseCard.generate_data(course_code: "NV228") }
610

711
before do
812
stub_course_templates
913
stub_duration_units
14+
allow(Sentry).to receive(:capture_message)
1015
end
1116

1217
context "with valid activity" do
13-
before do
14-
@card_section = Cms::Providers::Strapi::Factories::ComponentFactory.process_component(Cms::Mocks::CourseCardSection.generate_raw_data(cards: [valid_course_card]))
15-
end
18+
let(:card_section) { Cms::Providers::Strapi::Factories::ComponentFactory.process_component(Cms::Mocks::CourseCardSection.generate_raw_data(cards: [valid_course_card])) }
19+
let(:first_block) { card_section.cards_block.first }
1620

1721
it "should render as Cms::CardWrapperComponent" do
18-
expect(@card_section.render).to be_a(Cms::CardWrapperComponent)
22+
expect(card_section.render).to be_a(Cms::CardWrapperComponent)
1923
end
2024

2125
it "should render cards as Cms::DynamicsComponents::CourseCard" do
22-
expect(@card_section.cards_block.first.render).to be_a(Cms::CourseCardComponent)
26+
expect(first_block.render).to be_a(Cms::CourseCardComponent)
2327
end
2428

2529
it "should return true for valid code" do
26-
expect(@card_section.cards_block.first.render.render?).to be true
30+
expect(first_block.render.render?).to be true
31+
end
32+
33+
it "should have correct course instance" do
34+
expect(first_block.course.activity_code).to eq("CP228")
35+
end
36+
37+
it "should not send sentry notification" do
38+
expect(Sentry).not_to have_received(:capture_message)
2739
end
2840
end
2941

3042
context "with invalid activity" do
31-
before do
32-
@card_section = Cms::Providers::Strapi::Factories::ComponentFactory.process_component(Cms::Mocks::CourseCardSection.generate_raw_data(cards: [invalid_course_card]))
33-
end
43+
let(:card_section) { Cms::Providers::Strapi::Factories::ComponentFactory.process_component(Cms::Mocks::CourseCardSection.generate_raw_data(cards: [invalid_course_card])) }
44+
let(:first_block) { card_section.cards_block.first }
3445

3546
it "should return false for invalid code" do
36-
expect(@card_section.cards_block.first.render.render?).to be false
47+
expect(first_block.render.render?).to be false
48+
end
49+
50+
it "should have no course instance" do
51+
expect(first_block.course).to be_nil
52+
end
53+
54+
it "should not send sentry notification" do
55+
expect(Sentry).not_to have_received(:capture_message)
56+
end
57+
end
58+
59+
context "with replaced activity" do
60+
let!(:card_section) { Cms::Providers::Strapi::Factories::ComponentFactory.process_component(Cms::Mocks::CourseCardSection.generate_raw_data(cards: [replaced_course_card])) }
61+
let(:first_block) { card_section.cards_block.first }
62+
63+
it "should render as Cms::CardWrapperComponent" do
64+
expect(card_section.render).to be_a(Cms::CardWrapperComponent)
65+
end
66+
67+
it "should render cards as Cms::DynamicsComponents::CourseCard" do
68+
expect(first_block.render).to be_a(Cms::CourseCardComponent)
69+
end
70+
71+
it "should return true for valid code" do
72+
expect(first_block.render.render?).to be true
73+
end
74+
75+
it "should have correct course instance" do
76+
expect(first_block.course.activity_code).to eq("CP229")
77+
end
78+
79+
it "should send sentry notification" do
80+
expect(Sentry).to have_received(:capture_message).once.with("Course card has been found with a now replaced course (RP228 -> CP229) - get comms to update Strapi to new course instance")
3781
end
3882
end
3983
end

0 commit comments

Comments
 (0)