Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion app/models/course.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ def progress_for(user)
end

def next_lesson(lesson)
lessons.where('lessons.position > ?', lesson.position).first
lessons.where(lessons: { position: lesson.position.next.. }).first
end

def previous_lesson(lesson)
lessons.where(lessons: { position: ...lesson.position }).last
end
end
58 changes: 36 additions & 22 deletions app/views/lessons/_lesson_buttons.html.erb
Original file line number Diff line number Diff line change
@@ -1,29 +1,43 @@
<div class="flex flex-col justify-between max-w-sm mx-auto space-y-6 md:max-w-full md:space-y-0 md:flex-row md:space-x-7">
<%= link_to path_course_path(course.path, course), class: 'button button--secondary px-4 py-2 font-medium', data: { test_id: 'view-course-btn' } do %>
<%= inline_svg_tag 'icons/academic-cap.svg', class: 'h-8 w-8 pr-2', aria: true, title: 'View course', desc: 'Go to course page' %>
View Course
<% end %>

<% if user_signed_in? %>
<%= render Complete::ButtonComponent.new(lesson:) %>
<div class="flex flex-col gap-y-6 max-w-sm mx-auto md:grid md:grid-cols-3 md:gap-x-7 md:gap-y-0 md:max-w-full md:items-center">
<% if course.previous_lesson(lesson).present? %>
<div class="contents md:block md:justify-self-start">
<%= link_to lesson_path(course.previous_lesson(lesson)), class: 'button button--secondary px-4 py-2 font-medium', data: { test_id: 'previous-lesson-btn' } do %>
Comment thread
KevinMulhern marked this conversation as resolved.
Comment thread
KevinMulhern marked this conversation as resolved.
<%= inline_svg_tag 'icons/arrow-left-circle.svg', class: 'h-8 w-8 pr-2', aria: true, title: 'Previous lesson', desc: 'Go to previous lesson' %>
Previous Lesson
<% end %>
</div>
<% else %>
<%= link_to(
'Sign in to track progress',
sign_in_path,
class: 'button button--primary',
data: { test_id: 'sign_in_button' }
) %>
<div class="hidden md:block" aria-hidden="true"></div>
<% end %>

<% if course.next_lesson(lesson).present? %>
<%= link_to lesson_path(course.next_lesson(lesson)), class: 'button button--secondary px-4 py-2 font-medium', data: { test_id: 'next-lesson-btn' } do %>
<%= inline_svg_tag 'icons/arrow-right-circle.svg', class: 'h-8 w-8 pr-2', aria: true, title: 'Next lesson', desc: 'Go to next lesson' %>
Next Lesson
<div class="contents md:block md:justify-self-center">
<% if user_signed_in? %>
<%= render Complete::ButtonComponent.new(lesson:) %>
<% else %>
<%= link_to(
'Sign in to track progress',
sign_in_path,
class: 'button button--primary md:w-60',
data: { test_id: 'sign_in_button' }
) %>
<% end %>
</div>

<% if course.next_lesson(lesson).present? %>
<div class="contents md:block md:justify-self-end">
<%= link_to lesson_path(course.next_lesson(lesson)), class: 'button button--secondary px-4 py-2 font-medium', data: { test_id: 'next-lesson-btn' } do %>
<%= inline_svg_tag 'icons/arrow-right-circle.svg', class: 'h-8 w-8 pr-2', aria: true, title: 'Next lesson', desc: 'Go to next lesson' %>
Next Lesson
<% end %>
Comment thread
KevinMulhern marked this conversation as resolved.
</div>
<% elsif lesson.choose_path_lesson? %>
<%= link_to paths_url, class: 'button button--secondary px-4 font-medium', data: { test_id: 'choose-path-lesson-btn' } do %>
<%= inline_svg_tag 'icons/map.svg', class: 'h-8 w-8 pr-2', aria: true, title: 'Choose path', desc: 'Go to paths page' %>
Choose Path
<% end %>
<div class="contents md:block md:justify-self-end">
<%= link_to paths_url, class: 'button button--secondary px-4 font-medium', data: { test_id: 'choose-path-lesson-btn' } do %>
<%= inline_svg_tag 'icons/map.svg', class: 'h-8 w-8 pr-2', aria: true, title: 'Choose path', desc: 'Go to paths page' %>
Choose Path
<% end %>
</div>
<% else %>
<div class="hidden md:block" aria-hidden="true"></div>
<% end %>
</div>
61 changes: 56 additions & 5 deletions spec/models/course_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,71 @@
it 'returns the next lesson' do
course = create(:course)
section = create(:section, course:)
lesson_one = create(:lesson, position: 1, section:)
lesson_two = create(:lesson, position: 2, section:)
next_lesson = create(:lesson, position: 3, section:)
current_lesson = create(:lesson, position: 2, section:)
_previous_lesson = create(:lesson, position: 1, section:)

expect(course.next_lesson(lesson_one)).to eql(lesson_two)
expect(course.next_lesson(current_lesson)).to eql(next_lesson)
end
end

context 'when the next lesson is in a later section' do
it 'returns the lowest-position lesson after the current one' do
course = create(:course)
section = create(:section, position: 1, course:)
next_section = create(:section, position: 2, course:)
current_lesson = create(:lesson, position: 1, section:)
first_lesson_in_next_section = create(:lesson, position: 2, section: next_section)
_second_lesson_in_next_section = create(:lesson, position: 3, section: next_section)

expect(course.next_lesson(current_lesson)).to eql(first_lesson_in_next_section)
end
end

context 'when there is no next lesson' do
it 'returns nothing' do
course = create(:course)
section = create(:section, course:)
lesson_one = create(:lesson, position: 1, section:)
current_lesson = create(:lesson, position: 1, section:)

expect(course.next_lesson(current_lesson)).to be_nil
end
end
end

describe '#previous_lesson' do
context 'when there is a previous lesson' do
it 'returns the previous lesson' do
course = create(:course)
section = create(:section, course:)
current_lesson = create(:lesson, position: 2, section:)
previous_lesson = create(:lesson, position: 1, section:)
_next_lesson = create(:lesson, position: 3, section:)

expect(course.previous_lesson(current_lesson)).to eql(previous_lesson)
end
Comment thread
KevinMulhern marked this conversation as resolved.
end

context 'when the previous lesson is in an earlier section' do
it 'returns the highest-position lesson before the current one' do
course = create(:course)
section = create(:section, position: 1, course:)
next_section = create(:section, position: 2, course:)
_first_lesson_in_previous_section = create(:lesson, position: 1, section:)
last_lesson_in_previous_section = create(:lesson, position: 2, section:)
current_lesson = create(:lesson, position: 3, section: next_section)

expect(course.previous_lesson(current_lesson)).to eql(last_lesson_in_previous_section)
end
end

context 'when there is no previous lesson' do
it 'returns nothing' do
course = create(:course)
section = create(:section, course:)
current_lesson = create(:lesson, position: 1, section:)

expect(course.next_lesson(lesson_one)).to be_nil
expect(course.previous_lesson(current_lesson)).to be_nil
end
end
end
Expand Down
44 changes: 35 additions & 9 deletions spec/system/lesson_navigation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@

context 'when on the last lesson of a section' do
let!(:next_section) { create(:section, position: 2, course:) }
let!(:next_section_lesson) { create(:lesson, position: 2, section: next_section) }
let!(:first_lesson_in_next_section) { create(:lesson, position: 2, section: next_section) }

before { create(:lesson, position: 3, section: next_section) }

it 'moves to the first lesson in the next section when clicked' do
visit lesson_path(lesson)
find(:test_id, 'next-lesson-btn').click

expect(find(:test_id, 'lesson-title-header')).to have_text(/#{next_section_lesson.title}/i)
expect(find(:test_id, 'lesson-title-header')).to have_text(/#{first_lesson_in_next_section.title}/i)
end
end

Expand All @@ -44,15 +46,39 @@
end
end

describe 'the View Course button' do
it 'directs to the course view' do
visit lesson_path(lesson)
find(:test_id, 'view-course-btn').click
describe 'the previous lesson button' do
context 'when the previous lesson is within the same section' do
let!(:current_lesson) { create(:lesson, position: 2, section:) }

it 'moves to the previous lesson in the section when clicked' do
visit lesson_path(current_lesson)
find(:test_id, 'previous-lesson-btn').click

expect(find(:test_id, 'lesson-title-header')).to have_text(/#{lesson.title}/i)
end
end

context 'when on the first lesson of a section' do
let!(:next_section) { create(:section, position: 2, course:) }
let!(:next_section_lesson) { create(:lesson, position: 3, section: next_section) }

it 'moves to the last lesson in the previous section when clicked' do
last_lesson_in_previous_section = create(:lesson, position: 2, section:)

expect(find(:test_id, 'course-title-header')).to have_text(/#{course.title}/i)
visit lesson_path(next_section_lesson)
find(:test_id, 'previous-lesson-btn').click

expect(find(:test_id, 'lesson-title-header')).to have_text(/#{last_lesson_in_previous_section.title}/i)
end
Comment thread
KevinMulhern marked this conversation as resolved.
end

context 'when on the first lesson in the course' do
it 'is not present' do
visit lesson_path(lesson)

expect(page).to have_css('[data-test-id]')

within '[data-test-id="lesson-list"]', match: :first do
expect(page).to have_text(/#{lesson.title}/i)
expect(page).to have_no_css('[data-test-id="previous-lesson-btn"]')
end
end
end
Expand Down
Loading