-
Notifications
You must be signed in to change notification settings - Fork 5
Add ability to set read at on feedback #610
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 7 commits
3218e96
d50910e
25114a3
3b059e9
74e82eb
27bd784
27a1438
1c1b177
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,5 +7,6 @@ json.call( | |
| :user_id, | ||
| :content, | ||
| :created_at, | ||
| :updated_at | ||
| :updated_at, | ||
| :read_at | ||
| ) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| class AddReadAtToFeedback < ActiveRecord::Migration[7.2] | ||
| def change | ||
| add_column :feedback, :read_at, :datetime | ||
| end | ||
| end |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| class Feedback | ||
| class SetRead | ||
| class << self | ||
| def call(feedback:) | ||
| response = OperationResponse.new | ||
| response[:feedback] = feedback | ||
| response[:feedback].read_at = Time.current | ||
| response[:feedback].save! | ||
| response | ||
| rescue StandardError => e | ||
| Sentry.capture_exception(e) | ||
| response[:error] = response[:feedback]&.errors | ||
|
||
| response | ||
| end | ||
| end | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| require 'rails_helper' | ||
|
|
||
| RSpec.describe Feedback::SetRead, type: :unit do | ||
| let(:feedback) { create(:feedback) } | ||
|
|
||
| describe '.call' do | ||
| context 'when set_read is successful' do | ||
| it 'returns a successful operation response' do | ||
| response = described_class.call(feedback: feedback) | ||
| expect(response.success?).to be(true) | ||
| end | ||
|
|
||
| it 'returns the updated feedback' do | ||
| response = described_class.call(feedback: feedback) | ||
| expect(response[:feedback]).to eq(feedback) | ||
| end | ||
|
Comment on lines
15
to
18
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm a bit confused what this is testing to be honest. Might be simpler to test it is an instance of Feedback and then check the read at was set below like you're already doing |
||
|
|
||
| it 'returns read_at' do | ||
| response = described_class.call(feedback: feedback) | ||
| expect(response[:feedback].read_at).to be_present | ||
| end | ||
|
|
||
| it 'returns read_at as a timestamp' do | ||
| response = described_class.call(feedback: feedback) | ||
| expect(response[:feedback].read_at).to be_a(ActiveSupport::TimeWithZone) | ||
| end | ||
| end | ||
|
|
||
| context 'when set_read fails' do | ||
| before do | ||
| allow(feedback).to receive(:save!).and_raise(StandardError, 'Transition failed') | ||
|
||
| end | ||
|
|
||
| it 'returns a failed operation response' do | ||
| response = described_class.call(feedback: feedback) | ||
| expect(response.success?).to be(false) | ||
| end | ||
|
|
||
| it 'returns the original feedback' do | ||
| response = described_class.call(feedback: feedback) | ||
| expect(response[:feedback]).to eq(feedback) | ||
| end | ||
|
||
|
|
||
| it 'does not persist read_at' do | ||
| described_class.call(feedback: feedback) | ||
| feedback.reload | ||
| expect(feedback.read_at).to be_nil | ||
| end | ||
|
|
||
| it 'includes an error object in the response' do | ||
| response = described_class.call(feedback: feedback) | ||
| expect(response[:error]).to be_a(ActiveModel::Errors) | ||
|
||
| end | ||
| end | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| require 'rails_helper' | ||
|
|
||
| RSpec.describe 'Set read_at on feedback requests', type: :request do | ||
| let(:headers) { { Authorization: UserProfileMock::TOKEN } } | ||
| let(:school) { create(:school) } | ||
| let(:student) { create(:student, school:) } | ||
| let(:teacher) { create(:teacher, school:) } | ||
| let(:school_class) { create(:school_class, teacher_ids: [teacher.id], school:) } | ||
| let(:class_student) { create(:class_student, school_class:, student_id: student.id) } | ||
| let(:lesson) { create(:lesson, school:, school_class:, user_id: teacher.id, visibility: 'students') } | ||
| let(:teacher_project) { create(:project, user_id: teacher.id, school:, lesson:) } | ||
| let(:student_project) { create(:project, user_id: class_student.student_id, school:, parent: teacher_project) } | ||
| let!(:feedback) { create(:feedback, school_project: student_project.school_project, user_id: teacher.id, content: 'Excellent work!') } | ||
| let(:feedback_json) do | ||
| { | ||
| id: feedback.id, | ||
| school_project_id: feedback.school_project_id, | ||
| user_id: feedback.user_id, | ||
| content: feedback.content, | ||
| created_at: feedback.created_at, | ||
| updated_at: feedback.updated_at, | ||
| read_at: feedback.read_at | ||
| }.to_json | ||
| end | ||
|
|
||
| context 'when logged in as the class teacher' do | ||
| before do | ||
| authenticated_in_hydra_as(teacher) | ||
| put("/api/projects/#{student_project.identifier}/feedback/#{feedback.id}/read", headers: headers) | ||
| feedback.reload | ||
| end | ||
|
|
||
| it 'returns forbidden response' do | ||
| expect(response).to have_http_status(:forbidden) | ||
| end | ||
|
|
||
| it 'does not set the read_at on feedback' do | ||
| expect(feedback.read_at).to be_nil | ||
| end | ||
| end | ||
|
|
||
| context 'when logged in as the student' do | ||
| before do | ||
| authenticated_in_hydra_as(student) | ||
| put("/api/projects/#{student_project.identifier}/feedback/#{feedback.id}/read", headers: headers) | ||
| feedback.reload | ||
| end | ||
|
|
||
| it 'returns ok response' do | ||
| expect(response).to have_http_status(:ok) | ||
| end | ||
|
|
||
| it 'returns the feedback json' do | ||
| expect(response.body).to eq(feedback_json) | ||
| end | ||
|
|
||
| it 'does set the read_at on feedback' do | ||
| expect(feedback.read_at).to be_present | ||
| end | ||
|
|
||
| it 'sets read_at to be a time' do | ||
| expect(feedback.read_at).to be_a(ActiveSupport::TimeWithZone) | ||
| end | ||
|
|
||
| it 'sets read_at to a recent time' do | ||
| expect(feedback.read_at).to be_within(5.seconds).of(Time.current) | ||
| end | ||
| end | ||
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we want to 404 it if the feedback id is invalid?