From f04687d1b98fa936b0bbafeb02684fce8cae150a Mon Sep 17 00:00:00 2001 From: Michael Squance <m.squance@stem.org.uk> Date: Wed, 4 Dec 2024 15:35:31 +0000 Subject: [PATCH 1/6] Creating new pending/complete state components --- app/components/programme_status_component.rb | 28 ++++++++++++++++ .../programme_status_component.html.erb | 18 ++++++++++ .../programme_status_component.scss | 18 ++++++++++ app/models/programmes/a_level.rb | 4 +++ app/models/programmes/cs_accelerator.rb | 4 +++ app/models/programmes/i_belong.rb | 4 +++ app/models/programmes/primary_certificate.rb | 4 +++ .../programmes/secondary_certificate.rb | 4 +++ app/services/cms/collections/programme.rb | 33 +++++++++++++++++++ app/services/cms/models/text_field.rb | 15 +++++++++ .../strapi/factories/model_factory.rb | 9 ++++- app/services/cms/resource.rb | 20 +++++++++++ .../images/icons/programme_completed_icon.svg | 6 ++++ db/schema.rb | 4 ++- ...split_horizontal_card_component_preview.rb | 4 +-- .../programme_status_component_preview.rb | 27 +++++++++++++++ 16 files changed, 198 insertions(+), 4 deletions(-) create mode 100644 app/components/programme_status_component.rb create mode 100644 app/components/programme_status_component/programme_status_component.html.erb create mode 100644 app/components/programme_status_component/programme_status_component.scss create mode 100644 app/services/cms/collections/programme.rb create mode 100644 app/services/cms/models/text_field.rb create mode 100644 app/webpacker/images/icons/programme_completed_icon.svg create mode 100644 previews/components/programme_status_component_preview.rb diff --git a/app/components/programme_status_component.rb b/app/components/programme_status_component.rb new file mode 100644 index 0000000000..e88a42dc78 --- /dev/null +++ b/app/components/programme_status_component.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +class ProgrammeStatusComponent < ViewComponent::Base + def initialize(user_programme_enrolment:) + @user_programme_enrolment = user_programme_enrolment + @cms_programme_model = Cms::Collections::Programme.get(@user_programme_enrolment.programme.slug) + end + + def render? + @user_programme_enrolment.in_state?(:pending) || @user_programme_enrolment.in_state?(:complete) + end + + def title + if @user_programme_enrolment.in_state?(:pending) + @cms_programme_model.status_pending_title.value + else + @cms_programme_model.status_completed_title.value + end + end + + def content + if @user_programme_enrolment.in_state?(:pending) + @cms_programme_model.status_pending_text + else + @cms_programme_model.status_completed_text + end + end +end diff --git a/app/components/programme_status_component/programme_status_component.html.erb b/app/components/programme_status_component/programme_status_component.html.erb new file mode 100644 index 0000000000..54265e902a --- /dev/null +++ b/app/components/programme_status_component/programme_status_component.html.erb @@ -0,0 +1,18 @@ + +<%= render GovGridRowComponent.new(additional_classes: "programme-status-wrapper", background_color: "white") do |row| %> + <%= row.with_column("two-thirds") do %> + <div class="programme-status-wrapper__title-row"> + <h2 class="govuk-heading-m"><%= title %></h2> + <%= image_pack_tag "media/images/icons/programme_completed_icon.svg" %> + </div> + <%= render content.render %> + <% end %> + <%= row.with_column("one-third") do %> + <% if @user_programme_enrolment.in_state?(:complete) %> + <div class="programme-status-wrapper__button-container"> + <%= link_to 'Download your certificate', @user_programme_enrolment.programme.certificate_path, + class: 'govuk-button button', role: 'button', draggable: 'false' %></p> + </div> + <% end %> + <% end %> +<% end %> \ No newline at end of file diff --git a/app/components/programme_status_component/programme_status_component.scss b/app/components/programme_status_component/programme_status_component.scss new file mode 100644 index 0000000000..8f419630f1 --- /dev/null +++ b/app/components/programme_status_component/programme_status_component.scss @@ -0,0 +1,18 @@ +.programme-status-wrapper { + + &__title-row { + display: flex; + flex-direction: row; + align-items: center; + margin-bottom: 15px; + gap: 20px; + + h2 { + margin-bottom: 0; + } + } + + &__button-container { + padding-top: 50px; + } +} \ No newline at end of file diff --git a/app/models/programmes/a_level.rb b/app/models/programmes/a_level.rb index f852f51a02..6e6c0e6ac2 100644 --- a/app/models/programmes/a_level.rb +++ b/app/models/programmes/a_level.rb @@ -42,5 +42,9 @@ def achievement_type def enrolment_confirmation_required? false end + + def certificate_path + certificate_a_level_certificate_path + end end end diff --git a/app/models/programmes/cs_accelerator.rb b/app/models/programmes/cs_accelerator.rb index 61cd957c47..844c70439a 100644 --- a/app/models/programmes/cs_accelerator.rb +++ b/app/models/programmes/cs_accelerator.rb @@ -135,5 +135,9 @@ def achievement_type def enrolment_confirmation_required? false end + + def certificate_path + certificate_cs_accelerator_certificate_path + end end end diff --git a/app/models/programmes/i_belong.rb b/app/models/programmes/i_belong.rb index 39c06e8167..51ac6edaed 100644 --- a/app/models/programmes/i_belong.rb +++ b/app/models/programmes/i_belong.rb @@ -58,5 +58,9 @@ def achievement_type def enrolment_confirmation_required? false end + + def certificate_path + certificate_i_belong_certificate_path + end end end diff --git a/app/models/programmes/primary_certificate.rb b/app/models/programmes/primary_certificate.rb index f9ed6d764a..c1c29de2d9 100644 --- a/app/models/programmes/primary_certificate.rb +++ b/app/models/programmes/primary_certificate.rb @@ -57,5 +57,9 @@ def achievement_type def enrolment_confirmation_required? true end + + def certificate_path + certificate_primary_certificate_path + end end end diff --git a/app/models/programmes/secondary_certificate.rb b/app/models/programmes/secondary_certificate.rb index a1b474afcd..41ad89241e 100644 --- a/app/models/programmes/secondary_certificate.rb +++ b/app/models/programmes/secondary_certificate.rb @@ -68,5 +68,9 @@ def achievement_type def enrolment_confirmation_required? false end + + def certificate_path + certificate_secondary_certificate_path + end end end diff --git a/app/services/cms/collections/programme.rb b/app/services/cms/collections/programme.rb new file mode 100644 index 0000000000..1cbdbe8b21 --- /dev/null +++ b/app/services/cms/collections/programme.rb @@ -0,0 +1,33 @@ +module Cms + module Collections + class Programme < Resource + def to_search_record(index_time) + raise NotImplementedError + end + + def self.is_collection = true + + def self.collection_attribute_mappings + [] + end + + def self.resource_attribute_mappings + [ + {model: Models::Slug, key: nil, param_name: :slug}, + {model: Models::TextField, key: :statusPendingTitle}, + {model: Models::TextBlock, key: :statusPendingText, with_wrapper: false}, + {model: Models::TextField, key: :statusCompletedTitle}, + {model: Models::TextBlock, key: :statusCompletedText, with_wrapper: false} + ] + end + + def self.cache_expiry + 15.minutes + end + + def self.resource_key + "programmes" + end + end + end +end diff --git a/app/services/cms/models/text_field.rb b/app/services/cms/models/text_field.rb new file mode 100644 index 0000000000..9ecf6ffd12 --- /dev/null +++ b/app/services/cms/models/text_field.rb @@ -0,0 +1,15 @@ +module Cms + module Models + class TextField + attr_accessor :value + + def initialize(value:) + @value = value + end + + def render + # has no render method, this exists just to provide data to model + end + end + end +end diff --git a/app/services/cms/providers/strapi/factories/model_factory.rb b/app/services/cms/providers/strapi/factories/model_factory.rb index 1e9917648b..686837c2b8 100644 --- a/app/services/cms/providers/strapi/factories/model_factory.rb +++ b/app/services/cms/providers/strapi/factories/model_factory.rb @@ -15,10 +15,17 @@ def self.process_model(mapping, all_data) to_seo(strapi_data) elsif model_class == Models::Slug model_class.new(slug: strapi_data[:slug]) + elsif model_class == Models::TextField + model_class.new(value: strapi_data) elsif model_class == Models::FeaturedImage to_featured_image(strapi_data[:data][:attributes]) if strapi_data[:data] elsif model_class == Models::TextBlock - to_content_block(strapi_data) + with_wrapper = if mapping.key?(:with_wrapper) + mapping[:with_wrapper] + else + true + end + to_content_block(strapi_data, with_wrapper:) elsif model_class == Models::SimpleTitle model_class.new(title: strapi_data) elsif model_class == Models::Aside diff --git a/app/services/cms/resource.rb b/app/services/cms/resource.rb index bd66cc440f..6b2edbffc6 100644 --- a/app/services/cms/resource.rb +++ b/app/services/cms/resource.rb @@ -14,6 +14,26 @@ def to_search_record(index_time) raise NotImplementedError end + def respond_to_missing?(method_name, include_private = false) + self.class.param_indexes.key?(method_name) || super + end + + def method_missing(method_name) + index = self.class.param_indexes[method_name] + data_models[index] + end + + def self.param_name(mapping) + return mapping[:param_name] if mapping.has_key?(:param_name) + mapping[:key].to_s.underscore.to_sym + end + + def self.param_indexes + resource_attribute_mappings.each_with_object({}).with_index do |(mapping, indexes), index| + indexes[param_name(mapping)] = index + end + end + def self.is_collection = false def self.resource_attribute_mappings diff --git a/app/webpacker/images/icons/programme_completed_icon.svg b/app/webpacker/images/icons/programme_completed_icon.svg new file mode 100644 index 0000000000..95bf944695 --- /dev/null +++ b/app/webpacker/images/icons/programme_completed_icon.svg @@ -0,0 +1,6 @@ +<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M19.4665 16.6666L17.9999 15.1999L25.4665 7.73327C26.1332 7.0666 27.0665 6.6666 27.9999 6.6666C28.9332 6.6666 29.8665 7.0666 30.5332 7.73327L31.3332 8.53327L29.8665 9.99994L29.0665 9.19993C28.7999 8.93327 28.3999 8.6666 27.8665 8.6666C27.3332 8.6666 27.0665 8.79993 26.6665 9.19993L19.1999 16.6666H19.4665ZM14.1332 11.3333L12.6665 9.8666L13.4665 9.0666C13.7332 8.79994 13.9999 8.39994 13.9999 7.8666C13.9999 7.33327 13.8665 7.0666 13.4665 6.6666L12.5332 5.73327L13.9999 4.2666L14.9332 5.19993C15.5999 5.8666 15.9999 6.79994 15.9999 7.73327C15.9999 8.6666 15.5999 9.59994 14.9332 10.2666L14.1332 11.0666V11.3333Z" fill="#FF8300"/> +<path d="M9.33366 10.6665L2.66699 29.3332L21.3337 22.6665L9.33366 10.6665ZM10.4003 15.5998L16.4003 21.5998L7.06699 24.9332L10.4003 15.5998Z" fill="#1C0F5F"/> +<path d="M16.8007 14.0001L15.334 12.5334L20.134 7.7334C20.4007 7.46673 20.6673 7.06673 20.6673 6.5334C20.6673 6.00007 20.534 5.7334 20.134 5.3334L18.0007 3.20007L19.4673 1.7334L21.6007 3.86673C22.2673 4.5334 22.6673 5.46673 22.6673 6.40007C22.6673 7.3334 22.2673 8.26673 21.6007 8.9334L16.8007 13.7334V14.0001Z" fill="#59FF69"/> +<path d="M22.1337 19.3332L20.667 17.8665L22.8003 15.7332C23.467 15.0665 24.4003 14.6665 25.3337 14.6665C26.267 14.6665 27.2003 15.0665 27.867 15.7332L30.0003 17.8665L28.5337 19.3332L26.4003 17.1998C26.1337 16.9332 25.7337 16.6665 25.2003 16.6665C24.667 16.6665 24.4003 16.7998 24.0003 17.1998L21.867 19.3332H22.1337Z" fill="#59FF69"/> +</svg> diff --git a/db/schema.rb b/db/schema.rb index 4746628a08..aad34cd507 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2024_11_01_083738) do +ActiveRecord::Schema.define(version: 2024_11_26_112120) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" @@ -317,6 +317,8 @@ t.jsonb "web_copy" t.jsonb "metadata" t.string "type" + t.string "cms_slug" + t.index ["cms_slug"], name: "index_programme_activity_groupings_on_cms_slug", unique: true t.index ["programme_id"], name: "index_programme_activity_groupings_on_programme_id" end diff --git a/previews/components/cms_split_horizontal_card_component_preview.rb b/previews/components/cms_split_horizontal_card_component_preview.rb index a153d15983..597e92aa07 100644 --- a/previews/components/cms_split_horizontal_card_component_preview.rb +++ b/previews/components/cms_split_horizontal_card_component_preview.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true -class CmsSplitHorizontialCardComponentPreview < ViewComponent::Preview +class CmsSplitHorizontalCardComponentPreview < ViewComponent::Preview def default - render(CmsSplitHorizontialCardComponent.new( + render(CmsSplitHorizontalCardComponent.new( section_title: Faker::Lorem.sentence, card_content: Cms::Mocks::RichBlocks.as_model, aside_content: Cms::Mocks::RichBlocks.as_model, diff --git a/previews/components/programme_status_component_preview.rb b/previews/components/programme_status_component_preview.rb new file mode 100644 index 0000000000..fc877c55fa --- /dev/null +++ b/previews/components/programme_status_component_preview.rb @@ -0,0 +1,27 @@ +class ProgrammeStatusComponentPreview < ViewComponent::Preview + class UPEMock + def initialize(status) + @status = status + end + + def in_state?(status) + @status == status + end + + def programme = Programme.primary_certificate + end + + def pending + user_programme_enrolment = UPEMock.new(:pending) + render( + ProgrammeStatusComponent.new(user_programme_enrolment:) + ) + end + + def complete + user_programme_enrolment = UPEMock.new(:complete) + render( + ProgrammeStatusComponent.new(user_programme_enrolment:) + ) + end +end From 762004eab2c6d7178894c5745ee47e91ab228fc8 Mon Sep 17 00:00:00 2001 From: Michael Squance <m.squance@stem.org.uk> Date: Wed, 4 Dec 2024 15:43:59 +0000 Subject: [PATCH 2/6] Undoing the schema thats auto migrated --- db/schema.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index aad34cd507..4746628a08 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2024_11_26_112120) do +ActiveRecord::Schema.define(version: 2024_11_01_083738) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" @@ -317,8 +317,6 @@ t.jsonb "web_copy" t.jsonb "metadata" t.string "type" - t.string "cms_slug" - t.index ["cms_slug"], name: "index_programme_activity_groupings_on_cms_slug", unique: true t.index ["programme_id"], name: "index_programme_activity_groupings_on_programme_id" end From 80881abff3f6d5d3cb74061ebecb8ea30e6770d1 Mon Sep 17 00:00:00 2001 From: Michael Squance <m.squance@stem.org.uk> Date: Tue, 10 Dec 2024 12:52:22 +0000 Subject: [PATCH 3/6] Started working on testing --- .../cms/providers/strapi/mocks/programme.rb | 15 +++++++++++++++ .../components/programme_status_component_spec.rb | 15 +++++++++++++++ spec/support/cms/providers/strapi/strapi_stubs.rb | 4 ++++ 3 files changed, 34 insertions(+) create mode 100644 app/services/cms/providers/strapi/mocks/programme.rb create mode 100644 spec/components/programme_status_component_spec.rb diff --git a/app/services/cms/providers/strapi/mocks/programme.rb b/app/services/cms/providers/strapi/mocks/programme.rb new file mode 100644 index 0000000000..a5f39c466b --- /dev/null +++ b/app/services/cms/providers/strapi/mocks/programme.rb @@ -0,0 +1,15 @@ +module Cms + module Providers + module Strapi + module Mocks + class Programme < StrapiMock + attribute(:slug) { Faker::Internet.slug } + attribute(:statusPendingTitle) { Faker::Internet.slug } + attribute(:statusPendingText) { TextBlock.generate_raw_data } + attribute(:statusCompletedTitle) { Faker::Internet.slug } + attribute(:statusCompletedText) { TextBlock.generate_raw_data } + end + end + end + end +end diff --git a/spec/components/programme_status_component_spec.rb b/spec/components/programme_status_component_spec.rb new file mode 100644 index 0000000000..e71eba745c --- /dev/null +++ b/spec/components/programme_status_component_spec.rb @@ -0,0 +1,15 @@ +require "rails_helper" + +RSpec.describe ProgrammeStatusComponent, type: :component do + let(:programme) { create(:primary_certificate) } + let(:user_programme_enrolment) { create(:user_programme_enrolment, programme:) } + + before do + stub_strapi_programme + described_class.new(user_programme_enrolment:) + end + + it "should render the wrapper" do + expect(page).to have_css(".programme-status-wrapper") + end +end diff --git a/spec/support/cms/providers/strapi/strapi_stubs.rb b/spec/support/cms/providers/strapi/strapi_stubs.rb index aabbfc88d5..4b22ad32ef 100644 --- a/spec/support/cms/providers/strapi/strapi_stubs.rb +++ b/spec/support/cms/providers/strapi/strapi_stubs.rb @@ -111,6 +111,10 @@ def stub_strapi_web_page_not_found(key) stub_request(:get, /^https:\/\/strapi.teachcomputing.org\/api\/web-pages\/#{key}/).to_return_json(body: not_found_response, status: 404) end + def stub_strapi_programme(key, page: Cms::Mocks::Programme.generate_raw_data) + stub_request(:get, /^https:\/\/strapi.teachcomputing.org\/api\/programmes\/#{key}/).to_return_json(body: {data: page}) + end + private def to_strapi_collection(records, page: 1, page_size: 10, page_count: 1) From 30d9b3484ba3b96eb3922ff1bc2f936d21e9b93f Mon Sep 17 00:00:00 2001 From: Michael Squance <m.squance@stem.org.uk> Date: Tue, 10 Dec 2024 16:23:05 +0000 Subject: [PATCH 4/6] Increasing test coverage on updates --- .../programme_status_component.scss | 1 + app/models/programme.rb | 4 -- app/models/programmes/a_level.rb | 2 +- app/models/programmes/i_belong.rb | 2 +- app/models/programmes/primary_certificate.rb | 4 -- .../programmes/secondary_certificate.rb | 4 -- .../cms/providers/strapi/mocks/programme.rb | 4 +- .../programme_status_component_spec.rb | 55 +++++++++++++++++-- spec/models/programme_spec.rb | 8 --- spec/models/programmes/a_level_spec.rb | 12 ++++ spec/models/programmes/cs_accelerator_spec.rb | 12 ++++ spec/models/programmes/i_belong_spec.rb | 12 ++++ .../programmes/primary_certificate_spec.rb | 6 ++ .../programmes/secondary_certificate_spec.rb | 12 ++++ .../cms/collections/programme_spec.rb | 36 ++++++++++++ spec/services/cms/resource_spec.rb | 45 ++++++++++++++- .../cms/providers/strapi/strapi_stubs.rb | 4 +- 17 files changed, 189 insertions(+), 34 deletions(-) create mode 100644 spec/services/cms/collections/programme_spec.rb diff --git a/app/components/programme_status_component/programme_status_component.scss b/app/components/programme_status_component/programme_status_component.scss index 8f419630f1..a21886a8b8 100644 --- a/app/components/programme_status_component/programme_status_component.scss +++ b/app/components/programme_status_component/programme_status_component.scss @@ -14,5 +14,6 @@ &__button-container { padding-top: 50px; + text-align: center; } } \ No newline at end of file diff --git a/app/models/programme.rb b/app/models/programme.rb index 003ecd389e..6a0888b24c 100644 --- a/app/models/programme.rb +++ b/app/models/programme.rb @@ -151,10 +151,6 @@ def user_is_eligible?(user) true end - def enrichment_enabled? - false - end - def programme_objectives programme_activity_groupings.includes(:programme_activities).order(:sort_key) end diff --git a/app/models/programmes/a_level.rb b/app/models/programmes/a_level.rb index 6e6c0e6ac2..7b45448255 100644 --- a/app/models/programmes/a_level.rb +++ b/app/models/programmes/a_level.rb @@ -44,7 +44,7 @@ def enrolment_confirmation_required? end def certificate_path - certificate_a_level_certificate_path + certificate_a_level_path end end end diff --git a/app/models/programmes/i_belong.rb b/app/models/programmes/i_belong.rb index 51ac6edaed..3c1425faba 100644 --- a/app/models/programmes/i_belong.rb +++ b/app/models/programmes/i_belong.rb @@ -60,7 +60,7 @@ def enrolment_confirmation_required? end def certificate_path - certificate_i_belong_certificate_path + certificate_i_belong_path end end end diff --git a/app/models/programmes/primary_certificate.rb b/app/models/programmes/primary_certificate.rb index c1c29de2d9..4a7234e2dd 100644 --- a/app/models/programmes/primary_certificate.rb +++ b/app/models/programmes/primary_certificate.rb @@ -38,10 +38,6 @@ def pathways? true end - def enrichment_enabled? - true - end - def send_pending_mail? true end diff --git a/app/models/programmes/secondary_certificate.rb b/app/models/programmes/secondary_certificate.rb index 41ad89241e..b5b9711480 100644 --- a/app/models/programmes/secondary_certificate.rb +++ b/app/models/programmes/secondary_certificate.rb @@ -38,10 +38,6 @@ def pathways? true end - def enrichment_enabled? - true - end - def programme_objectives [ ProgrammeObjectives::ProgrammeCompletionRequired.new( diff --git a/app/services/cms/providers/strapi/mocks/programme.rb b/app/services/cms/providers/strapi/mocks/programme.rb index a5f39c466b..b029c6c12c 100644 --- a/app/services/cms/providers/strapi/mocks/programme.rb +++ b/app/services/cms/providers/strapi/mocks/programme.rb @@ -5,9 +5,9 @@ module Mocks class Programme < StrapiMock attribute(:slug) { Faker::Internet.slug } attribute(:statusPendingTitle) { Faker::Internet.slug } - attribute(:statusPendingText) { TextBlock.generate_raw_data } + attribute(:statusPendingText) { RichBlocks.generate_data } attribute(:statusCompletedTitle) { Faker::Internet.slug } - attribute(:statusCompletedText) { TextBlock.generate_raw_data } + attribute(:statusCompletedText) { RichBlocks.generate_data } end end end diff --git a/spec/components/programme_status_component_spec.rb b/spec/components/programme_status_component_spec.rb index e71eba745c..2662f4dd2b 100644 --- a/spec/components/programme_status_component_spec.rb +++ b/spec/components/programme_status_component_spec.rb @@ -2,14 +2,59 @@ RSpec.describe ProgrammeStatusComponent, type: :component do let(:programme) { create(:primary_certificate) } - let(:user_programme_enrolment) { create(:user_programme_enrolment, programme:) } before do - stub_strapi_programme - described_class.new(user_programme_enrolment:) + stub_strapi_programme(programme.slug, programme: Cms::Mocks::Programme.generate_raw_data( + status_pending_title: "Pending title", + status_completed_title: "Completed title" + )) end - it "should render the wrapper" do - expect(page).to have_css(".programme-status-wrapper") + context "Enrolment enrolled" do + let(:user_programme_enrolment) { create(:user_programme_enrolment, programme:) } + + before do + render_inline(described_class.new(user_programme_enrolment:)) + end + + it "should not render" do + expect(page).not_to have_css(".programme-status-wrapper") + end + end + + context "Enrolment Pending" do + let(:user_programme_enrolment) { create(:pending_enrolment, programme:) } + + before do + render_inline(described_class.new(user_programme_enrolment:)) + end + + it "should render the wrapper" do + expect(page).to have_css(".programme-status-wrapper") + end + + it "should render the correct heading" do + expect(page).to have_css("h2.govuk-heading-m", text: "Pending title") + end + end + + context "Enrolment completed" do + let(:user_programme_enrolment) { create(:completed_enrolment, programme:) } + + before do + render_inline(described_class.new(user_programme_enrolment:)) + end + + it "should render the wrapper" do + expect(page).to have_css(".programme-status-wrapper") + end + + it "should render the correct heading" do + expect(page).to have_css("h2.govuk-heading-m", text: "Completed title") + end + + it "should render cerficate button" do + expect(page).to have_link("Download your certificate", href: "/certificate/primary-certificate/view-certificate") + end end end diff --git a/spec/models/programme_spec.rb b/spec/models/programme_spec.rb index 1398d0ea43..c3d223d3dc 100644 --- a/spec/models/programme_spec.rb +++ b/spec/models/programme_spec.rb @@ -345,14 +345,6 @@ end end - describe "#enrichment_enabled?" do - let(:programme) { create(:programme) } - - it "should return false" do - expect(programme.enrichment_enabled?).to be false - end - end - describe "#certificate_name" do it "should return not implemented error" do expect { generic_programme.certificate_name }.to raise_error(NotImplementedError) diff --git a/spec/models/programmes/a_level_spec.rb b/spec/models/programmes/a_level_spec.rb index 9dba193560..db0f4052af 100644 --- a/spec/models/programmes/a_level_spec.rb +++ b/spec/models/programmes/a_level_spec.rb @@ -24,6 +24,12 @@ end end + describe "#enrolment_confirmation_required?" do + it "should return false" do + expect(subject.enrolment_confirmation_required?).to be false + end + end + describe "#enrol_path" do it "returns the path for the enrol" do expect(subject.enrol_path(user_programme_enrolment: {user_id: "user_id", @@ -52,4 +58,10 @@ expect(subject.programme_objectives[1..]).to match_array(pags) end end + + describe "#certificate_path" do + it "should return its certificate path" do + expect(subject.certificate_path).to eq "/certificate/a-level-certificate/view-certificate" + end + end end diff --git a/spec/models/programmes/cs_accelerator_spec.rb b/spec/models/programmes/cs_accelerator_spec.rb index fd22e9489e..7bc097fdb1 100644 --- a/spec/models/programmes/cs_accelerator_spec.rb +++ b/spec/models/programmes/cs_accelerator_spec.rb @@ -520,4 +520,16 @@ expect(programme.auto_enrollable?).to be true end end + + describe "#enrolment_confirmation_required?" do + it "should return false" do + expect(programme.enrolment_confirmation_required?).to be false + end + end + + describe "#certificate_path" do + it "should return its certificate path" do + expect(programme.certificate_path).to eq "/certificate/subject-knowledge/view-certificate" + end + end end diff --git a/spec/models/programmes/i_belong_spec.rb b/spec/models/programmes/i_belong_spec.rb index f1168ef260..93e688a228 100644 --- a/spec/models/programmes/i_belong_spec.rb +++ b/spec/models/programmes/i_belong_spec.rb @@ -58,4 +58,16 @@ expect(programme.minimum_character_required_community_evidence).to eq(50) end end + + describe "#enrolment_confirmation_required?" do + it "should return false" do + expect(programme.enrolment_confirmation_required?).to be false + end + end + + describe "#certificate_path" do + it "should return its certificate path" do + expect(programme.certificate_path).to eq "/certificate/i-belong/view-certificate" + end + end end diff --git a/spec/models/programmes/primary_certificate_spec.rb b/spec/models/programmes/primary_certificate_spec.rb index c772349197..bc52666599 100644 --- a/spec/models/programmes/primary_certificate_spec.rb +++ b/spec/models/programmes/primary_certificate_spec.rb @@ -105,4 +105,10 @@ expect(programme.enrolment_confirmation_required?).to be true end end + + describe "#certificate_path" do + it "should return its certificate path" do + expect(programme.certificate_path).to eq "/certificate/primary-certificate/view-certificate" + end + end end diff --git a/spec/models/programmes/secondary_certificate_spec.rb b/spec/models/programmes/secondary_certificate_spec.rb index a8a464c92c..0ddccd8bf8 100644 --- a/spec/models/programmes/secondary_certificate_spec.rb +++ b/spec/models/programmes/secondary_certificate_spec.rb @@ -111,4 +111,16 @@ expect(secondary_certificate.auto_enrollable?).to be true end end + + describe "#enrolment_confirmation_required?" do + it "should return false" do + expect(secondary_certificate.enrolment_confirmation_required?).to be false + end + end + + describe "#certificate_path" do + it "should return its certificate path" do + expect(secondary_certificate.certificate_path).to eq "/certificate/secondary-certificate/view-certificate" + end + end end diff --git a/spec/services/cms/collections/programme_spec.rb b/spec/services/cms/collections/programme_spec.rb new file mode 100644 index 0000000000..2cc1a1c019 --- /dev/null +++ b/spec/services/cms/collections/programme_spec.rb @@ -0,0 +1,36 @@ +require "rails_helper" + +RSpec.describe Cms::Collections::Programme do + it "should have correct resource_key" do + expect(described_class.resource_key).to eq("programmes") + end + + it "should have 15 minute cache expiry" do + expect(described_class.cache_expiry).to eq(15.minutes) + end + + it "defines not collection attribute mappings" do + expect(described_class.collection_attribute_mappings).to eq([]) + end + + context "slug" do + let(:slug) { "programme-resource-test" } + let!(:programme) { create(:programme, slug:) } + before do + mock_data = Cms::Mocks::Programme.generate_raw_data(slug:) + stub_strapi_programme(slug, programme: mock_data) + end + + it "should return correctly for single page" do + cms_programme = described_class.get(slug) + expect(cms_programme.slug.slug).to eq(slug) + end + + it "should raise error for search records" do + cms_programme = described_class.get(slug) + expect { + cms_programme.to_search_record(DateTime.now) + }.to raise_exception(NotImplementedError) + end + end +end diff --git a/spec/services/cms/resource_spec.rb b/spec/services/cms/resource_spec.rb index c94237bc4d..74b2085a8d 100644 --- a/spec/services/cms/resource_spec.rb +++ b/spec/services/cms/resource_spec.rb @@ -99,8 +99,12 @@ def self.resource_key end end - it "calling all gets collection object" do + before do stub_strapi_get_collection_entity("cms-collection-resource-test") + stub_strapi_get_single_blog_post("cms-collection-resource-test/test-post") + end + + it "calling all gets collection object" do response = collection_class.all(1, 10) expect(response).to be_a Cms::Collection end @@ -109,19 +113,54 @@ def self.resource_key expect(collection_class.collection_attribute_mappings).to be_a Array end + describe "#param_name" do + it "should use key as param_name" do + expect(collection_class.param_name({key: :title, model: Cms::Models::SimpleTitle})).to eq(:title) + end + + it "should use param_name as name when specified" do + expect(collection_class.param_name({key: :title, model: Cms::Models::SimpleTitle, param_name: :something})).to eq(:something) + end + end + + describe "#param_indexes" do + it "should include key" do + expect(collection_class.param_indexes).to have_key(:title) + end + + it "should set correct index" do + expect(collection_class.param_indexes[:title]).to eq(0) + end + end + it "calling collection_view should create component" do - stub_strapi_get_collection_entity("cms-collection-resource-test") response = collection_class.all(1, 10) resource = response.resources.first expect(resource.data_models.first).to be_a Cms::Models::SimpleTitle end it "calling get should return single record" do - stub_strapi_get_single_blog_post("cms-collection-resource-test/test-post") response = collection_class.get("test-post") expect(response).to be_a described_class end + it "should raise error for search_record" do + response = collection_class.get("test-post") + expect { + response.to_search_record(DateTime.now) + }.to raise_exception(NotImplementedError) + end + + it "should respond_to mapping key" do + response = collection_class.get("test-post") + expect(response).to respond_to(:title) + end + + it "should respond data model for mapping key" do + response = collection_class.get("test-post") + expect(response.title).to be_a Cms::Models::SimpleTitle + end + context "should cache results" do let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) } diff --git a/spec/support/cms/providers/strapi/strapi_stubs.rb b/spec/support/cms/providers/strapi/strapi_stubs.rb index 4b22ad32ef..0d68416630 100644 --- a/spec/support/cms/providers/strapi/strapi_stubs.rb +++ b/spec/support/cms/providers/strapi/strapi_stubs.rb @@ -111,8 +111,8 @@ def stub_strapi_web_page_not_found(key) stub_request(:get, /^https:\/\/strapi.teachcomputing.org\/api\/web-pages\/#{key}/).to_return_json(body: not_found_response, status: 404) end - def stub_strapi_programme(key, page: Cms::Mocks::Programme.generate_raw_data) - stub_request(:get, /^https:\/\/strapi.teachcomputing.org\/api\/programmes\/#{key}/).to_return_json(body: {data: page}) + def stub_strapi_programme(key, programme: Cms::Mocks::Programme.generate_raw_data) + stub_request(:get, /^https:\/\/strapi.teachcomputing.org\/api\/programmes\/#{key}/).to_return_json(body: {data: programme}) end private From 5c83773c75f37efe08142d59c6ce9855eab891a8 Mon Sep 17 00:00:00 2001 From: Michael Squance <m.squance@stem.org.uk> Date: Wed, 11 Dec 2024 15:01:02 +0000 Subject: [PATCH 5/6] Removing icon on the pending view --- .../programme_status_component.html.erb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/components/programme_status_component/programme_status_component.html.erb b/app/components/programme_status_component/programme_status_component.html.erb index 54265e902a..d0494ca32b 100644 --- a/app/components/programme_status_component/programme_status_component.html.erb +++ b/app/components/programme_status_component/programme_status_component.html.erb @@ -3,7 +3,9 @@ <%= row.with_column("two-thirds") do %> <div class="programme-status-wrapper__title-row"> <h2 class="govuk-heading-m"><%= title %></h2> - <%= image_pack_tag "media/images/icons/programme_completed_icon.svg" %> + <% if @user_programme_enrolment.in_state?(:complete) %> + <%= image_pack_tag "media/images/icons/programme_completed_icon.svg" %> + <% end %> </div> <%= render content.render %> <% end %> From 4cf5041a9921fb8b88f0e3bc4db0d8b27e876bec Mon Sep 17 00:00:00 2001 From: Michael Squance <m.squance@stem.org.uk> Date: Mon, 16 Dec 2024 09:59:07 +0000 Subject: [PATCH 6/6] Removing draggable --- .../programme_status_component.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/components/programme_status_component/programme_status_component.html.erb b/app/components/programme_status_component/programme_status_component.html.erb index d0494ca32b..72acac5bc3 100644 --- a/app/components/programme_status_component/programme_status_component.html.erb +++ b/app/components/programme_status_component/programme_status_component.html.erb @@ -13,7 +13,7 @@ <% if @user_programme_enrolment.in_state?(:complete) %> <div class="programme-status-wrapper__button-container"> <%= link_to 'Download your certificate', @user_programme_enrolment.programme.certificate_path, - class: 'govuk-button button', role: 'button', draggable: 'false' %></p> + class: 'govuk-button button', role: 'button' %></p> </div> <% end %> <% end %>