Skip to content
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

Set status directly instead of in form data #44874

Merged
merged 9 commits into from
Feb 18, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -294,12 +294,13 @@ const FormController = props => {
*
* @returns {Object}
*/
const serializeFormData = formData => {
const serializeFormData = (formData, status) => {
if (!formData) {
throw new Error(`formData cannot be undefined`);
}
return {
form_data: formData,
status: status,
...serializeAdditionalData()
};
};
Expand All @@ -318,16 +319,13 @@ const FormController = props => {
};

const makeRequest = applicationStatus => {
const dataWithStatus = {...data, status: applicationStatus};
setData(dataWithStatus);

const ajaxRequest = (method, endpoint) =>
$.ajax({
method: method,
url: endpoint,
contentType: 'application/json',
dataType: 'json',
data: JSON.stringify(serializeFormData(dataWithStatus))
data: JSON.stringify(serializeFormData(data, applicationStatus))
});

return updatedApplicationId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ describe('FormController', () => {
});

describe('Saving', () => {
// [MEG] TODO: Refactor this to use savedStatus instead of form_data
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm leaving this as a to-do because soon, we'll need to have a 'reopened' status if an RP reopens an application. We should check savedStatus for both of these cases.

it('Overrides application status as incomplete to data', () => {
const testData = {
field1: 'value 1',
Expand All @@ -192,7 +193,7 @@ describe('FormController', () => {
);
form.findAll('Button')[1].props.onClick();

expect(getData(DummyPage1)).to.eql({...testData, status: 'incomplete'});
expect(getData(DummyPage1)).to.eql({...testData});
});

it('Disables the save button during save', () => {
Expand Down Expand Up @@ -375,6 +376,7 @@ describe('FormController', () => {
expect(form.findOne('#submit').props.disabled).to.be.false;
});

// [MEG] TODO: Refactor this to use savedStatus instead of form_data
it('Overrides application status as unreviewed on submit', () => {
const testData = {
field1: 'value 1',
Expand All @@ -389,8 +391,7 @@ describe('FormController', () => {
triggerSubmit();

expect(getData(DummyPage3)).to.eql({
...testData,
status: 'unreviewed'
...testData
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,16 @@ def new_form

# PATCH /api/v1/pd/application/teacher/<applicationId>
def update
form_data_hash = params.try(:[], :form_data) || {}
form_data_json = form_data_hash.to_unsafe_h.to_json.strip_utf8mb4
form_data_hash = params.try(:[], :form_data)
if form_data_hash
form_data_json = form_data_hash.to_unsafe_h.to_json.strip_utf8mb4
@application.form_data_hash = JSON.parse(form_data_json)
end

@application.form_data_hash = JSON.parse(form_data_json)
status = params.try(:[], :status)
if status
@application.status = status
end

if @application.save
render json: @application, status: :ok
Expand Down
11 changes: 8 additions & 3 deletions dashboard/app/controllers/api/v1/pd/forms_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@ def new_form
end

def create
form_data_hash = params.try(:[], :form_data) || {}
form_data_json = form_data_hash.to_unsafe_h.to_json.strip_utf8mb4

form = new_form

form_data_hash = params.try(:[], :form_data)
form_data_json = form_data_hash ? form_data_hash.to_unsafe_h.to_json.strip_utf8mb4 : {}.to_json
form.form_data_hash = JSON.parse(form_data_json)

status = params.try(:[], :status)
if status
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

optional / for next time: I am not sure why the existing code is using params.try here, because params should always be defined in a controller method. params[:status] would be more clear.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, good to know! I'll make a note of it and include in a future PR. Thanks.

@application.status = status
end

# Check for idempotence
existing_form = form.check_idempotency
return render json: {id: existing_form.id}, status: :ok if existing_form
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def new
if @application
return render :submitted if @application.status != 'incomplete'
@application_id = @application.try(:id)
@saved_status = @application.try(:status)
@form_data = @application.try(:form_data)
end

Expand All @@ -36,6 +37,7 @@ def new
userId: current_user.id,
schoolId: current_user.school_info&.school&.id,
applicationId: @application_id,
savedStatus: @saved_status,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be needed once an RP can reopen an application

savedFormData: @form_data
}.to_json
}
Expand Down
2 changes: 1 addition & 1 deletion dashboard/app/models/concerns/pd/form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def validate_required_fields
hash = sanitize_and_trim_form_data_hash

# No validation is required if the application is still in progress
return if hash && hash[:status] == 'incomplete'
return if status == 'incomplete'

self.class.required_fields.each do |key|
add_key_error(key) unless hash.key?(key)
Expand Down
17 changes: 1 addition & 16 deletions dashboard/app/models/pd/application/application_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,7 @@ class ApplicationBase < ApplicationRecord

after_initialize :set_type_and_year

# Set the status only if (a) the application is new, or (b) the applicant updates form_data.
# Avoid setting the status when an RP or admin changes the application status, which only happens
# from the application dashboard, not from changing form_data.
before_validation :set_status
before_validation -> {self.status = 'unreviewed' unless status}
validate :status_is_valid_for_application_type
validates_presence_of :type
validates_presence_of :user_id, unless: proc {|application| application.application_type == PRINCIPAL_APPROVAL_APPLICATION}
Expand All @@ -70,7 +67,6 @@ class ApplicationBase < ApplicationRecord
# An application either has an "incomplete" or "unreviewed" state when created.
# After creation, an RP or admin can change the status to "accepted," which triggers update_accepted_data.
before_save :update_accepted_date, if: :status_changed?
before_save :remove_status_from_form_data

before_create :generate_application_guid, if: -> {application_guid.blank?}
after_destroy :delete_unsent_email
Expand All @@ -89,17 +85,6 @@ class ApplicationBase < ApplicationRecord
csa
).index_by(&:to_sym).freeze

def set_status
return unless new_record? || (sanitize_form_data_hash && sanitize_form_data_hash[:status])
self.status = 'unreviewed' if new_record?
self.status = sanitize_form_data_hash[:status] if sanitize_form_data_hash && sanitize_form_data_hash[:status]
end

def remove_status_from_form_data
return unless form_data_hash && form_data_hash["status"]
self.form_data = form_data_hash.except("status").to_json
end

def set_type_and_year
# Override in derived classes and set to valid values.
# Setting them to nil here fails those validations and prevents this base class from being saved.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ class TeacherApplicationsControllerTest < ::ActionController::TestCase

test 'can submit an empty form if application is incomplete' do
sign_in @applicant
put :create, params: {form_data: {status: 'incomplete'}}
put :create, params: {status: 'incomplete'}

assert_equal 'incomplete', TEACHER_APPLICATION_CLASS.last.status
assert_response :created
Expand All @@ -134,7 +134,7 @@ class TeacherApplicationsControllerTest < ::ActionController::TestCase
Pd::Application::TeacherApplication.expects(:queue_email).never

sign_in @applicant
put :create, params: {form_data: {status: 'incomplete'}}
put :create, params: {status: 'incomplete'}
assert_response :created
end

Expand All @@ -144,7 +144,8 @@ class TeacherApplicationsControllerTest < ::ActionController::TestCase
original_data = application.form_data_hash
original_school_info = @applicant.school_info

put :update, params: {id: application.id, form_data: {status: 'incomplete'}}
# Keep cs_total_course_hours because it is calculated on create or update
put :update, params: {id: application.id, status: 'incomplete', form_data: {"cs_total_course_hours": 80}}
application.reload
refute_equal original_data, application.form_data_hash
assert_nil application.course
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ class TeacherApplicationControllerTest < ::ActionController::TestCase

test 'teachers with an incomplete application have an application id and saved form data' do
application = create :pd_teacher_application, form_data_hash: (
build :pd_teacher_application_hash, :incomplete
)
build :pd_teacher_application_hash
), status: 'incomplete'
sign_in application.user
get :new
assert_response :success
Expand All @@ -44,6 +44,7 @@ class TeacherApplicationControllerTest < ::ActionController::TestCase
@script_data = assigns(:script_data)
assert_equal application.id, JSON.parse(@script_data.dig(:props)).dig('applicationId')
assert_equal application.form_data, JSON.parse(@script_data.dig(:props)).dig('savedFormData')
assert_equal application.status, JSON.parse(@script_data.dig(:props)).dig('savedStatus')
end

test 'teachers without an application have no id nor form data' do
Expand Down
4 changes: 0 additions & 4 deletions dashboard/test/factories/pd_factories.rb
Original file line number Diff line number Diff line change
Expand Up @@ -809,10 +809,6 @@
school_type 'Public school'
end

trait :incomplete do
status 'incomplete'
end

trait :with_no_school do
school(-1)
end
Expand Down
11 changes: 2 additions & 9 deletions dashboard/test/models/pd/application/application_base_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,15 @@ class ApplicationBaseTest < ActiveSupport::TestCase
assert application.unreviewed?
end

test 'form data overwrites default status' do
application = create TEACHER_APPLICATION_FACTORY, form_data: {status: 'incomplete'}.to_json
test 'can set a different status from the default' do
application = create TEACHER_APPLICATION_FACTORY, status: 'incomplete'
application.update_status_timestamp_change_log(nil)

assert application.incomplete?
assert_equal application.sanitize_status_timestamp_change_log.length, 1
assert application.sanitize_status_timestamp_change_log[0].value?('incomplete')
end

test 'status is removed from form_data after status is set' do
application = create TEACHER_APPLICATION_FACTORY, form_data: {status: 'incomplete'}.to_json

assert application.incomplete?
assert_nil application.form_data_hash['status']
end

test 'can update status' do
application = create FACILITATOR_APPLICATION_FACTORY
assert application.unreviewed?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ class TeacherApplicationTest < ActiveSupport::TestCase
}

application = create :pd_teacher_application, form_data_hash: (
build :pd_teacher_application_hash, :incomplete, custom_minutes_hours_weeks
)
build :pd_teacher_application_hash, custom_minutes_hours_weeks
), status: 'incomplete'

assert_equal 112, application.sanitize_form_data_hash[:cs_total_course_hours]
end
Expand All @@ -70,8 +70,8 @@ class TeacherApplicationTest < ActiveSupport::TestCase

%i(cs_how_many_minutes cs_how_many_days_per_week cs_how_many_weeks_per_year).each do |attribute|
application = create :pd_teacher_application, form_data_hash: (
build :pd_teacher_application_hash, :incomplete, empty_minutes_hours_weeks.slice(attribute)
)
build :pd_teacher_application_hash, empty_minutes_hours_weeks.slice(attribute)
), status: 'incomplete'

assert_nil application.sanitize_form_data_hash[:cs_total_course_hours]
end
Expand Down