diff --git a/app/controllers/student_homes_controller.rb b/app/controllers/student_homes_controller.rb index 36a2740..30386a7 100644 --- a/app/controllers/student_homes_controller.rb +++ b/app/controllers/student_homes_controller.rb @@ -3,5 +3,15 @@ class StudentHomesController < ApplicationController def index @student = Current.student + classroom = @student.classroom + @classroom_programs = classroom.classroom_programs + .includes(:program) + .order("programs.name") + @active_program = @classroom_programs.find { |cp| cp.id.to_s == params[:classroom_program_id] } || @classroom_programs.first + @published_modules = if @active_program + @active_program.classroom_modules.published.includes(content_module: :links) + else + [] + end end end diff --git a/app/views/student_homes/index.html.erb b/app/views/student_homes/index.html.erb index ed74f03..00511cc 100644 --- a/app/views/student_homes/index.html.erb +++ b/app/views/student_homes/index.html.erb @@ -1,11 +1,48 @@ -
-
-
-

Welcome to EndsideOut!

-

You are logged in as <%= @student.full_name %>

-
- <%= button_to "Logout", student_session_path, method: :delete, class: "btn btn-primary" %> -
+<% content_for :title, "Home" %> + +
+
+

Welcome, <%= @student.first_name %>!

+ <%= button_to "Logout", student_session_path, method: :delete, class: "btn btn-sm btn-ghost" %> +
+ + <% if @classroom_programs.size > 1 %> +
+ <% @classroom_programs.each do |enrollment| %> + <%= link_to student_homes_path(classroom_program_id: enrollment.id), + role: "tab", + aria: { selected: enrollment == @active_program }, + class: "tab #{"tab-active" if enrollment == @active_program}" do %> + <%= enrollment.program.name %> + <% end %> + <% end %>
-
+ <% end %> + + <% sorted = @published_modules.sort_by { |m| m.content_module.position.to_i } + latest_date = sorted.map(&:publish_on).max %> + <% if sorted.any? %> + <% sorted.each do |classroom_module| %> +
> + + <%= classroom_module.content_module.name %> + +
+ +
+
+ <% end %> + <% else %> +

No modules published yet.

+ <% end %>
\ No newline at end of file diff --git a/test/controllers/classrooms_controller_test.rb b/test/controllers/classrooms_controller_test.rb index 9fc0d49..3a66e26 100644 --- a/test/controllers/classrooms_controller_test.rb +++ b/test/controllers/classrooms_controller_test.rb @@ -35,6 +35,7 @@ class ClassroomsControllerTest < ActionDispatch::IntegrationTest test "should update an existing enrollment level" do enrollment = classroom_programs(:one) + enrollment.classroom_modules.update_all(publish_on: nil) patch classroom_url(@classroom), params: { classroom: { diff --git a/test/controllers/student_homes_controller_test.rb b/test/controllers/student_homes_controller_test.rb new file mode 100644 index 0000000..32e6aa1 --- /dev/null +++ b/test/controllers/student_homes_controller_test.rb @@ -0,0 +1,82 @@ +require "test_helper" + +class StudentHomesControllerTest < ActionDispatch::IntegrationTest + setup do + @student = students(:ada) + student_sign_in_as @student + end + + test "unauthenticated request redirects to student login" do + student_sign_out + get student_homes_url + assert_redirected_to new_student_session_url + end + + test "shows published module names" do + get student_homes_url + assert_response :success + assert_select "summary", text: /Introduction to Health/ + end + + test "shows links inside published modules" do + get student_homes_url + assert_response :success + link = content_modules(:intro).links.first + assert_select "a[target='_blank']", text: /#{link.title}/ if link + end + + test "most recently published module has the open attribute" do + # Add a second published module so there's a distinct "most recent" + second_module = ContentModule.create!( + program: programs(:kyh), level: "basic", name: "Second Module", position: 2 + ) + classroom_programs(:one).classroom_modules.create!( + content_module: second_module, publish_on: Date.current + ) + + get student_homes_url + assert_select "details[open] summary", text: /Second Module/ + end + + test "all modules published on the same latest date have the open attribute" do + second_module = ContentModule.create!( + program: programs(:kyh), level: "basic", name: "Second Module", position: 2 + ) + classroom_modules(:one).update!(publish_on: Date.current) + classroom_programs(:one).classroom_modules.create!( + content_module: second_module, publish_on: Date.current + ) + + get student_homes_url + assert_select "details[open]", count: 2 + end + + test "shows empty state when no modules are published" do + classroom_modules(:one).update!(publish_on: nil) + get student_homes_url + assert_select "p", text: /No modules published yet/ + end + + test "does not show tab bar for single program enrollment" do + get student_homes_url + assert_select "[role='tablist']", count: 0 + end + + test "shows tab bar when classroom has multiple program enrollments" do + classroom_programs(:one).classroom.classroom_programs.create!( + program: programs(:"3dw"), level: "moderate" + ) + + get student_homes_url + assert_select "[role='tablist']" + assert_select "a[role='tab']", minimum: 2 + end + + test "tab switching shows the selected program as active" do + enrollment = classroom_programs(:one) + enrollment.classroom.classroom_programs.create!(program: programs(:"3dw"), level: "moderate") + + get student_homes_url(classroom_program_id: enrollment.id) + assert_select "a[role='tab'][aria-selected='true'][href*='classroom_program_id=#{enrollment.id}']" + end +end diff --git a/test/fixtures/classroom_modules.yml b/test/fixtures/classroom_modules.yml index 22daaf1..93021f0 100644 --- a/test/fixtures/classroom_modules.yml +++ b/test/fixtures/classroom_modules.yml @@ -1,6 +1,7 @@ one: classroom_program: one content_module: intro + publish_on: 2026-05-01 scheduled: classroom_program: two diff --git a/test/models/classroom_test.rb b/test/models/classroom_test.rb index c529a33..3405fe9 100644 --- a/test/models/classroom_test.rb +++ b/test/models/classroom_test.rb @@ -16,25 +16,26 @@ class ClassroomTest < ActiveSupport::TestCase test "updates level via nested attributes" do classroom = classrooms(:one) - cp = classroom_programs(:one) + enrollment = classroom_programs(:one) + enrollment.classroom_modules.update_all(publish_on: nil) classroom.update!( - classroom_programs_attributes: [ { id: cp.id, program_id: cp.program_id, level: "advanced" } ] + classroom_programs_attributes: [ { id: enrollment.id, program_id: enrollment.program_id, level: "advanced" } ] ) - assert_equal "advanced", cp.reload.level + assert_equal "advanced", enrollment.reload.level end test "destroys enrollment via nested attributes" do classroom = classrooms(:one) - cp = classroom_programs(:one) + enrollment = classroom_programs(:one) # Add a second enrollment first so the classroom still has one after destruction classroom.classroom_programs.create!(program: programs(:"3dw"), level: "basic") assert_difference "ClassroomProgram.count", -1 do classroom.update!( - classroom_programs_attributes: [ { id: cp.id, _destroy: "1" } ] + classroom_programs_attributes: [ { id: enrollment.id, _destroy: "1" } ] ) end end @@ -64,10 +65,10 @@ class ClassroomTest < ActiveSupport::TestCase test "is invalid when all programs are removed" do classroom = classrooms(:one) - cp = classroom_programs(:one) + enrollment = classroom_programs(:one) classroom.assign_attributes( - classroom_programs_attributes: [ { id: cp.id, _destroy: "1" } ] + classroom_programs_attributes: [ { id: enrollment.id, _destroy: "1" } ] ) assert_not classroom.valid?