CSC/ECE 517 Fall 2021 - E2140. Create new late policy successfully and fix Bank link: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 20: Line 20:
* Fix back link on "New late policy" page.
* Fix back link on "New late policy" page.
* Fix incorrect flash message on the screen when new late policy is created
* Fix incorrect flash message on the screen when new late policy is created
* Add controller unit tests for create actions for late_policies_controller
* Add controller unit tests for create and edit actions for late_policies_controller
* Add functional test for late policy creation
* Add functional test for late policy creation
* Add functional test for back button on new late policy page
* Add functional test for back button on new late policy page
Line 27: Line 27:
* TODO: SQL stack trace shows up when long string is entered in policy name
* TODO: SQL stack trace shows up when long string is entered in policy name
* View was checked after a controller test to ensure that the correct message is shown to the user.
* View was checked after a controller test to ensure that the correct message is shown to the user.
* Database was checked after controller test to verify whether correct changes happened or didn't.
* TODO: model was also checked to ensure the database is in a correct state
* TODO: model was also checked to ensure the database is in a correct state


Line 44: Line 45:
2. spec/features/late_policy_creation_spec.rb <br/>
2. spec/features/late_policy_creation_spec.rb <br/>
3. spec/features/late_policy_back_button_spec.rb <br/>
3. spec/features/late_policy_back_button_spec.rb <br/>
==Files modified for tests===
1. spec/factories/factories.rb<br />
2. app/controllers/late_policies_controller.rb


===Current Implementation===
===Current Implementation===
Line 50: Line 56:
* Edit action for late_policies_controller is complex to reason about, with booleans deciding whether there are errors.
* Edit action for late_policies_controller is complex to reason about, with booleans deciding whether there are errors.
* Back button does not lead to the assignment from which the new late policy page was created.
* Back button does not lead to the assignment from which the new late policy page was created.




Line 70: Line 74:
<%= link_to 'Back', edit_assignment_path(session[:edit_assignment]) %>
<%= link_to 'Back', edit_assignment_path(session[:edit_assignment]) %>
</pre>
</pre>
* '''Solution''': The link_to function is called with the page previous to current page, so it will go to assginment page.
* '''Solution''': The link_to function is called with the link to the assignment which was last edited, so it will go to assginment page.


* Use edit_assignment_path(session[:edit_assignment]) to go back to the previous page
* Use edit_assignment_path(session[:edit_assignment]) to go back to the previous page
Line 79: Line 83:
::The existing code just shows a blank error, without specifying what has gone wrong. Hence, user will not know what is wrong when they created a new policy.
::The existing code just shows a blank error, without specifying what has gone wrong. Hence, user will not know what is wrong when they created a new policy.


* '''Solution''':  The existing error handling code was changed to show the ActiveRecord::Invalid errors to user. And in case, a different exception occurs, a "something went wrong" message is shown, as this exception shouldn't be visible to users.
* '''Solution''':  The existing error handling code was changed to show the ActiveRecord::Invalid errors to user. And in case, a different exception occurs, a "Something went wrong" message is shown, as this exception shouldn't be visible to users.
          
          
Before:
Before:
<pre>
<pre>
       rescue StandardError
       rescue StandardError
      flash[:error] = "The following error occurred while saving the penalty policy: "
        flash[:error] = "The following error occurred while saving the penalty policy: "
</pre>
</pre>
After:
After:
Line 98: Line 102:




* '''Problem 3''': The paginate method can be moved to a helper class.
* '''Problem 3''': Update `update` method of late_policies_controller
::VersionsController is not the only component which require to paginate items. There are other components too. For instance, the UsersController has to paginate the list of users. Hence the Paginate method can be moved to a helper class which can be accessed by other components as well.
:: Existing update method was too convoluted to read and due to it's convolution, it was showing wrong errors on screen.
* '''Solution''': The filtering options has also been enhanced. The current user can now choose as part of the version search filter any user from a list of users if the current user is authorized to see the versions created by that user.
* '''Solution''':  
The control flow of the `update` method was improved to use early exits when errors occur, instead of using booleans to manage execution.


===New Implementation===
===Code improvements===
text
late_policies_controller#update
Before
<pre>
<pre>
    @penalty_policy = LatePolicy.find(params[:id])
    flash[:error] = "The maximum penalty cannot be less than penalty per unit." if invalid_penalty_per_unit
    same_policy_name = false
    # if name has changed then only check for this
    if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)
      flash[:error] = "The policy could not be updated because a policy with the same name already exists."
    if !same_policy_name && !invalid_penalty_per_unit
      begin
        @penalty_policy.update_attributes(late_policy_params)
        @penalty_policy.save!
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)
        flash[:notice] = "The late policy was successfully updated."
        redirect_to action: 'index'
      rescue StandardError
        flash[:error] = "The following error occurred while updating the penalty policy: "
        redirect_to action: 'edit', id: params[:id]
      end
    elsif invalid_penalty_per_unit
      flash[:error] = "Cannot edit the policy. The maximum penalty cannot be less than penalty per unit."
      redirect_to action: 'edit', id: params[:id]
    elsif same_policy_name
      flash[:error] = "Cannot edit the policy. A policy with the same name " + params[:late_policy][:policy_name] + " already exists."
      redirect_to action: 'edit', id: params[:id]
</pre>
</pre>
* text


After:
<pre>
<pre>
</pre>
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i < params[:late_policy][:penalty_per_unit].to_i
    # If penalty per unit is invalid, exit early
    if invalid_penalty_per_unit
      flash[:error] = "Cannot edit the policy. The maximum penalty cannot be less than penalty per unit."
      redirect_to action: 'edit', id: params[:id] and return
    end


* text
    # Only do DB search if we pass the invalid penalty check
<pre>
    @penalty_policy = LatePolicy.find(params[:id])
</pre>
    # if name has changed, then only check for this
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)
        flash[:error] = "Cannot edit the policy. A policy with the same name " + params[:late_policy][:policy_name] + " already exists."
        redirect_to action: 'edit', id: params[:id] and return
      end
    end


===Code improvements===
    begin
      @penalty_policy.update_attributes(late_policy_params)
      @penalty_policy.save!
      LatePolicy.update_calculated_penalty_objects(@penalty_policy)
      flash[:notice] = "The late policy was successfully updated."
      redirect_to action: 'index' and return
    rescue StandardError
      flash[:error] = "The following error occurred while updating the penalty policy: "
      redirect_to action: 'edit', id: params[:id] and return
    end
* text
* text


Line 128: Line 177:
===Automated Testing using RSPEC===
===Automated Testing using RSPEC===
TODO: add this section
TODO: add this section
The current version of expertiza did not have any test for LatePoliciesController.
The current version of expertiza did not have any test for LatePoliciesController, and for back button.
Using the test driven development(TDD) approach, we have added an exhaustive set of RSPEC tests for LatePoliciesController, to test all the modifications we have done to the code of the controller class. The tests use double and stub features of rspec-rails gem, to fake the log in by different users - Administrator, Instructor, Student etc. The tests can be executed "rpec spec" command as shown below.
Using the test driven development(TDD) approach, we have added an exhaustive set of RSPEC tests for LatePoliciesController, to test creation and expected failure to create scenarios.
We have also added tests for back button on new late policy page.
Similarly, we have added feature tests for late policy creation.
 
Late policy creation tests
<pre>
<pre>
TODO:: Add execution trace for tests, with time taken, etc
$ rspec ./spec/features/late_policy_creation_spec.rb
Randomized with seed 65056
.....
 
Finished in 22.28 seconds (files took 9.71 seconds to load)
5 examples, 0 failures
 
Randomized with seed 65056
 
Coverage report generated for RSpec to /.../expertiza/coverage. 2074 / 15378 LOC (13.49%) covered.
[Coveralls] Outside the Travis environment, not sending data.
</pre>
 
Back button tests
<pre>
$ rspec ./spec/features/late_policy_back_button_spec.rb
Randomized with seed 15242
.
 
Finished in 9.74 seconds (files took 8.95 seconds to load)
1 example, 0 failures
 
Randomized with seed 15242
 
Coverage report generated for RSpec to /.../expertiza/coverage. 2041 / 15378 LOC (13.27%) covered.
</pre>
<pre>
$ rspec ./spec/controllers/late_policies_controller_spec.rb
 
Randomized with seed 29277
........
 
Finished in 17.56 seconds (files took 8.64 seconds to load)
8 examples, 0 failures
 
Randomized with seed 29277
 
Coverage report generated for RSpec to /.../expertiza/coverage. 1587 / 15800 LOC (10.04%) covered.
[Coveralls] Outside the Travis environment, not sending data.
</pre>
</pre>


===Testing from UI===
===References===
===References===


Line 143: Line 233:
#[https://github.com/vinay-deshmukh/expertiza/issues Issues made while development]
#[https://github.com/vinay-deshmukh/expertiza/issues Issues made while development]
#[https://github.com/vinay-deshmukh/expertiza/pulls  Pull requests made to the fork to document work]
#[https://github.com/vinay-deshmukh/expertiza/pulls  Pull requests made to the fork to document work]
#[https://github.com/vinay-deshmukh/expertiza/pulls?q=is%3Apr+is%3Aclosed Closed Pull Requests on Fork]

Revision as of 02:37, 21 October 2021


E2140. Create new late policy successfully and fix "Back" link

This page provides a description of the Expertiza based OSS project, E1240.

About Expertiza

Expertiza is an open source project based on Ruby on Rails framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.

Problem Statement

Create new late policy successfull and fix "Back" link.


Fixes performed

  • Fix back link on "New late policy" page.
  • Fix incorrect flash message on the screen when new late policy is created
  • Add controller unit tests for create and edit actions for late_policies_controller
  • Add functional test for late policy creation
  • Add functional test for back button on new late policy page
  • Improve flow of late_policies_controller#edit action for better tests
  • Fix late_policies_controller#edit action when it displayed two contradictory flashes
  • TODO: SQL stack trace shows up when long string is entered in policy name
  • View was checked after a controller test to ensure that the correct message is shown to the user.
  • Database was checked after controller test to verify whether correct changes happened or didn't.
  • TODO: model was also checked to ensure the database is in a correct state

About Late Policies Controller

This controller can be accessed by editing an assignment, going on "Due Dates" page and clicking on "New late policy".

Files modified in current project

1. app/controllers/late_policies_controller.rb
2. app/views/late_policies/new.html.erb
3. spec/factories/factories.rb

Files added for tests=

1. spec/controllers/late_policies_controller_spec.rb
2. spec/features/late_policy_creation_spec.rb
3. spec/features/late_policy_back_button_spec.rb

Files modified for tests=

1. spec/factories/factories.rb
2. app/controllers/late_policies_controller.rb

Current Implementation

  • There were no tests present in beta branch, so tests for the CRUD operations were added.
  • Edit action for late_policies_controller is complex to reason about, with booleans deciding whether there are errors.
  • Back button does not lead to the assignment from which the new late policy page was created.


Functionality

1.

Drawbacks and Solutions
  • Problem 1: Back button was taking user to index of late_policies, and not assignment due dates page
The back button was performing it's default action of going back to index page of late_policies, but it needs to send user to the assginment page.

Before:

<%= link_to 'Back', :action => 'index' %>

After:

<%= link_to 'Back', edit_assignment_path(session[:edit_assignment]) %>
  • Solution: The link_to function is called with the link to the assignment which was last edited, so it will go to assginment page.
  • Use edit_assignment_path(session[:edit_assignment]) to go back to the previous page
  • Problem 2: Creating new policy with blank fields does not give a proper error


The existing code just shows a blank error, without specifying what has gone wrong. Hence, user will not know what is wrong when they created a new policy.
  • Solution: The existing error handling code was changed to show the ActiveRecord::Invalid errors to user. And in case, a different exception occurs, a "Something went wrong" message is shown, as this exception shouldn't be visible to users.

Before:

      rescue StandardError
        flash[:error] = "The following error occurred while saving the penalty policy: "

After:

      rescue ActiveRecord::RecordInvalid => exception
        flash[:error] = exception.record.errors.full_messages.join("<br />").html_safe
        redirect_to action: 'new'
      rescue StandardError => exception
        # In case it's some error, this error should not be shown to users
        flash[:error] = "Something went wrong"


  • Problem 3: Update `update` method of late_policies_controller
Existing update method was too convoluted to read and due to it's convolution, it was showing wrong errors on screen.
  • Solution:

The control flow of the `update` method was improved to use early exits when errors occur, instead of using booleans to manage execution.

Code improvements

late_policies_controller#update Before

    @penalty_policy = LatePolicy.find(params[:id])
    flash[:error] = "The maximum penalty cannot be less than penalty per unit." if invalid_penalty_per_unit
    same_policy_name = false
    # if name has changed then only check for this
    if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)
      flash[:error] = "The policy could not be updated because a policy with the same name already exists."
    if !same_policy_name && !invalid_penalty_per_unit
      begin
        @penalty_policy.update_attributes(late_policy_params)
        @penalty_policy.save!
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)
        flash[:notice] = "The late policy was successfully updated."
        redirect_to action: 'index'
      rescue StandardError
        flash[:error] = "The following error occurred while updating the penalty policy: "
        redirect_to action: 'edit', id: params[:id]
      end
    elsif invalid_penalty_per_unit
      flash[:error] = "Cannot edit the policy. The maximum penalty cannot be less than penalty per unit."
      redirect_to action: 'edit', id: params[:id]
    elsif same_policy_name
      flash[:error] = "Cannot edit the policy. A policy with the same name " + params[:late_policy][:policy_name] + " already exists."
      redirect_to action: 'edit', id: params[:id]

After:

    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i < params[:late_policy][:penalty_per_unit].to_i
    # If penalty per unit is invalid, exit early
    if invalid_penalty_per_unit
      flash[:error] = "Cannot edit the policy. The maximum penalty cannot be less than penalty per unit."
      redirect_to action: 'edit', id: params[:id] and return
    end

    # Only do DB search if we pass the invalid penalty check
    @penalty_policy = LatePolicy.find(params[:id])
    # if name has changed, then only check for this
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)
        flash[:error] = "Cannot edit the policy. A policy with the same name " + params[:late_policy][:policy_name] + " already exists."
        redirect_to action: 'edit', id: params[:id] and return
      end
    end

    begin
      @penalty_policy.update_attributes(late_policy_params)
      @penalty_policy.save!
      LatePolicy.update_calculated_penalty_objects(@penalty_policy)
      flash[:notice] = "The late policy was successfully updated."
      redirect_to action: 'index' and return
    rescue StandardError
      flash[:error] = "The following error occurred while updating the penalty policy: "
      redirect_to action: 'edit', id: params[:id] and return
    end
* text

<pre>
text

Automated Testing using RSPEC

TODO: add this section The current version of expertiza did not have any test for LatePoliciesController, and for back button. Using the test driven development(TDD) approach, we have added an exhaustive set of RSPEC tests for LatePoliciesController, to test creation and expected failure to create scenarios. We have also added tests for back button on new late policy page. Similarly, we have added feature tests for late policy creation.

Late policy creation tests

$ rspec ./spec/features/late_policy_creation_spec.rb 
Randomized with seed 65056
.....

Finished in 22.28 seconds (files took 9.71 seconds to load)
5 examples, 0 failures

Randomized with seed 65056

Coverage report generated for RSpec to /.../expertiza/coverage. 2074 / 15378 LOC (13.49%) covered.
[Coveralls] Outside the Travis environment, not sending data.

Back button tests

$ rspec ./spec/features/late_policy_back_button_spec.rb 
Randomized with seed 15242
.

Finished in 9.74 seconds (files took 8.95 seconds to load)
1 example, 0 failures

Randomized with seed 15242

Coverage report generated for RSpec to /.../expertiza/coverage. 2041 / 15378 LOC (13.27%) covered.
$ rspec ./spec/controllers/late_policies_controller_spec.rb 

Randomized with seed 29277
........

Finished in 17.56 seconds (files took 8.64 seconds to load)
8 examples, 0 failures

Randomized with seed 29277

Coverage report generated for RSpec to /.../expertiza/coverage. 1587 / 15800 LOC (10.04%) covered.
[Coveralls] Outside the Travis environment, not sending data.

References

  1. Expertiza on GitHub
  2. GitHub Project Repository Fork
  3. Pull request to Expertiza repo
  4. GitHub Fork: Project board
  5. Issues made while development
  6. Pull requests made to the fork to document work
  7. Closed Pull Requests on Fork