Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e3dadb5
WIP: create feedback route
loiswells97 Oct 9, 2025
195eaaf
fixing
loiswells97 Oct 9, 2025
7e78390
Update feedback.rb
loiswells97 Oct 13, 2025
1dc0f11
improving feedback validations and adding factory and model tests
loiswells97 Oct 14, 2025
8fa4791
adding abilities
loiswells97 Oct 14, 2025
a560c73
testing feedback create operation
loiswells97 Oct 14, 2025
56f32da
tidying
loiswells97 Oct 14, 2025
1ec8287
initial rubocop fixes
loiswells97 Oct 14, 2025
1631cf9
Merge branch 'main' into create-feedback
loiswells97 Oct 16, 2025
826e1a4
updating schema version
loiswells97 Oct 16, 2025
788b447
remove unneeded test
loiswells97 Oct 16, 2025
8a1d61c
some rubocop fixes
loiswells97 Oct 16, 2025
054be3f
refactoring feedback factory to please rubocop
loiswells97 Oct 16, 2025
c57741d
adding authorisation for feedback creation
loiswells97 Oct 16, 2025
40ab7c5
add feedback auditing
loiswells97 Oct 16, 2025
7e1ea4a
tidying
loiswells97 Oct 16, 2025
3ad056b
tidying and request specs
loiswells97 Oct 17, 2025
581e3aa
rubocop fixes
loiswells97 Oct 17, 2025
59ecd17
adding comments to explain params
loiswells97 Oct 17, 2025
066ee40
removing commented code
loiswells97 Oct 17, 2025
5678604
fixing papertrail by adding meta migration to versions table
loiswells97 Oct 21, 2025
96c4b92
remove redundant operations directory
loiswells97 Oct 21, 2025
a3c612b
factoring out teacher project ids
loiswells97 Oct 22, 2025
8875291
factoring feedback template out into a partial
loiswells97 Oct 22, 2025
2adbcef
simplify feedback creation error handling
loiswells97 Oct 22, 2025
f08ba8c
Merge branch 'main' into create-feedback
loiswells97 Oct 22, 2025
1c801ae
refactor error handling slightly to catch non-validation errors
loiswells97 Oct 22, 2025
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
Prev Previous commit
Next Next commit
improving feedback validations and adding factory and model tests
  • Loading branch information
loiswells97 committed Oct 14, 2025
commit 1dc0f11cfe8023ce5136d2fc5cb633771f070977
19 changes: 18 additions & 1 deletion app/models/feedback.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ class Feedback < ApplicationRecord
validates :user_id, presence: true
validates :school_project, presence: true
validate :user_has_the_school_owner_or_school_teacher_role_for_the_school
validate :parent_project_belongs_to_lesson
validate :parent_project_belongs_to_school_class
validate :user_is_the_class_teacher_for_the_school_project

def user_has_the_school_owner_or_school_teacher_role_for_the_school
Expand All @@ -20,9 +22,24 @@ def user_has_the_school_owner_or_school_teacher_role_for_the_school
errors.add(:user, msg)
end

def parent_project_belongs_to_lesson
parent_project = school_project&.project&.parent
return if parent_project&.lesson_id.present?
msg = "Parent project '#{parent_project&.id}' does not belong to a 'lesson'"
errors.add(:user, msg)
end

def parent_project_belongs_to_school_class
parent_project = school_project&.project&.parent
return if parent_project&.lesson&.school_class_id.present?

msg = "Parent project '#{parent_project&.id}' does not belong to a 'school-class'"
errors.add(:user, msg)
end

def user_is_the_class_teacher_for_the_school_project
school_class = school_project&.project&.parent&.lesson&.school_class
return if !school_class || school_class.teacher_ids.include?(user_id)
return if !school_project || school_class&.teacher_ids&.include?(user_id)

errors.add(:user, "'#{user_id}' is not the 'school-teacher' for school_project '#{school_project.id}'")
end
Expand Down
19 changes: 19 additions & 0 deletions spec/factories/feedback.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# # frozen_string_literal: true

FactoryBot.define do
factory :feedback do
content { Faker::Lorem.sentence }
user_id { teacher.id }
school_project { create(:school_project, school: school, project: student_project) }

transient do
school { create(:school) }
teacher { create(:teacher, school: school) }
student { create(:student, school: school) }
school_class { create(:school_class, school: school, teacher_ids: [teacher.id]) }
class_student { create(:class_student, school_class: school_class, student_id: student.id) }
parent_project { create(:project, user_id: teacher.id, school: school, lesson: create(:lesson, school_class: school_class, user_id: teacher.id)) }
student_project { create(:project, parent: parent_project, user_id: student.id) }
end
end
end
58 changes: 58 additions & 0 deletions spec/models/feedback_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe Feedback do
before do
stub_user_info_api_for(teacher)
end

let(:teacher) { create(:teacher, school:, name: 'School Teacher') }
let(:school) { create(:school) }

describe 'associations' do
it { is_expected.to belong_to(:school_project) }
end

describe 'validations' do
it { is_expected.to validate_presence_of(:school_project) }
it { is_expected.to validate_presence_of(:content) }
it { is_expected.to validate_presence_of(:user_id) }

it 'validates that the user has the school-owner or school-teacher role for the school' do
feedback = build(:feedback, user_id: SecureRandom.uuid)
expect(feedback).not_to be_valid
expect(feedback.errors[:user]).to include(/does not have the 'school-owner' or 'school-teacher' role/)
end

it 'validates that the parent project belongs to a lesson' do
school_project = create(:school_project, school:, project: create(:project))
feedback = build(:feedback, school_project:, user_id: teacher.id)
expect(feedback).not_to be_valid
expect(feedback.errors[:user]).to include(/Parent project '.*' does not belong to a 'lesson'/)
end

it 'validates that the parent project belongs to a school class' do
parent_project = create(:project, user_id: teacher.id, school:, lesson: create(:lesson, school:, user_id: teacher.id))
school_project = create(:school_project, school:, project: create(:project, parent: parent_project))
feedback = build(:feedback, school_project:, user_id: teacher.id)
expect(feedback).not_to be_valid
expect(feedback.errors[:user]).to include(/Parent project '.*' does not belong to a 'school-class'/)
end

it 'validates that the user is the class teacher for the school project' do
school_class = create(:school_class, teacher_ids: [teacher.id], school:)
parent_project = create(:project, user_id: teacher.id, school:, lesson: create(:lesson, school:, school_class:, user_id: teacher.id))
school_project = create(:school_project, school:, project: create(:project, parent: parent_project))
other_teacher = create(:teacher, school:)
feedback = build(:feedback, school_project:, user_id: other_teacher.id)
expect(feedback).not_to be_valid
expect(feedback.errors[:user]).to include(/is not the 'school-teacher' for school_project/)
end

it 'has a valid default factory' do
feedback = build(:feedback)
expect(feedback).to be_valid
end
end
end