diff --git a/app/controllers/activity_categories_controller.rb b/app/controllers/activity_categories_controller.rb index ce09a56a40..249c29812d 100644 --- a/app/controllers/activity_categories_controller.rb +++ b/app/controllers/activity_categories_controller.rb @@ -7,7 +7,11 @@ def index @pupil_categories = ActivityCategory.pupil.by_name @activity_categories = ActivityCategory.featured.by_name.select { |activity_category| activity_category.activity_types.active.count >= 4 } @activity_count = ActivityType.active_and_not_custom.count - @programme_types = ProgrammeType.featured + if Flipper.enabled?(:todos, current_user) + @programme_types = ProgrammeType.featured.with_task_type(ActivityType) + else + @programme_types = ProgrammeType.featured + end end def show diff --git a/app/controllers/intervention_type_groups_controller.rb b/app/controllers/intervention_type_groups_controller.rb index 6163e6cdf3..abda6ec679 100644 --- a/app/controllers/intervention_type_groups_controller.rb +++ b/app/controllers/intervention_type_groups_controller.rb @@ -5,6 +5,9 @@ class InterventionTypeGroupsController < ApplicationController def index @intervention_type_groups = @intervention_type_groups.by_name + if Flipper.enabled?(:todos, current_user) + @programme_types = ProgrammeType.featured.with_task_type(InterventionType) + end end def show diff --git a/app/controllers/programme_types_controller.rb b/app/controllers/programme_types_controller.rb index c6426d40b1..dd8ea7a317 100644 --- a/app/controllers/programme_types_controller.rb +++ b/app/controllers/programme_types_controller.rb @@ -9,12 +9,18 @@ def index end def show - route_not_found unless @programme_type.active + if Flipper.enabled?(:todos) + route_not_found unless @programme_type.active && @programme_type.has_todos? + else + route_not_found unless @programme_type.active + end end private def user_progress - @user_progress = Programmes::UserProgress.new(current_user) + if !Flipper.enabled?(:todos) || Flipper.enabled?(:todos_old) + @user_progress = Programmes::UserProgress.new(current_user) + end end end diff --git a/app/models/concerns/todos/assignable.rb b/app/models/concerns/todos/assignable.rb index b59c249ca5..c9e379ae47 100644 --- a/app/models/concerns/todos/assignable.rb +++ b/app/models/concerns/todos/assignable.rb @@ -16,6 +16,18 @@ module Assignable accepts_nested_attributes_for :activity_type_todos, allow_destroy: true accepts_nested_attributes_for :intervention_type_todos, allow_destroy: true + + scope :with_task_type, ->(task_type) { + where(id: ProgrammeType.joins(:todos).where(todos: { task_type: task_type.name }).distinct) + } + end + + def has_todos? + todos.any? + end + + def no_todos? + todos.none? end # Has the provided school already completed all activity & intervention types this year? diff --git a/app/models/concerns/todos/completable.rb b/app/models/concerns/todos/completable.rb index 9e0d466490..4233501362 100644 --- a/app/models/concerns/todos/completable.rb +++ b/app/models/concerns/todos/completable.rb @@ -15,40 +15,24 @@ module Completable scope :completable, -> { raise NoMethodError, 'Implement completable scope in subclass!' } end - def assignable_todos - assignable.todos - end - - def assignable_todo_ids - assignable_todos.ids - end - def completed_todo_ids completed_todos.pluck(:todo_id) end - def has_todos? - assignable_todo_ids.any? - end - - def nothing_todo? - assignable_todo_ids.none? - end - def completable? - has_todos? && todos_complete? + assignable.has_todos? && todos_complete? end def todos_incomplete? - (assignable_todo_ids - completed_todo_ids).any? + (assignable.todos.ids - completed_todo_ids).any? end def todos_complete? - (assignable_todo_ids - completed_todo_ids).empty? + (assignable.todos.ids - completed_todo_ids).empty? end def uncompleted_todos - assignable_todos - todos_completed + assignable.todos - todos_completed end def uncompleted_tasks diff --git a/app/models/intervention_type.rb b/app/models/intervention_type.rb index a030d035fa..a1734b957a 100644 --- a/app/models/intervention_type.rb +++ b/app/models/intervention_type.rb @@ -78,7 +78,7 @@ class InterventionType < ApplicationRecord before_save :copy_searchable_attributes def actions_for_school(school) - observations.for_school(school) + observations.visible.for_school(school) end # override default name for this resource in transifex diff --git a/app/models/programme_type.rb b/app/models/programme_type.rb index b22336c2bf..d6679e0f10 100644 --- a/app/models/programme_type.rb +++ b/app/models/programme_type.rb @@ -25,6 +25,8 @@ class ProgrammeType < ApplicationRecord translates :document_link, type: :string, fallbacks: { cy: :en } t_has_one_attached :image + + ## these two relationships to be removed when todos feature removed has_many :programme_type_activity_types has_many :activity_types, through: :programme_type_activity_types @@ -98,8 +100,8 @@ def activity_types_and_school_activity(school) end def repeatable?(school) - # Does the school have any programmes for this programme type completed before the beginning of this academic year? - school.programmes.where(programme_type: self).completed.where(ended_on: ..school.current_academic_year.start_date).any? + # Only allow a repeat if the school hasn't completed this programe type this academic year + school.programmes.where(programme_type: self).completed.where(ended_on: school.current_academic_year.start_date..).none? end # Provide a list of activity types a school has already completed this year for this programme type diff --git a/app/models/school.rb b/app/models/school.rb index 64d988c235..35456aff97 100644 --- a/app/models/school.rb +++ b/app/models/school.rb @@ -130,11 +130,18 @@ class ProcessDataError < StandardError; end has_many :school_target_events, inverse_of: :school has_many :audits, inverse_of: :school + # relationships to be removed when :todos removed has_many :audit_activity_types, -> { distinct }, through: :audits, source: :activity_types has_many :audit_intervention_types, -> { distinct }, through: :audits, source: :intervention_types + has_many :audit_todos, through: :audits, source: :todos + has_many :audit_activity_type_tasks, through: :audit_todos, source: :task, source_type: 'ActivityType' + has_many :audit_intervention_type_tasks, through: :audit_todos, source: :task, source_type: 'InterventionType' + has_many :programmes, inverse_of: :school has_many :programme_types, through: :programmes + + # relationships to be removed when :todos removed has_many :programme_activity_types, through: :programmes, source: :activity_types has_many :alerts, inverse_of: :school diff --git a/app/models/todo.rb b/app/models/todo.rb index bb9e92a435..20401bb544 100644 --- a/app/models/todo.rb +++ b/app/models/todo.rb @@ -49,7 +49,7 @@ def complete_for?(completable:) end def latest_recording_for(completable:) - recordings_for(school: completable.school).in_academic_year_for(completable.school, Time.zone.now).by_date(:desc).first + recordings_for(school: completable.school).in_academic_year_for(completable.school, Time.zone.now).by_date(:asc).order(id: :asc).last end private @@ -59,7 +59,7 @@ def recordings_for(school:) when 'ActivityType' school.activities.where(activity_type: task) when 'InterventionType' - school.observations.intervention.where(intervention_type: task) + school.observations.intervention.visible.where(intervention_type: task) else raise StandardError, 'Unsupported task type' end diff --git a/app/services/completables/progress.rb b/app/services/completables/progress.rb index 6ad39b9b9c..f85dc8818c 100644 --- a/app/services/completables/progress.rb +++ b/app/services/completables/progress.rb @@ -25,7 +25,7 @@ def uncompleted_scores end def available_count - completable.assignable_todos.count + completable.assignable.todos.count end def completed_count diff --git a/app/services/observation_removal.rb b/app/services/observation_removal.rb index e0c39120cf..cb7eebfcf2 100644 --- a/app/services/observation_removal.rb +++ b/app/services/observation_removal.rb @@ -9,6 +9,9 @@ def process @observation.destroy else @observation.update_attribute(:visible, false) + if Flipper.enabled?(:todos) + CompletedTodo.where(recording: @observation).destroy_all if @observation.intervention? + end end end end diff --git a/app/services/recommendations/actions.rb b/app/services/recommendations/actions.rb index 84beb09e46..591094b810 100644 --- a/app/services/recommendations/actions.rb +++ b/app/services/recommendations/actions.rb @@ -7,7 +7,11 @@ def alert_tasks(alert) end def audit_tasks - school.audit_intervention_types + if Flipper.enabled?(:todos) + school.audit_intervention_type_tasks + else + school.audit_intervention_types + end end def task_tasks(task) diff --git a/app/services/recommendations/activities.rb b/app/services/recommendations/activities.rb index 08577050a1..9776fd7869 100644 --- a/app/services/recommendations/activities.rb +++ b/app/services/recommendations/activities.rb @@ -11,7 +11,11 @@ def alert_tasks(alert) end def audit_tasks - with_key_stage(school.audit_activity_types) + if Flipper.enabled?(:todos) + with_key_stage(school.audit_activity_type_tasks) + else + with_key_stage(school.audit_activity_types) + end end def task_tasks(task) diff --git a/app/views/activity_categories/_programme_types.html.erb b/app/views/activity_categories/_programme_types.html.erb deleted file mode 100644 index 52a351a1dc..0000000000 --- a/app/views/activity_categories/_programme_types.html.erb +++ /dev/null @@ -1,14 +0,0 @@ -
- <% programme_types.each do |programme_type| %> -
- <%= link_to programme_type_path(programme_type) do %> - <%= render 'programme_types/image', programme_type: programme_type, css_class: "" %> - <% end %> -
-

- <%= programme_type.title %> -

-
-
- <% end %> -
diff --git a/app/views/activity_categories/index.html.erb b/app/views/activity_categories/index.html.erb index 86c2a07988..d3329a21e2 100644 --- a/app/views/activity_categories/index.html.erb +++ b/app/views/activity_categories/index.html.erb @@ -40,21 +40,7 @@ <%= render 'pupil_categories', activity_categories: @pupil_categories.first(4) %> <% end %> - <% if !@programme_types.blank? %> -
-
-
-

<%= t('activity_categories.our_programmes.title') %>

-
- <%= link_to t('activity_categories.view_all_programmes'), programme_types_path, - class: 'btn btn-default' %> -
-
-

<%= t('activity_categories.our_programmes.introduction') %>

-
-
- <%= render 'programme_types', programme_types: @programme_types.first(4) %> - <% end %> + <%= render 'shared/tasks/programme_types', programme_types: @programme_types %> <% @activity_categories.each do |activity_category| %>
diff --git a/app/views/intervention_type_groups/index.html.erb b/app/views/intervention_type_groups/index.html.erb index 91edb6091e..9c52ff42dc 100644 --- a/app/views/intervention_type_groups/index.html.erb +++ b/app/views/intervention_type_groups/index.html.erb @@ -23,6 +23,10 @@ <%= render 'schools/prompt_recommended', scope: :adult %> +<% if Flipper.enabled?(:todos, current_user) %> + <%= render 'shared/tasks/programme_types', programme_types: @programme_types %> +<% end %> + <% @intervention_type_groups.each do |intervention_type_group| %>
diff --git a/app/views/programme_types/_intention.html.erb b/app/views/programme_types/_intention.html.erb new file mode 100644 index 0000000000..dbcf5c9568 --- /dev/null +++ b/app/views/programme_types/_intention.html.erb @@ -0,0 +1,7 @@ +<% if programme_type.activity_type_todos.none? %> + <%= render IconComponent.new(name: 'people-group') %> <%= t('programme_types.intention.adults') %> +<% elsif programme_type.intervention_type_todos.none? %> + <%= render IconComponent.new(name: 'book-open-reader') %> <%= t('programme_types.intention.pupils') %> +<% else %> + <%= render IconComponent.new(name: 'school') %> <%= t('programme_types.intention.all') %> +<% end %> diff --git a/app/views/programme_types/_programme_type.html.erb b/app/views/programme_types/_programme_type.html.erb new file mode 100644 index 0000000000..23392b1896 --- /dev/null +++ b/app/views/programme_types/_programme_type.html.erb @@ -0,0 +1,45 @@ +<% programme = programme_type.programme_for_school(current_user_school) if current_user_school %> + +
+
+ <%= link_to programme_type_path(programme_type) do %> + <%= render 'programme_types/image', programme_type: programme_type, css_class: 'activity-card-img' %> + <% end %> +
+
+

+ <%= link_to programme_type.title, programme_type_path(programme_type), style: 'text-decoration: none;' %> +

+ <% if programme&.completed? %> +

+ + <%= fa_icon('flag-checkered text-success') %> + + <%= t('programme_types.cards.you_have_already_completed_this_programme') %> +

+ <% elsif programme&.started? %> +

+ + <%= far_icon('check-circle text-success') %> + + <%= t('programme_types.cards.you_have_already_started_this_programme') %> +

+ <% end %> +

+ <%= programme_type.short_description %> +

+

+ <%= render 'intention', programme_type: %> +

+

<%= t('programme_types.cards.bonus_points_html', + bonus_score: tag.span(programme_type.bonus_score, class: 'badge badge-success')) %>

+
+
+ <% if programme&.started? %> + <%= link_to t('programme_types.cards.continue'), programme_type_path(programme_type), + class: 'btn btn-primary btn-lg' %> + <% else %> + <%= link_to t('programme_types.cards.view'), programme_type_path(programme_type), class: 'btn btn-primary btn-lg' %> + <% end %> +
+
diff --git a/app/views/programme_types/index.html.erb b/app/views/programme_types/index.html.erb index 8b2e7ed2ff..92253d64a6 100644 --- a/app/views/programme_types/index.html.erb +++ b/app/views/programme_types/index.html.erb @@ -17,4 +17,10 @@
-<%= render "cards", programme_types: @programme_types, user_progress: @user_progress %> +<% if Flipper.enabled?(:todos, current_user) %> + <% @programme_types.each do |programme_type| %> + <%= render('programme_type', programme_type:) if programme_type.has_todos? %> + <% end %> +<% else %> + <%= render 'cards', programme_types: @programme_types, user_progress: @user_progress %> +<% end %> diff --git a/app/views/programme_types/show.html.erb b/app/views/programme_types/show.html.erb index f5153bedb1..aec395e0af 100644 --- a/app/views/programme_types/show.html.erb +++ b/app/views/programme_types/show.html.erb @@ -9,6 +9,9 @@

<%= @programme_type.title %>

<%= @programme_type.short_description %>

+ <% if Flipper.enabled?(:todos) %> +

<%= render 'intention', programme_type: @programme_type %>

+ <% end %>

<%= t('programme_types.cards.bonus_points_html', bonus_score: tag.span(@programme_type.bonus_score, class: 'badge badge-success')) %>

@@ -43,7 +46,7 @@ <%= render 'programme_types/prompts/prompt', programme_type: @programme_type, school: current_user_school %> <% elsif programme&.completed? %> <%= render 'programme_types/prompts/completed', programme: programme %> - <% elsif programme %> + <% elsif programme&.started? %> <%= render 'programme_types/prompts/started', programme: programme %> <% end %> diff --git a/app/views/schools/audits/show.html.erb b/app/views/schools/audits/show.html.erb index c4bc6b82e3..a07c9fc36e 100644 --- a/app/views/schools/audits/show.html.erb +++ b/app/views/schools/audits/show.html.erb @@ -50,7 +50,7 @@ <% if Flipper.enabled?(:todos, current_user) %> <% if @audit.has_todos? %>

- <%= t('schools.audits.show.completing_all_of_these_activities_will_award_you') %> + <%= t('schools.audits.show.completed_points') %> <%= SiteSettings.current&.audit_activities_bonus_points %> <%= t('schools.audits.show.points', count: SiteSettings.current&.audit_activities_bonus_points) %>

diff --git a/app/views/shared/tasks/_programme_types.html.erb b/app/views/shared/tasks/_programme_types.html.erb new file mode 100644 index 0000000000..cdd2a0486a --- /dev/null +++ b/app/views/shared/tasks/_programme_types.html.erb @@ -0,0 +1,33 @@ +<% if programme_types&.any? && programme_types.count >= 4 %> +
+
+
+

<%= t('activity_categories.our_programmes.title') %>

+
+ <%= link_to t('activity_categories.view_all_programmes'), programme_types_path, + class: 'btn btn-default' %> +
+
+ <% if Flipper.enabled?(:todos, current_user) %> +

<%= t('activity_categories.our_programmes.introduction') %>

+ <% else %> +

<%= t('activity_categories.our_programmes.introduction_activities') %>

+ <% end %> +
+
+ +
+ <% programme_types.first(4).each do |programme_type| %> +
+ <%= link_to programme_type_path(programme_type) do %> + <%= render 'programme_types/image', programme_type: programme_type, css_class: '' %> + <% end %> +
+

+ <%= programme_type.title %> +

+
+
+ <% end %> +
+<% end %> diff --git a/config/locales/cy/views/activity_categories/activity_categories.yml b/config/locales/cy/views/activity_categories/activity_categories.yml index 63f25bdb14..fa8441a15e 100644 --- a/config/locales/cy/views/activity_categories/activity_categories.yml +++ b/config/locales/cy/views/activity_categories/activity_categories.yml @@ -10,7 +10,7 @@ cy: item_2: Cynlluniau gwersi yn ymwneud ag ynni ac adnoddau y gellir eu lawrlwytho. item_3: Cefnogaeth i ddisgyblion wrth ddylunio a chynnal arbrofion i fonitro data yn ymwneud ag ynni a phatrymau ymddygiad yn yr ysgol. our_programmes: - introduction: Rhaglenni byr o weithgareddau cysylltiedig y gall disgyblion weithio drwyddynt gam wrth gam i gael mwy o effaith. + introduction_activities: Rhaglenni byr o weithgareddau cysylltiedig y gall disgyblion weithio drwyddynt gam wrth gam i gael mwy o effaith. title: Ein Rhaglenni page_title: Gweithgareddau pupil: diff --git a/config/locales/views/activity_categories/activity_categories.yml b/config/locales/views/activity_categories/activity_categories.yml index 46964df217..f5598f2c95 100644 --- a/config/locales/views/activity_categories/activity_categories.yml +++ b/config/locales/views/activity_categories/activity_categories.yml @@ -9,7 +9,8 @@ en: item_2: Energy-related lesson plans and downloadable resources. item_3: Support for pupils in designing and carrying out experiments to monitor energy related data and behaviour patterns at school. our_programmes: - introduction: Short programmes of related activities that pupils can work through step-by-step to achieve greater impact. + introduction: Short programmes of related tasks that can be worked through step-by-step to achieve greater impact + introduction_activities: Short programmes of related activities that pupils can work through step-by-step to achieve greater impact. title: Our Programmes page_title: Activities pupil: diff --git a/config/locales/views/programme_types/programme_types.yml b/config/locales/views/programme_types/programme_types.yml index d8567abe82..7ee21faee6 100644 --- a/config/locales/views/programme_types/programme_types.yml +++ b/config/locales/views/programme_types/programme_types.yml @@ -15,6 +15,10 @@ en: introduction_2: As an Energy Sparks user you can enrol in any of our programmes and record activities to track your progress and score points for your school page_title: Programmes title: Our Energy Saving Programmes + intention: + adults: This programme is intended for adults + all: This programme is intended for the whole school + pupils: This programme is intended for pupils prompt: completed_message_html: one: You've completed all the activities in this programme. Mark it done to score %{count} bonus point? diff --git a/config/locales/views/schools/schools.yml b/config/locales/views/schools/schools.yml index 5b73c06cea..b1e13fa529 100644 --- a/config/locales/views/schools/schools.yml +++ b/config/locales/views/schools/schools.yml @@ -98,6 +98,7 @@ en: show: completed_message: Congratulations, you completed all recommended actions and activities on %{date}! completed_on: Completed on + completed_points: Completing all of these tasks will award you completing_all_of_these_activities_will_award_you: Completing all of these activities will award you download_report: Download report points: diff --git a/lib/tasks/todos/import.rake b/lib/tasks/todos/import.rake index 848e85d5bf..38e46b6af8 100644 --- a/lib/tasks/todos/import.rake +++ b/lib/tasks/todos/import.rake @@ -19,7 +19,7 @@ namespace :todos do ## latest activity for this activity_type completed since the audit was created activity = audit.school.activities.where( - activity_type: audit_activity_type.activity_type, happened_on: audit.created_at..).order(happened_on: :asc).last + activity_type: audit_activity_type.activity_type, happened_on: audit.created_at..).order(happened_on: :asc, id: :asc).last if activity audit.completed_todos.find_or_create_by!( @@ -36,8 +36,8 @@ namespace :todos do notes: audit_intervention_type.notes) ## latest observation for this intervention_type completed since the audit was created - observation = audit.school.observations.intervention.where( - intervention_type: audit_intervention_type.intervention_type, at: audit.created_at..).order(at: :asc).last + observation = audit.school.observations.intervention.visible.where( + intervention_type: audit_intervention_type.intervention_type, at: audit.created_at..).order(at: :asc, id: :asc).last if observation audit.completed_todos.find_or_create_by!( todo: todo, diff --git a/spec/factories/programme_types_factory.rb b/spec/factories/programme_types_factory.rb index c44e5d4afb..10cdc1f309 100644 --- a/spec/factories/programme_types_factory.rb +++ b/spec/factories/programme_types_factory.rb @@ -13,6 +13,18 @@ end end + trait :with_activity_type_todos do + after(:create) do |programme_type, _evaluator| + create_list(:activity_type_todo, 3, assignable: programme_type) + end + end + + trait :with_intervention_type_todos do + after(:create) do |programme_type, _evaluator| + create_list(:intervention_type_todo, 3, assignable: programme_type) + end + end + # old way - remove when :todos feature removed factory :programme_type_with_activity_types do transient do diff --git a/spec/services/recommendations/actions_spec.rb b/spec/services/recommendations/actions_spec.rb index 5a5309a7cd..77cc0dced6 100644 --- a/spec/services/recommendations/actions_spec.rb +++ b/spec/services/recommendations/actions_spec.rb @@ -20,8 +20,16 @@ def complete_task(task, school:, at:) end describe '#based_on_energy_use' do - subject(:energy_use) { service.based_on_energy_use(limit) } + context without_feature: :todos do + subject(:energy_use) { service.based_on_energy_use(limit) } - it_behaves_like 'a service making recommendations based on energy use' + it_behaves_like 'a service making recommendations based on energy use', with_todos: false + end + + context with_feature: :todos do + subject(:energy_use) { service.based_on_energy_use(limit) } + + it_behaves_like 'a service making recommendations based on energy use', with_todos: true + end end end diff --git a/spec/services/recommendations/activities_spec.rb b/spec/services/recommendations/activities_spec.rb index 3ea2648033..696eaa9433 100644 --- a/spec/services/recommendations/activities_spec.rb +++ b/spec/services/recommendations/activities_spec.rb @@ -63,7 +63,13 @@ def complete_task(task, school:, at:) context 'when school has no key stages' do let(:key_stages) { [] } - it_behaves_like 'a service making recommendations based on energy use' + context without_feature: :todos do + it_behaves_like 'a service making recommendations based on energy use' + end + + context with_feature: :todos do + it_behaves_like 'a service making recommendations based on energy use', with_todos: true + end end context 'when school has key stages' do diff --git a/spec/support/shared_examples/recommendations_service.rb b/spec/support/shared_examples/recommendations_service.rb index 6811c10add..554edd12ba 100644 --- a/spec/support/shared_examples/recommendations_service.rb +++ b/spec/support/shared_examples/recommendations_service.rb @@ -68,7 +68,7 @@ end end -RSpec.shared_examples 'a service making recommendations based on energy use' do +RSpec.shared_examples 'a service making recommendations based on energy use' do |with_todos: false| let!(:alert_generation_run) { create(:alert_generation_run, school: school)} let!(:alert_type_elec) { create(:alert_type, fuel_type: :electricity)} let!(:alert_type_gas) { create(:alert_type, fuel_type: :gas)} @@ -191,8 +191,21 @@ it { expect(energy_use).to be_empty } context 'when school has suggested actions from an audit' do - let!(:audit) { create(:audit, school: school, "#{task_types}": create_list(task_type, 6)) } - let(:audit_task_types) { audit.send(task_types) } + let!(:audit) do + if with_todos + create(:audit, school: school, "#{task_type}_todos": create_list("#{task_type}_todo", 6)) + else + create(:audit, school: school, "#{task_types}": create_list(task_type, 6)) + end + end + + let(:audit_task_types) do + if with_todos + audit.send("#{task_type}_tasks") + else + audit.send(task_types) + end + end it 'tops up from them' do expect(energy_use).to eq(audit_task_types.take(5)) diff --git a/spec/support/shared_examples/todos.rb b/spec/support/shared_examples/todos.rb index 6b7b4c8eb7..620264ed84 100644 --- a/spec/support/shared_examples/todos.rb +++ b/spec/support/shared_examples/todos.rb @@ -13,6 +13,7 @@ context 'when school has multiple recordings for task' do let!(:older) { create(:activity, activity_type:, school:, happened_on: 3.days.ago) } + let!(:new) { create(:activity, activity_type:, school:, happened_on: 2.days.ago) } let!(:newer) { create(:activity, activity_type:, school:, happened_on: 2.days.ago) } let!(:created_last) { create(:activity, activity_type:, school:, happened_on: 4.days.ago) } @@ -58,6 +59,7 @@ context 'when school has multiple recordings for task' do let!(:older) { create(:observation, :intervention, intervention_type:, school:, at: 3.days.ago) } + let!(:new) { create(:observation, :intervention, intervention_type:, school:, at: 2.days.ago) } let!(:newer) { create(:observation, :intervention, intervention_type:, school:, at: 2.days.ago) } let!(:created_last) { create(:observation, :intervention, intervention_type:, school:, at: 4.days.ago) } @@ -140,8 +142,8 @@ end context 'when nothing to complete' do - it { expect(completable.has_todos?).to be(false) } - it { expect(completable.nothing_todo?).to be(true) } + it { expect(assignable.has_todos?).to be(false) } + it { expect(assignable.no_todos?).to be(true) } it { expect(completable.completable?).to be(false) } it { expect(completable.todos_complete?).to be(true) } end @@ -150,17 +152,15 @@ let!(:activity_type_todos) { create_list(:activity_type_todo, 3, assignable:) } let!(:intervention_type_todos) { create_list(:intervention_type_todo, 3, assignable:) } - it { expect(completable.has_todos?).to be(true) } - it { expect(completable.nothing_todo?).to be(false) } + it { expect(assignable.has_todos?).to be(true) } + it { expect(assignable.no_todos?).to be(false) } it { expect(completable.completable?).to be(false) } it { expect(completable.todos_complete?).to be(false) } - describe '#assignable_todos' do - it 'returns todos from completable' do - expect(completable.assignable_todos.count).to eq(6) - todos.each do |todo| - expect(Todo.where(task: todo.task, assignable:)).not_to be_nil - end + it 'returns todos' do + expect(assignable.todos.count).to eq(6) + todos.each do |todo| + expect(Todo.where(task: todo.task, assignable:)).not_to be_nil end end @@ -174,8 +174,8 @@ end end - it { expect(completable.has_todos?).to be(true) } - it { expect(completable.nothing_todo?).to be(false) } + it { expect(assignable.has_todos?).to be(true) } + it { expect(assignable.no_todos?).to be(false) } it { expect(completable.completable?).to be(true) } it { expect(completable.todos_complete?).to be(true) } end diff --git a/spec/system/activity_category_spec.rb b/spec/system/activity_category_spec.rb index c5f86b0e8b..fc94cbdceb 100644 --- a/spec/system/activity_category_spec.rb +++ b/spec/system/activity_category_spec.rb @@ -25,85 +25,91 @@ let!(:activity_category_4) { create(:activity_category, name: 'cat4', pupil: true)} let!(:activity_type_4_1) { create(:activity_type, activity_category: activity_category_4)} - let!(:programme_type) { create(:programme_type, title: 'prog1')} - - let(:user) { } - - before do - sign_in(user) if user.present? - visit activity_categories_path - end + context toggle_feature: :todos do + let!(:programme_types) do + if Flipper.enabled?(:todos) + create_list(:programme_type, 4, :with_todos) + else + create_list(:programme_type, 4) + end + end - context 'when user is not logged in' do - it_behaves_like 'a recommended prompt', displayed: false - end + let(:user) { } - context 'when user is logged in' do - context 'without a school' do - let(:school) { } - let(:user) { create :admin, school: school } + before do + sign_in(user) if user.present? + visit activity_categories_path + end + context 'when user is not logged in' do it_behaves_like 'a recommended prompt', displayed: false end - context 'with a school' do - let(:school) { create :school } - let(:user) { create :pupil, school: school } + context 'when user is logged in' do + context 'without a school' do + let(:school) { } + let(:user) { create :admin, school: school } - it_behaves_like 'a recommended prompt' - end - end + it_behaves_like 'a recommended prompt', displayed: false + end - context 'as a public user' do - describe 'activity categories can be viewed' do - before do - visit activity_categories_path + context 'with a school' do + let(:school) { create :school } + let(:user) { create :pupil, school: school } + + it_behaves_like 'a recommended prompt' end + end - it 'shows featured activity categories with at least 4 activities, plus Pupil activities and Programmes, but not Recommended section' do - expect(page).to have_content(activity_category_1.name) - expect(page).not_to have_content(activity_category_2.name) - expect(page).not_to have_content(activity_category_3.name) - expect(page).not_to have_content('Recommended') + context 'as a public user' do + describe 'activity categories can be viewed' do + before do + visit activity_categories_path + end - expect(page).to have_content('Pupil activities') - expect(page).to have_content(activity_category_4.name) + it 'shows featured activity categories with at least 4 activities, plus Pupil activities and Programmes, but not Recommended section' do + expect(page).to have_content(activity_category_1.name) + expect(page).not_to have_content(activity_category_2.name) + expect(page).not_to have_content(activity_category_3.name) + expect(page).not_to have_content('Recommended') - expect(page).to have_content('Programmes') - expect(page).to have_content(programme_type.title) - end + expect(page).to have_content('Pupil activities') + expect(page).to have_content(activity_category_4.name) + end - it 'shows 4 activities' do - expect(page).to have_content(activity_type_1_1.name) - expect(page).to have_content(activity_type_1_2.name) - expect(page).to have_content(activity_type_1_3.name) - expect(page).to have_content(activity_type_1_4.name) + it 'shows 4 programmes' do + expect(page).to have_content('Programmes') + programme_types.each do |programme_type| + expect(page).to have_content(programme_type.title) + expect(page).to have_link(href: programme_type_path(programme_type)) + end + end - expect(page).not_to have_content(activity_type_2_1.name) - expect(page).not_to have_content(activity_type_3_1.name) - end + it 'shows 4 activities' do + expect(page).to have_content(activity_type_1_1.name) + expect(page).to have_content(activity_type_1_2.name) + expect(page).to have_content(activity_type_1_3.name) + expect(page).to have_content(activity_type_1_4.name) - it 'links to category page, activity page and back' do - click_link 'View all 4 activities' - expect(page).to have_content(activity_category_1.name) - expect(page).to have_content(activity_category_1.description) + expect(page).not_to have_content(activity_type_2_1.name) + expect(page).not_to have_content(activity_type_3_1.name) + end - click_link activity_type_1_1.name - expect(page).to have_content(activity_type_1_1.name) - expect(page).to have_content('public descriptive text here') + it 'links to category page, activity page and back' do + click_link 'View all 4 activities' + expect(page).to have_content(activity_category_1.name) + expect(page).to have_content(activity_category_1.description) - click_link "View #{activity_category_1.activity_types.count} related activities" - expect(page).to have_content(activity_category_1.name) + click_link activity_type_1_1.name + expect(page).to have_content(activity_type_1_1.name) + expect(page).to have_content('public descriptive text here') - click_link 'All activities' - expect(page).to have_content('Explore energy saving activities') - end + click_link "View #{activity_category_1.activity_types.count} related activities" + expect(page).to have_content(activity_category_1.name) - it 'links to programme type page' do - within '#programme-types' do - first('.card-img-top').click + click_link 'All activities' + expect(page).to have_content('Explore energy saving activities') end - expect(page).to have_content(programme_type.title) end end end diff --git a/spec/system/intervention_type_groups_spec.rb b/spec/system/intervention_type_groups_spec.rb index 248f62eee7..f2fc73257f 100644 --- a/spec/system/intervention_type_groups_spec.rb +++ b/spec/system/intervention_type_groups_spec.rb @@ -3,6 +3,7 @@ RSpec.describe 'intervention type groups', type: :system do let!(:intervention_type_1) { create(:intervention_type) } let!(:intervention_type_2) { create(:intervention_type) } + let!(:programme_types) { create_list(:programme_type, 4, :with_todos) } let(:user) { } @@ -11,6 +12,18 @@ visit intervention_type_groups_path end + context with_feature: :todos do + before { refresh } + + it 'shows programmes' do + expect(page).to have_content('Our Programmes') + programme_types.each do |programme_type| + expect(page).to have_content(programme_type.title) + expect(page).to have_link(href: programme_type_path(programme_type)) + end + end + end + context 'when user is not logged in' do it_behaves_like 'a recommended prompt', displayed: false end diff --git a/spec/system/programme_type_spec.rb b/spec/system/programme_type_spec.rb index 89c1beca33..79be6c8e22 100644 --- a/spec/system/programme_type_spec.rb +++ b/spec/system/programme_type_spec.rb @@ -526,9 +526,12 @@ context with_feature: :todos do let!(:programme_type_1) { create(:programme_type, :with_todos) } - let!(:programme_type_2) { create(:programme_type, active: false) } - let!(:programme_type_3) { create(:programme_type) } + let!(:programme_type_2) { create(:programme_type, :with_todos, active: false) } + let!(:programme_type_3) { create(:programme_type, :with_todos) } let!(:programme_type_4) { create(:programme_type, :with_todos, bonus_score: bonus_points) } + let!(:programme_type_empty) { create(:programme_type) } + let!(:programme_type_activities) { create(:programme_type, :with_activity_type_todos) } + let!(:programme_type_actions) { create(:programme_type, :with_intervention_type_todos) } context 'as a public user' do before do @@ -546,6 +549,26 @@ expect(page).to have_no_content(programme_type_2.title) end + it 'does not show programme types without todos' do + expect(page).to have_no_content(programme_type_empty.title) + end + + context 'viewing activity only programme type' do + before do + click_on programme_type_activities.title + end + + it { expect(page).to have_content('This programme is intended for pupils')} + end + + context 'viewing action only programme type' do + before do + click_on programme_type_actions.title + end + + it { expect(page).to have_content('This programme is intended for adults')} + end + context 'viewing a programme type' do before do click_on programme_type_1.title @@ -556,6 +579,7 @@ expect(page).to have_content(programme_type_1.short_description) expect(page).to have_content(programme_type_1.description.body.to_plain_text) expect(page).to have_link(href: programme_type_1.document_link) + expect(page).to have_content('This programme is intended for the whole school') end it_behaves_like 'a todo list when user is not enrolled' do